本地文件包含(LFI)漏洞允许攻击者读取服务器上的任意文件,甚至通过日志注入或PHP封装协议执行任意代码。这种漏洞在PHP应用中尤为常见,根源在于开发者对文件路径参数缺乏严格过滤,导致攻击者可以通过路径遍历、日志注入或利用PHP伪协议获取敏感信息或远程代码执行。据OWASP《Top 10 Web Application Security Risks》报告显示,文件包含类漏洞在历年排名中始终位于前列,是Web应用渗透测试中的高频攻击向量。
LFI漏洞通常出现在PHP的include、require、include_once、require_once等文件包含函数中。当开发者将用户输入直接拼接为文件路径时,攻击者可以通过控制输入参数来包含任意文件。例如,以下代码直接将GET参数page传递给include函数:
<?php $page = $_GET['page']; include($page . '.php'); ?>
攻击者如果传入../../etc/passwd%00,利用空字节截断(PHP 5.3.4之前版本)或../../etc/passwd配合扩展名截断,可以包含系统敏感文件。即使没有空字节,也可以使用PHP封装协议如php://filter来读取文件内容。
路径遍历是最直接的LFI利用方式。攻击者通过../序列回溯目录,指向系统关键文件,如/etc/passwd、/etc/shadow、Windows的boot.ini等。在PHP中,如果应用附加了文件扩展名,攻击者可以使用空字节截断或长路径截断(Windows系统)绕过。例如,对于include($path . '.php'),传入../../../etc/passwd%00可使.php被忽略。
当无法直接读取文件时,攻击者可以通过污染日志文件来实现代码执行。例如,Apache的访问日志access.log和错误日志error.log通常可写。攻击者向服务器发送包含恶意PHP代码的HTTP请求,如GET /?cmd=echo shell_exec($_GET['c']);,然后通过LFI包含日志文件,触发恶意代码执行。这种方法需要应用具有日志文件的可读权限,且日志路径可预测。
PHP提供多种封装协议,如php://filter、php://input、data://等,可被用于LFI攻击。例如,php://filter/convert.base64-encode/resource=index.php可以读取PHP源码并输出base64编码内容。而data://协议允许直接包含文本或base64编码的PHP代码,如data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjJ10pOyA/Pg==,这会在支持allow_url_include的PHP配置下直接执行代码。
在渗透测试中,一个典型的LFI利用链如下:攻击者首先探测应用是否存在文件包含漏洞,通过输入../测试返回结果。如果发现可读取文件,则进一步尝试日志注入。例如,在某个CMS中,发现参数file存在LFI,但限制了目录。攻击者通过包含php://filter读取源码,发现日志路径为/var/log/apache2/access.log。然后构造包含恶意代码的请求:
curl -X GET "http://target.com/index.php?file=../../../../var/log/apache2/access.log" -H "User-Agent: <?php system($_GET['c']); ?>"
再次请求?file=../../../../var/log/apache2/access.log&c=id,即可执行id命令。
| 场景 | 防御措施 | 有效性 |
|---|---|---|
| 路径遍历 | 白名单验证、禁用../、使用basename()过滤 | 高,但需注意编码绕过 |
| 日志注入 | 限制日志文件权限、使用单独日志目录、关闭allow_url_include | 中,需结合其他措施 |
| PHP封装协议 | 禁用allow_url_include、设置open_basedir限制 | 高,但需注意php://filter仍可用 |
在上表中,白名单验证是最直接有效的防御方式,即只允许包含预定义的文件列表。对于日志注入,关键在于不允许Web服务进程写入日志文件或限制日志文件的读权限。而PHP封装协议中,php://filter即使关闭allow_url_include仍可读取文件,因此需要额外使用open_basedir限制可访问目录。
在开发层面,应避免直接将用户输入作为文件路径参数。推荐使用白名单映射,如:
<?php
$allowed_pages = array('home', 'about', 'contact');
$page = $_GET['page'];
if (in_array($page, $allowed_pages, true)) {
include($page . '.php');
} else {
// 错误处理
}
?>此外,对输入进行严格的过滤与验证,使用realpath()将路径转换为绝对路径后检查是否在允许目录内。对于WAF,攻击者常用的绕过手法包括URL编码、双编码、路径遍历混淆(如....//)、使用..;/(Windows)等。WAF规则需要覆盖这些变形,并实施基于正则的深度检测。
LFI本地文件包含漏洞的核心危害在于允许攻击者读取任意文件或执行任意代码。防御的关键在于彻底放弃用户输入直接拼接路径的做法,严格实施白名单机制,并配合服务器配置如open_basedir、allow_url_include关闭等。安全从业者在进行渗透测试时,应将LFI测试作为标准流程的一部分,并掌握日志注入、PHP封装协议等高级利用技巧,以评估应用的真实风险。
评论
加载中...