苏师傅给了一道反序列化题,卑微的我在多次提示的情况下搞出来了。。
分析
1 |
|
代码中有一点我当初的思考过程,其实利用的思路并不是很难,关键是你一定要知道自己想要干嘛。
目标就是Read
函数中的file_get
函数,其他的函数虽然也可以读文件,但是利用点还是在这里,(因为我们没办法控制_show
方法的参数)
要想调用file_get
函数,看到有一个__invoke
方法,这个方法触发的条件是:当类的一个对象被当作函数调用的时候触发,也就是Test
类中
1 | public function __get($key) |
如果我们能覆盖掉$this->p
为Read
类的一个对象,后面$function()
就是将这个对象当作函数调用
那么如何触发__get
方法呢?这个方法的触发条件就是访问类中的私有属性或者是不存在的属性时,
此时看到Show
的
1 | public function __toString() |
如果$this->str['str']
被覆盖为Test
类,那么此时就相当于访问Test
类中不存在的属性,自然就会触发__get
方法了
我的难点
也许是我一直忽视了__toString
函数触发的条件 ,这个方法的触发条件是比较简单,但是又比较容易忽视的,我关注到了
1 | public function __construct($file='index.php') |
此处存在一个字符串拼接,所以可以触发__toString
方法,但是__construct
方法在反序列化中是没有什么价值的。导致我一度很纠结,觉得是不是少了一个__destruct
方法。
后来。。。。
原来问题出在
1 |
|
此处的preg_match
也是将其当作字符串来使用,所以显而易见(至少对于之前的我来说不是)会触发__toString
方法
exp
1 |
|
拓展
我在找资料的过程中,还发现了__wakeup
函数的一个漏洞
1 |
|
这个题目中反序列化之后肯定会调用__wakeup
方法,但是在这个方法中,强制给$this->file
赋值为code.png
导致最后的__destruct
不能够读取其他的文件
但是如果我们在反序列化后的数据中做一定的修改,将其属性的数量修改2就可以绕过__wakeup
方法
说是这么说,但是我在调试的过程中怎么也不能触发__wakeup
方法
1 | import requests |
漏洞的详情如下:
谷歌发现了CVE-2016-7124,一个月前爆出的。简单来说就是当序列化字符串中,如果表示对象属性个数的值大于真实的属性个数时就会跳过
__wakeup
的执行 参考https://bugs.php.net/bug.php?id=72663,
查阅bugs.php网站,看到了两个POC
1 |
|
和
1 |
|
但是本地并没有调试成功