PHP反序列化POP链构造

构造PHP反序列化pop链

以前理解的序列化攻击更多是在魔术方法中出现的一些利用漏洞,因为自动调用从而触发的漏洞。但是如果关键代码不在魔术方法中,而在一个类的普通方法中,这时候需要找相同的函数名将类的属性与敏感函数的属性联系起来

常见的php魔法函数

构造pop链的关键

__construct()  当一个对象创建时被调用
__destruct()   当一个对象被销毁时调用
__weakup()     使用unserialize时触发
__sleep()      使用serialize时触发
__call()       在对象上下文中调用不可访问的方法时触发
__get()        从不可访问的属性读取数据
__set()        将数据写入不可访问的属性
__toString()   把类当成字符串使用时触发
__invoke()     当脚本尝试将对象调用为函数时触发

构造pop链,首先要找到头和尾(用户传入参数的地方与最终要执行函数的地方),从头到尾进行反推

简单实例

<?php

class test1{
    pubilc $a;
    function __construct()
    {
        $this->a = new test2;
    }
    function __toString()
    {
        if(isset($this->a))
            return $this->a->action();
    }
}

class test2{
    function action()
    {
        echo "Hello world!";
    }
}

class test3{
    public $cmd
    function action()
    {
        eval($this->cmd);
    }
}

unserialize($_GET['d']);

?>

这是一个简单的例子,通过test::__string() --> test3::__action() 来构造pop链

// 构造pop链
<?php
class test1{
    public $a;
    function __construct()
    {
        $this->a = new test3; 
    }
    
}
class test3{
    public $cmd = '';
}
$b = new test1;
echo serialize($b);
?>

对于protect 与 private 序列化后 需要添加 %00

最后修改于:2021年03月31日 21:40

添加新评论