从 session 角度学习反序列化
下面是题目给出的源码 原题链接
|
前言
题目直接给出了 phpinfo
信息,作为 CTF 的题来说,一定有其特别的意义。
另外,在实战中也是重要的信息泄露,不熟悉的同学可参考 phpinfo 可以告诉我们什么。
遇到这种情况,可直接拿下来与默认的 phpinfo
进行文件对比,或许可以迅速找到突破口。
困境
看到 __construct()
和 __destruct()
两个魔术方法,极有可能是反序列化的题。其中,__destruct()
中有
eval($this->mdzz); |
如果 $this->mdzz
可控的话,这就是一个明显的 webshell
了,可惜 mdzz
在构造函数中就限死了,而且这里并没有变量覆盖的漏洞,否则也可以打一波,陷入困境。
有这么方便的 eval()
在这里,能不能绕过构造函数,直接执行我们需要的命令呢?
此处必有蹊跷。
ini_set('session.serialize_handler', 'php'); |
知识点
1.PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患
phpinfo
中可以看到,PHP 反序列化时可以使用的几种方法。
平时实验过程中,也可以用这个语句进行方法指定。
session_start([ |
在设置 session 和读取 session 两个阶段中,若使用了不同的序列化方法,将产生任意对象注入,进而导致反序列化漏洞。
$_SESSION['test'] = '|O:8:"stdClass":0:{}'; |
PHP 获取到 session 字符串后,就开始查找第一个 |(竖线),用竖线将字符串分割成”键名”和“键值”, 并对“键值”进行反序列化。但如果这次反序列化失败,就放弃这次解析,再去找下一个竖线,执行同样的操作,直到成功。
然而到这里还是没解决 mdzz
不可控的问题,接下来引入第二个知识点。
2.上传进度支持(Upload progress in sessions)
正常用法参见 example #1,配合 Ajax 就能显示上传进度。
利用此法可达到对 session
写入数据的效果,从而使得 $mdzz
可控,可参照 有趣的 php 反序列化总结
当一个上传在处理中,同时 post 一个与 ini 设置的 session.upload_progress.name 同名变量时,php 检测到这种 post 请求时就会在 $_SESSION 中添加一组数据,所以可通过 session.upload_progress 来设置
session
。
下面是部分参数说明
session.upload_progress.enabled[=1] : 是否启用上传进度报告(默认开启)
session.upload_progress.cleanup[=1] : 是否在上传完成后及时删除进度数据(默认开启, 推荐开启).
session.upload_progress.prefix[=upload_progress_] : 进度数据将存储在
_SESSION[session.upload_progress.prefix . _POST[session.upload_progress.name]]
session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] :
如果 _POST[session.upload_progress.name]没有被设置, 则不会报告进度.
session.upload_progress.freq[=1%] : 更新进度的频率(已经处理的字节数), 也支持百分比表示’%’.
session.upload_progress.min_freq[=1.0] : 更新进度的时间间隔(秒级)
回到本题,查看 phpinfo
session.upload_progress.enabled = 1 |
即使 cleanup 开启了也问题不大,可利用持续上传进行条件竞争。
开干
构造一个表单
|
如果不指定,PHP 将默认使用 “php“ 作为 session 序列化的方法,payload 及结果如下:
PS:不用纠结 Content-Type
,这个对解题没有影响,重点是加入\
,防止 "
被转义。
filename="|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:19:\"print_r($_SESSION);\";}" |
根据 php 手册,存入 session
里的形式是这样的,由此看出 field_name
也可,所以不一定要用 filename
。
$_SESSION["upload_progress_123"] = array( |
拿 flag
的老套路就不多说了,把 mdzz
里的值换成你需要执行的操作即可。
总结
知识面,决定看到的攻击面有多广。
知识链,决定发动的杀伤链有多深。
——猪猪侠