unserialize反序列化漏洞的原理与挖掘

2018-11-13  本文已影响0人  N8_xEnn7nA1

当在php中创建了一个对象后,可以通过 serialize() 函数把这个对象转变成一个字符串,保存对象的值方便之后的传递与使用。

image.png

与 serialize() 对应的就是反序列化函数 unserialize() ,它可以将一个字符串转变为相对应的php对象。

image.png

其实本质上来说,serialize() 和 unserialize() 在 PHP内部实现上是没有漏洞的,之所以会产生反序列化漏洞是因为应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。

当传给 unserialize() 的参数可控时,那么用户就可以注入精心构造的 payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。

这里简单说一下魔术方法。"Magic Function" 是 php 中一类特殊的方法。这里我们着重关注以下几个:

下面结合代码可以更好的理解:

image.png image.png

下面来看一下很简单的存在反序列化漏洞的例子:

image.png

由于 unserialize() 的参数可控,我们就,且chybeta类的对象在被销毁时,会执行 $this->test->action 方法,它的 $this->test 我们也可以控制。所以我们可以构造如下代码来生成经过序列化后的 poc:

image.png

于是,我们就成功构造了一句话木马:

image.png

知道了漏洞的原理和利用方式之后,下面就来实战一把。

访问靶场地址:

image.png

填点东西,提交表单:

image.png

点击超链接“Check Code”,页面上打印出了 index.php 的源码:

image.png

来分析下代码。首先看HTML的部分,其中会通过php的foreach循环来遍历$todos遍历的内容,并以无序列表的形式显示在页面上。

然后看一下表单处理的部分,首先获取textarea提交的文本,存储到数组变量 $todos 中,然后对 $todos 进行序列化并存入变量 $m中,

再对 $m进行md5加密,加密后的内容存到变量 $h中,最后将 $h和$m拼接起来作为 Cookie todos的值,然后重定向到当前页面。

接着,获取Cookie中 todos的值,分别取出$h和 $m的值,比较两者是否相等,如果相等,则将$m的值进行反序列化,并将结果存到变量$todos,最终在下面的foreach循环中显示在页面上。

再往上看,有一个叫 readme的类,该类中重写了魔术方法 __toString(),如果用echo 打印该类的对象,则内容就是Readme.txt 和 成员变量 $this->source 的内容的拼接。

image.png

而且可以看到,成员变量可以控制。因此可以按照上面代码中对Cookie的处理逻辑,构造好包含着能反序列化为 readme 对象的字符串,然后放到Cookie中去访问http://120.203.13.75:8123/uns/index.php ,就能讲 flag.php的内容打印到页面上。

于是,在本地构造php程序,sez.php 如下:

image.png

访问结果如下:

image.png

再次访问 http://120.203.13.75:8123/uns/index.php, 然后利用Firefox的Cookie Quick Manager 插件,修改Cookie中todos的值为上面得到的结果:

image.png

保存设置后的值,然后刷新页面,flag.php的内容就显示在了页面上:

image.png
上一篇下一篇

猜你喜欢

热点阅读