Web渗透之前后端漏洞-文件下载漏洞

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

目录

一、什么是文件下载漏洞

二、漏洞产生的原因

三、漏洞危害

四、典型攻击示例

[1. 路径穿越读取系统文件](#1. 路径穿越读取系统文件)

[2. 读取 PHP 源码](#2. 读取 PHP 源码)

[3. 使用编码绕过过滤](#3. 使用编码绕过过滤)

[4. 利用空字节截断(旧版 PHP)](#4. 利用空字节截断(旧版 PHP))

[5. 利用 ZIP 或 Phar 协议(某些语言)](#5. 利用 ZIP 或 Phar 协议(某些语言))

五、漏洞检测方法

六、防御措施

[1. 白名单限制](#1. 白名单限制)

[2. 路径过滤与规范化](#2. 路径过滤与规范化)

[3. 隐藏真实路径](#3. 隐藏真实路径)

[4. 文件权限最小化](#4. 文件权限最小化)

[5. 禁用危险函数或协议](#5. 禁用危险函数或协议)

[6. 输出强制下载](#6. 输出强制下载)

七、与文件包含漏洞的区别

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

九、总结

十、靶场演示推荐

[一、CTFHub 相关题目](#一、CTFHub 相关题目)

[二、BUUCTF 相关题目](#二、BUUCTF 相关题目)


一、什么是文件下载漏洞

文件下载漏洞 是指 Web 应用程序在实现文件下载功能时,对用户传入的文件路径参数未进行严格过滤 ,导致攻击者可以任意下载服务器上的敏感文件(如源代码、配置文件、数据库备份、系统密码文件等)。

这类漏洞常出现在提供文件下载的页面,例如:

  • download.php?filename=report.pdf

  • file.jsp?path=/uploads/guide.doc

攻击者通过修改 filenamepath 参数,尝试读取服务器任意位置的文件。


二、漏洞产生的原因

典型的不安全代码(PHP 示例):

复制代码
$filename = $_GET['filename'];
$filepath = "/var/www/downloads/" . $filename;
header('Content-Type: application/octet-stream');
readfile($filepath);
  • 直接拼接用户输入 :未过滤 ../\ 等路径穿越字符。

  • 未限制基础目录 :没有使用 realpath()open_basedir 限制可访问范围。

  • 未进行白名单校验:允许用户任意指定文件名。


三、漏洞危害

文件类型 典型路径 泄露信息
源代码 index.phpconfig.phpinc/*.inc 数据库密码、API密钥、业务逻辑漏洞
配置文件 /etc/passwd/etc/shadow(需root)、web.config.htaccess 系统用户、服务器配置
日志文件 /var/log/apache2/access.logerror.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 批量尝试常见敏感文件路径。

  • 代码审计 :搜索文件读取函数(readfilefile_get_contentsfopenFile.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-TypeContent-Disposition: attachment,避免文件内容直接在浏览器显示(但不能阻止路径遍历)。

七、与文件包含漏洞的区别

对比 文件下载漏洞 文件包含漏洞
目的 读取文件内容(下载) 将文件内容作为脚本执行
函数 readfilefile_get_contentsfopen includerequire
后果 信息泄露(源码、配置、数据) 代码执行(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 源码。
相关推荐
曲幽5 天前
你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南
python·fastapi·web·graphql·route·cors·rest·strawberry
唐青枫6 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
带刺的坐椅7 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
掉头发的王富贵8 天前
【StarRocks】极限十分钟入门StarRocks
数据库·sql·mysql
曲幽11 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
曲幽12 天前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
zzzzzz31013 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
云技纵横15 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
treesforest17 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
零零信安17 天前
零零信安荣登数世咨询《新质·数字安全专精百强(2026)》暗网情报领域,彰显专业实力与创新引领
安全·网络安全·数据泄露·暗网·零零信安