对php反序列化漏洞的进一步理解

发布于 2018-12-09  153 次阅读


今天还是一样无趣的在刷题,其中有一道反序列化的题目让我觉得值得记录一下= =

首先右键是可以看到源码如下:

既然有源码了那就本地调试呗 。。


调试了老一会 都不行 然后发现这有一小坑点

也就是这里

public $flag = ******************;

public $truepassword = ******************;

没有加引号(也就是不是字符串),导致无法实例化....加上引号继续干


首先查到了资料

1.构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。

2.析构函数__destruct():当对象被销毁时会自动调用。

3.__wakeup() :如前所提,unserialize()时会自动调用。

也就是说__construct()我们根本不必要去考虑,这应该是坑点之二


所以现在我们的思路就是:

实例化一个Time

然后对truepassword新赋值且等于password的赋值

对time进行赋值

然后等待应该就能出现flag了

可是....
eval("11 * 22 * 33 * 44 * 55 * 66")=1275523920

也许要等我儿子来提交这个flag么= =

关键点sleep((int)$this->time) 如果我们传入以0x开头的字符串的话,岂不是就可以跳过sleep了

此处应为坑点三。


坑点完了应该就是正确解法了。

直接实例化出一个新的Time,再序列化这个新的Time即可

然后。。

(这里我为了演示方便直接把flag的值改成了"this is flag")

但是如果把flag也写上就会覆盖掉。。

所以直接把源码中的flag变量删除,重新实例化得到

O:4:"Time":3:{s:12:"truepassword";i:1;s:4:"time";s:10:"0x4c06f351";s:8:"password";i:1;}

然后就拿到flag啦。

总结:

这个题目的大前提是php的反序列化漏洞,即

通过对一个对象序列化后的反序列化可恢复这个对象,从而调用函数或者给变量重新赋值

主要考点:

1.构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。

2.析构函数__destruct():当对象被销毁时会自动调用。

3.__wakeup() :如前所提,unserialize()时会自动调用。

还有一个php是弱语言类型 16进制也可以和10进制的数进行比较

参考文章:

Comments


请相信,你的指尖拥有改变世界的力量