4

I'm trying to understand the PHP Object Injection flaw in vBulletin 5.1.x (CVE 2015-7808) and I stumbled across the requirements for Object Injection as stated by OWASP:

The application must have a class which implements a PHP magic method (such as __wakeup or __destruct) that can be used to carry out malicious attacks, or to start a "POP chain".
Source: https://www.owasp.org/index.php/PHP_Object_Injection

However in this writeup about the vbulletin vulnerability I don't see a magic method being exploited, instead the rewind() function of class vB_dB_Result is called because of foreach():

public function decodeArguments($arguments){
        if ($args = @unserialize($arguments)){
            $result = '';
            foreach ($args AS $varname => $value){
                $result .= $varname;
...
class vB_dB_Result implements Iterator{
...
    public function rewind(){
        //no need to rerun the query if we are at the beginning of the recordset.
        if ($this->bof){
            return;
        }
        if ($this->recordset){
            $this->db->free_result($this->recordset);
        }
...
abstract class vB_Database{
... 
    function free_result($queryresult){
        $this->sql = '';
        return @$this->functions['free_result']($queryresult);
    }

Am I missing something or is the OWASP statement simply false in this case?

3

The statement in that form is false. You can use any method for PHP object injection. The important point is that the method must actually be called.

The advantage of magic methods is that they are all named the same, and __wakeup and __destruct are both automatically called.

In this specific case, rewind works as it's called as part of the iterator in the foreach loop.

But it works also in other simpler examples. Imagine for example that you have two classes, both of which have a method of the same name:

class Foo {
    public function bar() {
        echo "everything is safe here";
    }
    [other methods...]
}

class BadFoo {
    public $command = "something";
    public function bar() {
        echo exec($this->command);
    }
}

Now you want to unserialize an object of the safe Foo class, and call the bar function on it:

$foo = unserialize($_GET['foo']);
$foo->bar();

Obviously, an attacker could simply send an object of the BadFoo class instead, leading to code execution:

O:6:"BadFoo":1:{s:7:"command";s:2:"id";}

This shows that it works with any methods, not just magic methods, as long as the method is called and does something an attacker is interested in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.