文件包含漏洞(File Inclusion)是Web安全测试中经常遇到的高危漏洞之一。它的根源在于开发人员为了代码复用,使用动态变量去引入文件,而这个变量又没有被严格校验,最终导致攻击者可以控制被包含的文件路径。根据包含对象的不同,文件包含分为本地文件包含(LFI)和远程文件包含(RFI)两种。在渗透测试项目中,掌握这类漏洞的检测方法非常必要,下面结合实际测试经验做一次系统梳理。

一、文件包含漏洞的基本原理
在PHP等动态语言中,include、require、include_once、require_once这类函数可以引入并执行其他文件。如果传入的文件路径参数来自用户输入,且没有做白名单限制,漏洞就会产生。例如某个页面的代码写成了include($_GET['page']),攻击者只要修改page参数的值,就能让服务器包含任意文件。
本地文件包含指的是只能包含服务器本地存在的文件,比如通过相对路径或绝对路径读取系统配置文件;远程文件包含则可以包含外部URL指向的文件,危害更大,可直接注入恶意代码执行。远程文件包含需要allow_url_include开启,在较新版本的PHP中该选项默认关闭,所以实际遇到的多为本地文件包含。
二、常见的可疑参数与测试点
渗透测试时,首先要找出可能存在文件包含的参数。通常带有以下特征的参数值得重点关注:page、file、path、url、template、include、src、doc、lang、dir等。看到URL中出现类似index.php?page=about.php这样的请求,就应该尝试篡改参数值进行探测。
测试时可以先用一个确定不存在的文件名探测,比如提交page=xxxxxxx.php,如果页面返回报错信息如failed to open stream,说明文件路径被直接传入了包含函数,基本可以判定存在包含点。如果程序做了后缀拼接,还需要配合截断技巧绕过,常见方式包括使用%00截断(仅对旧版本PHP有效)或者利用路径长度截断。
三、本地文件包含的路径构造技巧
确认存在包含点后,下一步是构造路径读取敏感文件。最常用的是遍历目录读取系统文件,例如在Linux下使用../../etc/passwd,可以根据报错信息中暴露的路径逐级增加../来定位;Windows下则可以尝试C:\Windows\System32\drivers\etc\hosts、C:\Windows\win.ini等文件,判断标准是页面是否出现这些文件的特有内容,比如win.ini中典型的for 16-bit app support字样。
除了系统文件,还可以尝试读取应用自身的源码和日志文件。例如通过包含服务器日志(如Apache的access.log),把恶意代码写进日志再包含执行,这就是常见的日志包含攻击。此外,/proc/self/environ在部分环境下可以读取进程环境变量,session文件、phpinfo页面也都是可利用的目标。
四、PHP伪协议在检测中的利用
当目标确认存在本地文件包含且为PHP环境时,伪协议是强有力的测试手段。最经典的是php://filter,构造类似?page=php://filter/read=convert.base64-encode/resource=index.php的请求,可以把源码以base64编码形式读出来,既验证了漏洞存在,又能进一步审计代码寻找更多漏洞点。
其他常用协议包括php://input,配合POST提交恶意代码可能实现代码执行;data://协议在allow_url_include开启时可以直接写入代码执行;file://协议用于绝对路径访问本地文件。测试时逐一尝试这些协议,能够全面评估漏洞的实际危害等级。
五、常用检测工具与手工验证结合
| 工具名称 | 主要用途 | 适用场景 |
|---|---|---|
| Burp Suite | 抓包修改参数、批量fuzz测试 | 自动化探测包含点 |
| dirsearch | 辅助发现敏感文件路径 | 配合LFI读取目标 |
| LFISuite | 自动化本地文件包含检测 | 快速批量验证 |
| Commix / wfuzz | 字典 fuzz 参数路径 | 路径遍历深度探测 |
工具扫描效率高,但容易产生误报,建议扫描出疑似包含点后,一定要手工构造payload验证。手工验证时要观察三个层面的反馈:报错信息、页面内容差异、响应时间变化。没有回显的盲文件包含场景,可以借助时间延迟或者外带(OOB)技术判断。
六、文件包含漏洞的修复建议
从开发角度,最根本的修复方式是不要让用户输入直接进入包含函数,可以维护一个文件白名单映射,参数只接受白名单内的值;其次可以固定文件后缀和路径前缀,过滤../、..\\等目录跳转字符,并关闭allow_url_include、allow_url_fopen等危险配置。
对运维层面而言,应当及时升级PHP版本到不受%00截断影响的版本,合理配置open_basedir限制脚本可访问的目录范围,规范错误提示避免泄露绝对路径,同时关闭日志、session等文件的可被包含利用的写入入口。多层防护结合,才能把文件包含的风险降到最低。
七、总结
文件包含漏洞的检测核心在于:先识别可疑参数,再通过报错或回显确认包含点,然后利用路径遍历和伪协议验证危害,最后结合工具提高效率。渗透测试人员在做这类检测时应注意授权范围,只在合法授权的项目中进行测试。对开发者而言,理解攻击思路有助于写出更安全的代码,白名单校验加安全配置永远是防御文件包含最有效的组合。