1. 漏洞概述
文件上传漏洞是 Web 安全中危害极大的漏洞之一。如果服务器对上传文件的类型、内容没有进行严格的 后端过滤,攻击者可以上传恶意的可执行文件(Webshell),从而直接控制服务器。
本关卡是“Client Check”,即 客户端验证。这意味着文件类型的检查逻辑仅运行在用户的浏览器端(JavaScript),而服务器端可能没有任何验证,或者验证非常薄弱。
2. 源码分析 (前端逻辑)
打开页面查看源代码,发现了一段 JavaScript 脚本,用于在文件上传前检查扩展名:
<script>
function checkFileExt(filename)
{
var flag = false; // 状态
var arr = ["jpg","png","gif"];
// 取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
// 比较
for(var i=0;i<arr.length;i++)
{if(ext == arr[i])
{
flag = true; // 一旦找到合适的,立即退出循环
break;
}
}
// 条件判断
if(!flag)
{alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>
分析: 代码逻辑非常简单,通过 checkFileExt 函数获取文件名后缀,并在白名单 ["jpg","png","gif"] 中进行比对。如果不匹配,直接弹窗并刷新页面,根本不会向服务器发送请求。
结论: 既然验证逻辑在前端,我们可以完全掌控它。
3. 闯关实操
针对前端验证,我们有两种经典的绕过方案。
方案一:直接禁用 JavaScript (简单粗暴)
既然拦截逻辑是 JS 写的,直接让浏览器不运行 JS 即可。
- 在浏览器设置中(或使用插件如 NoScript、Chrome 开发者工具 F12 -> Settings -> Debugger -> Disable JavaScript)禁用 JavaScript。
- 刷新页面,直接选择恶意的 PHP Webshell 文件(
1.php)上传。 - 由于没有 JS 拦截,文件直接发送到服务器。
- 结果: 上传成功。访问路径:
http://localhost:8899/vul/unsafeupload/uploads/1.php。

方案二:Burp Suite 抓包修改 (中间人攻击)
这是更符合渗透测试流程的方法。前端 JS 只能验证我们在“文件选择框”里选的文件,无法验证数据包在传输过程中的内容。
- 准备文件: 准备一个 Webshell,将其重命名为合法的后缀,例如
1.jpg。 - 上传抓包: 网页上选择
1.jpg,点击上传。此时前端 JS 校验通过。 - 拦截修改: 在 Burp Suite 中开启拦截,抓到上传的数据包。
- 修改数据: 在数据包中找到
filename="1.jpg",将其修改为filename="2.php"。 - 放行: Forward 数据包。
- 结果: 服务器接收到的文件名是
2.php,文件内容是 Webshell 代码,上传成功。

4. Webshell 连接与后渗透
工具: 哥斯拉 (Godzilla) V4.01
有效载荷: PhpDynamicPayload
加密器: PHP_EVAL_XOR_BASE64
连接步骤:
- 目标 URL 填入上传后的路径:
http://localhost:8899/vul/unsafeupload/uploads/2.php - 填写 Webshell 的
pass和key。 - 点击“测试连接”,显示 Success。
- 进入功能模块,成功获取服务器权限。

5. 总结
前端验证(Client-side Validation)的主要目的是 为了用户体验 (减少用户等待时间,避免误操作),而不是为了安全。攻击者可以轻易通过禁用 JS、抓包修改、编写脚本直接发包等方式绕过浏览器限制。 永远不要信任前端输入。
防御修复方案:
必须在 服务器后端 进行严格的检查:
- 白名单验证: 只允许特定的后缀名(如 jpg, png),不要使用黑名单。
- MIME 类型检查: 检查 Content-Type 头(虽然也可以伪造)。
- 内容检查: 读取文件头(Magic Number)判断文件是否真的是图片。
- 重命名文件: 上传后随机重命名文件,防止攻击者利用已知文件名。
- 目录权限: 上传目录设置为 不可执行(禁止 PHP/JSP 等脚本运行)。