【Web】PHP 反序列化
[0CTF 2016]piapiapia(反序列化逃逸)
以为是sql注入,试了半天都没反应
常规登录是登不了的,显示无效的账号或密码,但是也没给登录框
这时候,就试试看在url里面输入看看

在随便注册登录后,会提示你完善信息,此时出现文件上传窗口
完善后也没有什么特殊的地方,既然有文件上传,那就扫描后台
扫出来一堆429,设个延迟比较好,但是还是扫出了:www.zip(一般情况下源码会在这里,扫描的时候也可以选择专门扫zip)
index.php 和 register.php 里面没有有价值的东西,config.php 里面是flag
profile.php 中有对 $profile 反序列化
既然使用了 file_get_contents() 函数,那么如果把 $profile['photo'] 替换成 config.php 就能读到flag

对 profile 使用了 show_profile,在class.php里面找

找 filter

利用正则表达式会把一些函数换成 hacker,对大小写不敏感
于是,方法就是 反序列化逃逸
反序列化是以";}结束的,因此如果我们把";}带入需要反序列化的字符串中(除了结尾处),就能让反序列化提前结束而后面的内容就会被丢弃
因为 profile 整个结构就是数组,所以反序列化时是以 a 开始而不是 O
nickname有正则表达式过滤,但是如果nickname变成了数组,则过滤就不起作用,成功绕过
原始序列化是这样:
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:10:"123@qq.com";s:8:"nickname";s:3:"123";s:5:"photo";s:39:"upload/3fcc69yb9b3fc536710fa08b6817z42b";}
现在需要做的是:
通过反序列化逃逸,使 photo 的值为 config.php,掐断序列化,丢弃 upload 的那一段
利用数组绕过 nickname 的过滤,把 photo 那段写进 nickname 数组中
闭合 nickname 数组,把 photo 挤到正确的位置
需要写入的反序列化片段是:
;}s:5:“photo”;s:10:“config.php”;}
共计34个字符
由于过滤的时候有个 where 被换成 hacker,导致5个字符变成了6个
那么写34个 where 就能在序列化的时候腾出34个字符
204 = 5*34 + 34
s:8:"nickname";a:1:{i:0;s:204:"34*where";}s:5:"photo";s:10:"config.php";}
此时的 "34*where";}s:5:"photo";s:10:"config.php" 是作为 nickname 存在的
当序列化后
s:8:"nickname";a:1:{i:0;s:204:"34*hacker";}s:5:"photo";s:10:"config.php";}
由于204字符被占满,自然 s:5:"photo";s:10:"config.php" 就不再是 nickname 里面的东西
因此 payload 就是:
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
抓包,修改 nickname,写入 payload

由于是写在 photo 里面的,需要在开发者模式找图片的base64编码

解密就行


浙公网安备 33010602011771号