Pikachu靶场通关笔记(33) — Unsafe Filedownload (任意文件下载)

45次阅读
没有评论

1. 漏洞概述

文件下载功能在很多 Web 应用中都很常见(如附件下载、图片下载)。如果不安全的文件下载(Unsafe File Download)漏洞存在,攻击者可以通过构造特殊的文件路径(通常利用 ../),跳出 Web 服务器指定的下载目录,去下载服务器系统中的敏感文件(如 /etc/passwd、配置文件、源代码等)。

2. 闯关实操

第一步:分析请求
进入靶场页面,发现是 NBA 球星头像下载页面。点击图片链接,观察 URL 结构:
http://localhost:8899/vul/unsafedownload/execdownload.php?filename=ns.png

可以看到参数 filename 直接指定了要下载的文件名。

第二步:漏洞验证
尝试修改 filename 参数,测试是否存在目录遍历漏洞。
Payload:
../../../../etc/passwd (Linux 环境通用测试)
或者
../../../../windows/win.ini (Windows 环境通用测试)

结果: 成功下载了 /etc/passwd 文件,证明存在任意文件下载漏洞。

Pikachu 靶场通关笔记(33) — Unsafe Filedownload (任意文件下载)

第三步:获取特定文件(上帝视角验证)
已知容器内存在测试文件 test/phpinfo.txt
Payload:
../../../test/phpinfo.txt
结果: 浏览器成功弹出下载框或直接展示文件内容,利用成功。

Pikachu 靶场通关笔记(33) — Unsafe Filedownload (任意文件下载)

3. 源码分析

本次关卡的核心漏洞代码如下:

$file_path="download/{$_GET['filename']}"; // 漏洞点

// ... 省略部分代码...

// 判断文件是否存在
if(!file_exists($file_path)){skip("你要下载的文件不存在,请重新下载", 'unsafe_down.php');
    return ;
}

// ... 省略 Header 设置...

// 读取并输出文件
while(!feof($fp) && $file_count<$file_size){$file_con=fread($fp,$buffer);
    $file_count+=$buffer;
    echo $file_con;
}
fclose($fp);

分析:

  1. 直接拼接: $file_path="download/{$_GET['filename']}"; 这行代码直接将用户输入的 filename 拼接到 download/ 目录下。
  2. 缺乏过滤: 后端虽然使用了 file_exists 检查文件是否存在,但 并没有检查该文件是否在允许的目录内,也没有过滤 ../ 等敏感字符。
  3. 逻辑缺陷: 只要用户通过 ../ 抵消掉前面的 download/ 目录,就可以访问文件系统中的任意位置(只要权限允许)。

4. 深度思考:实战中的利用逻辑

只要能跳出开发者预设的目录(这里是 download/)并读取到本不应公开的文件(如 /etc/passwd 或其他路径的文件),即视为漏洞利用成功。
在实战中,盲目猜测文件名效率很低,通常结合以下思路:

  1. 扫描网站结构(Dirsearch/Gobuster):
    你需要知道网站有哪些文件才能去下载它们。例如,如果你扫描出了 config.phpweb.config 或者备份文件 index.php.bak,你就可以利用下载漏洞把这些源码下载下来进行白盒审计,寻找数据库密码或新的漏洞。
  2. 猜测默认配置文件: 针对特定的 CMS 或中间件,尝试下载默认路径的配置文件。
    • ../../wp-config.php (WordPress)
    • ../../WEB-INF/web.xml (Java Web)
    • C:/Windows/System32/drivers/etc/hosts (Windows)
    • /root/.bash_history (Linux 操作历史)
  3. 读取源码:
    利用下载漏洞读取当前处理脚本本身的源码(如 execdownload.php),查看它是如何写的,或者包含(include)了哪些其他核心文件。

总结: 任意文件下载漏洞通常是进一步攻击的 跳板。通过它获取源码和配置信息,从而拿到数据库权限或配合文件上传 / 包含漏洞 GetShell。


5. 防御修复

  1. 过滤特殊字符: 严格过滤 ./\ 等字符,禁止用户输入目录跳转符号。
  2. 白名单机制: 如果下载的文件数量有限,使用 ID 映射文件名(如数据库中 id=1 对应 ns.png),用户请求只传 ID。
  3. 限定目录: 在 PHP 中使用 realpath() 函数解析绝对路径,判断解析后的路径是否以预定义的 download/ 目录开头。
// 修复示例
$base_dir = '/var/www/html/vul/unsafedownload/download/';
$filename = $_GET['filename'];
$real_path = realpath($base_dir . $filename);

// 检查 realpath 是否存在,且是否以 base_dir 开头
if ($real_path && strpos($real_path, $base_dir) === 0 && file_exists($real_path)) {// 安全,执行下载} else {
    // 非法请求
    die("Access Denied");
}
正文完
 0
评论(没有评论)