引言
在渗透测试与代码审计领域,文件包含漏洞堪称 PHP 的 "专属漏洞"------ 它因 PHP 文件包含函数的特性而生,一旦被利用,攻击者可轻松获取服务器权限。本文将从漏洞原理、触发条件入手,深度拆解 file://、php://filter 两大核心伪协议,结合实操案例与过滤器用法,带你全方位掌握文件包含漏洞的攻防逻辑。
一、文件包含漏洞:PHP 的 "天生短板"
文件包含漏洞的核心,源于 PHP 中 include () 等函数的特殊机制:函数仅读取文件流内容,不校验文件后缀,只要文件中包含<?php ?>标记的 PHP 代码,就会被解析执行。
1.1 漏洞原理
PHP 内核由 C 语言编写,include () 等函数底层以 "文件流" 方式读取目标文件 ------ 无论文件后缀是.php、.txt 还是.png,只要内容中存在<?php起始标记,后续内容就会被当作 PHP 代码执行;遇到?>结束标记后,恢复普通文本输出模式。
简单说:文件后缀无关紧要,内容中的 PHP 代码才是关键。
1.2 触发条件
漏洞成立的核心前提是:include () 函数的参数可控。
示例漏洞代码:
<?php
file = _GET['file'];
include($file);
?>
攻击者只需上传包含 PHP 代码的文件(如写有<?php phpinfo();?>的 1.txt),构造 URL:http://example.com/vuln.php?file=1.txt,服务器就会执行文件中的代码,漏洞触发成功。
1.3 攻击场景
攻击者可上传伪装成图片、文本的恶意文件(如 shell.png),通过文件包含漏洞执行该文件,进而读取服务器配置、篡改数据甚至控制整个服务器,危害极大。
二、核心 php 伪协议:文件包含漏洞的 "攻防利器"
在文件包含漏洞的利用中,php 伪协议是核心工具 ------ 其中 file:// 和 php://filter 最为常用,且不受allow_url_fopen、allow_url_include配置影响,实用性拉满。
2.1 file:// 伪协议:本地文件操作 "全能手"
file:// 是 PHP 本地文件读取协议,无需依赖任何配置,支持对本地文件系统的几乎所有操作(读取、写入、删除、重命名等)。
核心特性
- 读取.php 文件:直接执行源码,仅显示执行结果,无法查看原始代码;
- 读取非 PHP 文件(.txt/.jpg/.ini 等):原样输出文件内容,不解析;
- 适用场景:已知目标文件绝对 / 相对路径时,快速读取本地文件。
实操案例
- 环境准备:小皮面板 + Nginx1.25,创建漏洞文件 te.php(代码同上),同目录创建 test.php(内容为普通文本);
- 构造 URL:
http://127.0.0.1/te.php?file=test.php; - 执行结果:页面原样输出 test.php 中的普通文本,验证了 file:// 协议的读取功能(默认隐式调用)。
常用路径示例
- Linux 绝对路径:
file:///var/www/html/config.php - Windows 绝对路径:
file://C:/phpstudy/www/test.txt
2.2 php://filter 伪协议:源码读取 "神器"
php://filter 堪称文件包含漏洞的 "核心武器"------ 它像一个 "数据处理管道",文件内容被 include () 读取时,会先经过过滤器处理,再交给 PHP 解析器,完美解决了直接包含.php 文件无法查看源码的问题。
核心参数
|----------|-----------------------------------------------|
| 参数 | 描述 |
| resource | 必选参数,指定目标文件(如resource=index.php) |
| read | 可选参数,指定读取时的过滤器(如read=convert.base64-encode) |
| write | 可选参数,指定写入时的过滤器(渗透测试中较少使用) |
四大过滤器类型(渗透测试重点)
|--------|--------------------|-----------------|
| 过滤器类型 | 核心作用 | 渗透用途 |
| 字符串过滤器 | 大小写转换、字符替换、移除标签 | 绕过 WAF、简单数据处理 |
| 转换过滤器 | Base64、QP 编码 / 解码 | 读取 PHP 源码(核心用途) |
| 压缩过滤器 | GZIP/BZIP2 压缩 / 解压 | 读取压缩文件、绕过长度限制 |
重点过滤器实操(渗透必备)
1. convert.base64-encode:源码读取 "王牌" •
作用:读取文件时对内容进行 Base64 编码,编码后无<?php ?>标记,PHP 不会执行代码,仅输出密文;
• 优势:无任何限制,PHP 全版本支持,解码后可得完整源码;
• 实操 Payload:http://127.0.0.1/te.php?file=php://filter/read=convert.base64-encode/resource=test.php;
• 解码方式:将页面输出的密文(如VGhpcyBpcyBhIHRlc3QuCg==)复制到 Base64 在线工具,即可还原原始内容。
2. string.rot13:WAF 绕过 "备选方案" •
原理:对字母执行 ROT13 替换(A↔N、a↔n,非字母不变),对称加密,执行两次可还原; • 用途:当 Base64 编码被 WAF 拦截时,用其替代,输出编码后的源码再还原即可。
3. convert.iconv.*:编码转换 "工具人"
作用:实现不同字符编码转换(如 GBK→UTF-8),解决中文乱码;
用法:convert.iconv.GBK.UTF-8(GBK 转 UTF-8);
场景:读取 GBK 编码文件时,避免页面乱码,或绕过对特定编码关键词的 WAF 拦截。
- string.strip_tags:移除标签(谨慎使用)
作用:移除 HTML/XML 标签,保留纯文本;
注意:PHP 7.3.0 后已废弃,不建议在新版本中使用。
php://filter Payload 结构拆解
以核心 Payload 为例:http://127.0.0.1/te.php?file=php://filter/read=convert.base64-encode/resource=test.php
1.漏洞入口:http://127.0.0.1/te.php(含include($_GET['file'])代码);
2.参数传递:?file=(将后续内容传递给 include 函数);
3.核心协议:php://filter/read=convert.base64-encode/resource=test.php
php://filter:本地文件过滤协议;read=convert.base64-encode:读取时执行 Base64 编码;resource=test.php:指定目标文件。
三、总结与防御建议
文件包含漏洞的本质是 "参数可控 + 文件流解析特性",而 php 伪协议则是利用该漏洞的关键工具 ------file:// 适用于快速读取本地文件,php://filter 则专注于源码获取与 WAF 绕过,掌握这些知识点,就能应对大部分渗透测试场景。
防御要点
- 严格限制 include () 参数:避免直接使用用户输入作为文件路径,采用白名单机制;
- 禁用危险伪协议:通过配置禁止 php://filter 等协议的滥用;
- 加强文件上传校验:对上传文件的后缀、内容进行双重验证,避免恶意文件上传;
- 定期审计代码:重点检查 include ()、require () 等函数的参数是否可控。
渗透测试的核心是 "知己知彼",了解漏洞原理与利用方式,才能更好地做好防御。希望本文能为你提供实用的技术参考,欢迎在评论区交流讨论!