前言
这道题接触到了很多之前没见过的新知识,解题过程中学到了不少有趣的技巧和思路,特别是文件包含和反序列化相关的利用手段。尽管解题过程中遇到了不少坑,但最终解决还是非常有成就感的。
题目分析
1. 登陆框分析
题目一开始给了一个登陆框,惯例下意识地认为是 SQL 注入,于是尝试手工和 SQLMap 跑了一下,但无论是 F12 抓包,还是 SQLMap 工具测试,发现都没有明显的 SQL 注入痕迹。
为此,我试了御剑和 Disreash 跑目录,但奇怪的是,不同的工具跑出来的结果居然不同。在使用 Disreash 时,因为线程开高了一点导致 IP 被封,之后调整到低线程继续尝试,最终也没跑出什么结果。后来参考了 WP,才发现正确路径在于寻找备份文件。
注意:备份文件为
www.zip
,御剑可以跑出来,而 Disreash 没能识别到。因此工具的选择也很重要。
2. 源码审计
通过备份文件www.zip
拿到整个网站的源码,接下来就是源码审计了。我将代码放到了 Seay 审计工具中进行快速扫描。
通过审计,发现了漏洞的源头:profile.php
文件包含问题。在代码中,有一个config.php
文件,其中有一个flag
的变量,但是并没有值。
通过反复分析,发现这个文件主要是用来引导我们往文件包含方向走。真正的关键在于如何将config.php
的内容包含进来,并读取其中的flag
。最后发现,在update.php
文件中,程序存在反序列化漏洞,这个文件通过POST
方式接受数据并进行序列化操作。
但这里存在一个特殊点:过滤操作是在反序列化完成后才执行的,这跟通常遇到的序列化前过滤
有所不同。
3. 利用反序列化漏洞
观察代码后,联想到了之前做过的类似题目,想到反序列化时可以通过手工构造字符串,利用提前结束符号";}
来逃逸。尝试构造了以下 payload:
s:3:"abc";s:5:"photo";s:10:"config.php";}
但是,这样构造存在一个问题:反序列化时config.php
被当作nickname
的一部分,而不是photo
字段内容。解决这个问题需要进一步深入分析过滤函数。
通过继续分析,发现过滤操作其实可以用来制造字符空间。在反序列化后,对字段进行了长度验证,并且通过构造膨胀字符来挤出空间。也就是说,利用字符替换的技巧可以成功将config.php
包含到photo
字段中。
4. 绕过正则匹配
题目还对nickname
字段有长度限制,这里可以抓包修改,直接将nickname[]
作为绕过手段。抓包后修改nickname
的值为以下 payload:
s:8:"nickname";a:1:{i:0;s:204:"34*where";}s:5:"photo";s:10:"config.php";}
正则替换后,得到:
s:8:"nickname";a:1:{i:0;s:204:"34*hacker";}s:5:"photo";s:10:"config.php";}
由于字符数达到了限制,因此config.php
成功被挤进了photo
字段,反序列化成功结束。
5. 最终Payload
构造完成的payload如下:
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
通过抓包,修改请求参数并重新发送。最终在响应中成功得到了base64编码的flag,解码之后便是题目的flag。
总结
这道题目设计巧妙,尤其是反序列化漏洞的利用点和后续的字符挤出技巧,非常值得学习。整个解题过程虽然有些卡顿,但思路非常清晰。希望以后在做题时,遇到类似情况可以更快反应过来,节省不必要的时间。