美文网首页网络安全实验室
最全的PHP反序列化漏洞的理解和应用

最全的PHP反序列化漏洞的理解和应用

作者: 蚁景科技 | 来源:发表于2019-05-05 16:47 被阅读0次

php反序列化漏洞,又叫php对象注入漏洞,是一种常见的漏洞,在我们进行代码审计以及CTF中经常能够遇到。

01 学习前最好提前掌握的知识

PHP类与对象(https://www.php.net/manual/zh/language.oop5.php

PHP魔术方法(https://secure.php.net/manual/zh/language.oop5.magic.php

serialize()  (http://php.net/manual/zh/function.serialize.php

与unserialize()  (http://php.net/manual/zh/function.unserialize.php

02 序列化与反序列化

PHP (从 PHP 3.05 开始)为保存对象提供了一组序列化和反序列化的函数:serialize、unserialize。

serialize()

当我们在php中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,用于保存对象的值方便之后的传递与使用。测试代码如下:

测试结果:

unserialize()

与 serialize() 对应的,unserialize()可以从序列化后的结果中恢复对象(object),我们翻阅PHP手册发现官方给出的是:unserialize — 从已存储的表示中创建 PHP 的值。我们可以直接把之前序列化的对象反序列化回来来测试函数,如下:

03 反序列化漏洞

由前面可以看出,当传给 unserialize() 的参数可控时,我们可以通过传入一个"精心”构造的序列化字符串,从而控制对象内部的变量甚至是函数。

利用构造函数等

Magic function

php中有一类特殊的方法叫“Magic function”,就是我们常说的"魔术方法" 这里我们着重关注以下几个:

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

__destruct():析构函数,类似于C++。会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行,当对象被销毁时会自动调用。

__wakeup():如前所提,unserialize()时会检查是否存在__wakeup(),如果存在,则会优先调用__wakeup()方法。

__toString():用于处理一个类被当成字符串时应怎样回应,因此当一个对象被当作一个字符串时就会调用。

__sleep():用于提交未提交的数据,或类似的清理操作,因此当一个对象被序列化的时候被调用。

测试如下:

结果如下:

从运行结果来看,我们可以看出unserialize函数是优先调用"__wakeup()"再进行的反序列化字符串。同时,对于其他方法的调用顺序也一目了然了。(注意:这里我将sleep注释掉了,因为sleep会在序列化的时候调用,因此执行sleep方法就不会再执行序列以及之后的操作了。)

利用场景

__wakeup()和destruct()

由前可以看到,unserialize()后会导致wakeup() 或destruct()的直接调用,中间无需其他过程。因此最理想的情况就是一些漏洞/危害代码在wakeup() 或destruct()中,从而当我们控制序列化字符串时可以去直接触发它们。我们这里直接使用参考文章的例子,代码如下:

梳理下这2个php文件的功能,index.php是一个有php序列化漏洞的主业文件,logfile.php的功能就是在临时日志文件被记录了之后调用 __destruct方法来删除临时日志的一个php文件。 这个代码写的有点逻辑漏洞的感觉,利用这个漏洞的方式就是,通过构造能够删除source.txt的序列化字符串,然后get方式传入被反序列化函数,反序列化为对象,对象销毁后调用__destruct()来删除source.txt.

漏洞利用exp

04 其它magic function的利用

这里我就结合PCTF和今年国赛上的题来分析了

PCTF

题目链接:(http://web.jarvisoj.com:32768/index.php

前面几步都是很常见的读文件源码,这里直接放出给的两个源码

上边index.php提示了包含的shield.php所以说直接构造base64就完事了

index.php 1.包含了一个shield.php 2.实例化了Shiele方法 3.通过[GET]接收了用户反序列化的内容,输出了readfile()方法

shield.php 1.首先就能发现file是可控的(利用点) 2.construct()在index中实例化的时候就已经执行了,因此不会影响我们对可控$file的利用。

构造poc

ciscn2019 web1- JustSoso

读源码的过程省略

其实刚开始做的时候是很懵逼了,一直在纠结爆破md5上边。22233333

1.首先我们需要绕的就是 $url=parse_url($_SERVER['REQUEST_URI']);使得 parse_str($url['query'],$query); 中query解析失败,这样就可以在payload里出现flag,这里应该n1ctf的web eating cms的绕过方式,添加 ///index.php绕过。

2.接下来就是需要我们绕过wakeup()里的将$k赋值为空的操作,这里用到的是一枚cve当成员属性数目大于实际数目时可绕过wakeup方法(CVE-2016-7124)

3.绕md5这里用到了PHP中引用变量的知识

https://blog.csdn.net/qq_33156633/article/details/79936487

简单来说就是,当两个变量指向同一地址时,例如: $b=&$a,这里的 $b指向的是 $a的区域,这样b就随着a变化而变化,同样的原理,我们在第二步序列化时加上这一步

这样最后的token就和token_flag保持一致了。

最后的POC

05 利用普通成员方法

前面谈到的利用都是基于“自动调用”的magic function。但当漏洞/危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时我们需要去寻找相同的函数名,把敏感函数和类联系在一起。一般来说在代码审计的时候我们都要盯紧这些敏感函数的,层层递进,最终去构造出一个有杀伤力的payload。

参考文章

https://www.cnblogs.com/Mrsm1th/p/6835592.html

http://p0desta.com/2018/04/01/php反序列化总结/

http://whc.dropsec.xyz/2017/06/15/PHP反序列化漏洞理解与利用/

https://p0sec.net/index.php/archives/114/

相关操作学习

PHP反序列化漏洞实验:明白什么是反序列化漏洞,漏洞成因以及如何挖掘和预防此类漏洞。点击前往 合天网安实验室,开始操作!

相关文章

  • 最全的PHP反序列化漏洞的理解和应用

    php反序列化漏洞,又叫php对象注入漏洞,是一种常见的漏洞,在我们进行代码审计以及CTF中经常能够遇到。 01学...

  • 【PHP】深入浅出PHP中的魔术方法

    0x01 引子 PHP的魔术方法在反序列化漏洞利用中是十分常见的,因此对于深入理解反序列化漏洞来说,理解PHP中常...

  • PHP反序列化漏洞原理与复现

    php反序列化漏洞,又叫php对象注入漏洞 序列化与反序列化 php中有两个函数serialize()[http:...

  • Bugku CTF 反序列化

    反序列化 php反序列化漏洞又称对象注入,可能会导致远程代码执行(RCE)个人理解漏洞为执行unserialize...

  • php反序列化漏洞

    php反序列化漏洞我本身也不太懂,看到大佬们的资料,自己进行小结一下 漏洞原因 php反序列化漏洞的原因是unse...

  • 序列化与JSON

    在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。 序列化和反序列化在PHP中...

  • php反序列化漏洞

    php反序列化 反序列化漏洞产生的原因: php在传递和保存数据时通常会将一个对象按照一定的格式来保存,这个过程称...

  • 读懂PHP反序列化

    主要目的 借着本次机会系统的学习反序列化漏洞,和PHP的一些语句的具体用法 问题原因: 漏洞的根源在于unseri...

  • 细说php反序列化字符逃逸

    相关实验推荐--PHP反序列化漏洞实验[https://www.hetianlab.com/expc.do?ec=...

  • Phar的一些利用姿势

    Phar绕过上传 test.php 压缩后改后缀名为jpg index.php Phar反序列化漏洞 test.p...

网友评论

    本文标题:最全的PHP反序列化漏洞的理解和应用

    本文链接:https://www.haomeiwen.com/subject/soshoqtx.html