PHP Unserialization and duplicate variable names

Viewed 64

Recently I stumbled across this description of a PHP Object Injection vulnerability in an older version of the CMS Contao (It's written in german but I will translate the crucial parts).

There the author says, he didn't manage to get Null-Bytes to the unserialize function (they were filtered out) so he wasn't directly able to write to protected or private members of a class.

Then he says this wouldn't be a problem, because the unserialize() function wouldn't care if the serialized version of the class has public members that are actually protected in the real class so he could just remove the leading Null-Bytes and the stars and correct the length of the variable name strings (just making the variables public in the serialized version) to get the attack to work (so writing to the protected members of a vulnerable class).

Then I tried writing my own PoC of this behavior but failed. First I created a little test class called 'Test' which has the protected member 'value' and a destructor which prints this value:

class Test {
   protected $value = "Default";

   public function __destruct() {
      echo $this->value . "<br>";
   }
}

Now I'm trying to change the value of the protected 'value' member. With the Null-Bytes and the Star, everything works fine:

$obj = unserialize("O:4:\"Test\":1:{s:8:\"\0*\0value\";s:8:\"Injected\";}");
echo serialize($obj);

gives me:
O:4:"Test":1:{s:8:"*value";s:8:"Injected";}
Injected

Now I tried leaving out the Null-Bytes and the star so I pretended that 'value' would be a public variable:

$obj2 = unserialize("O:4:\"Test\":1:{s:5:\"value\";s:8:\"Injected\";}"); // I pretended that 'value' would be a public variable
echo serialize($obj2);

This gives me:
O:4:"Test":2:{s:8:"*value";s:7:"Default";s:5:"value";s:8:"Injected";}
Default

If you look at the serialized version of the class it seems like the PHP-Object has got two members with the same name but a different visibility. The destructor prints out the protected member so the injection doesn't work.

Now I'm wondering whether I'm missing something in this context or why this seemed to work for the author of the article. I would very appreciate your help here!

0 Answers
Related