反序列化是PHP特性之一,关于其知识点网上有很多讲解的文章,但是很少有涉及到其在CTF中的应用,本篇文章在介绍其原理的基础上,重点关注其在CTF中的出题套路,直击命题人内心,洞悉考点趋势……
OK,吹比时间结束,开始进入正题吧~
别问小编这三个月干嘛去了,问就是去拯救世界了-_-
0x00 前言
关于PHP反序列化的基础知识:
serialize()函数——将PHP中的变量如对象(Object)、数组(Array)等序列化为字符串
unserialize()函数——将序列化的字符串转换为原先的值
贴上PHP手册上的说明:
想要将已序列化的字符串变回 PHP 的值,可使用 unserialize()。serialize() 可处理除了 resource 之外的任何类型。甚至可以 serialize() 那些包含了指向其自身引用的数组。serialize() 的数组/对象中的引用也将被存储。
当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数。
是不是很通俗易懂?
看不懂没关系,继续看下去,你一定会看(fang)懂(qi)的!
0x01 原理
不知道大家还有没有印象,在《Bugku Web Write Up(七)》的《flag.php》这道题中,我们与反序列化打过交道,当时只是将字符串为0的变量序列化后提交即可,比较简单
而在上一篇关于CBC字节翻转攻击的文章中,我们举例的那个明文序列:
a:2:
我们仔细研究下它的格式
除了图中的数据类型外,还有其他类型表示:
O:表示对象
i :表示int
R:特殊类型,保存了到外部资源的一个引用
…………
说了这么多,还是以一道CTF题目来巩固一下学习效果吧~
0x02 实战
题目链接:http://120.24.86.145:8006/test1/
没错,选题来自bugku,新赛季又开始了,了解一下~
打开网页,查看源代码,审计一下代码发现我们需要让txt参数内容为:
welcome to the bugkuctf
方法很简单,使用php://input封装协议即可,这样可以得到原始的post数据
OK,绕过第一个限制后,到了include($file);这一步
题目已经提示的很明显了,需要我们读取hint.php这个文件
这个时候就需要php://filter伪协议出场了
成功读取到了base64编码的文件内容
解码看一下代码
根据代码,显示存在flag.php文件,但是使用任意文件漏洞读取时提示:
题目做了限制,看一下index.php页面的源代码
发现有preg_match()函数,无法直接读取flag.php页面
这就需要我们另辟蹊径了
PHP反序列化漏洞,又称为对象注入,可能会导致远程代码执行(RCE)
还记得文章开头引用的PHP官方手册上的话吗?
当执行unserialize()函数时,会调用某一类执行其魔术方法,之后可以执行类中的函数,从而产生安全问题。
总结一下漏洞产生的前提:
1)unserialize()函数变量可控
2)存在可利用的类,类中有魔术方法
再次回到题目上,现在hint.php中有类和魔术方法__tostring()
index.php中有unserialize()函数且变量可控
于是可以为所欲为了~
口(xie)算(ge)一(jiao)下(ben)序列化后的字符串
构造我们最终的payload
base64解码后就得到最终的flag了~
0x03 提升
关于PHP反序列化漏洞,我觉得freebuf上这篇文章写得很不错:
http://www.freebuf.com/vuls/116705.html
文章最后举例的HITCON 2016《babytrick》这题,考点整合了PHP的反序列化漏洞、SQL注入、__wakeup绕过、mysql字符编码trick等等
大家可以去看看,可以学到不少姿势哦~
0x04 参考
http://www.freebuf.com/vuls/116705.html
https://www.waitalone.cn/php-serialize-inject.html
https://chybeta.github.io/2017/06/17/%E6%B5%85%E8%B0%88php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
https://www.anquanke.com/post/id/86452
这篇文章简单介绍了PHP反序列化的原理及在CTF中的应用,如果大家在学习和做题的过程遇到了新的套路和姿势,欢迎一起交流哦~
领取专属 10元无门槛券
私享最新 技术干货