1. 漏洞概述
在上个关卡中,我们绕过了前端 JS 验证。这次我们面对的是 服务端验证 (Server-side Check)。
表面上看,服务器似乎会对上传的文件进行检查,但关键在于它 检查的是什么。如果服务器仅仅依靠 HTTP 请求头中的 Content-Type (即 MIME 类型) 来判断文件类型,那么攻击者完全可以伪造这个字段,实现欺骗。
MIME (Multipurpose Internet Mail Extensions) 是用于标识文档类型的标准。例如:
.jpg->image/jpeg.php->application/octet-stream或text/x-php
2. 闯关实操 (MIME Bypass)
第一步:初步测试
直接上传 3.php 一句话木马。
结果:上传失败,提示文件类型不符合要求。这说明服务端确实有检测机制。

第二步:Burp Suite 抓包伪造
既然是检测 MIME 类型,我们就可以利用 Burp Suite 进行“中间人欺骗”。
- 准备: 选择本地的
3.php文件准备上传。 - 拦截: 开启 Burp Suite 拦截功能,点击“开始上传”。
- 分析: 查看抓到的数据包,找到
Content-Type字段。- 默认情况下,上传 PHP 文件时,浏览器会自动将其标记为
Content-Type: application/octet-stream(或者是application/x-php)。
- 默认情况下,上传 PHP 文件时,浏览器会自动将其标记为
- 修改: 将该字段修改为服务器允许的图片类型,例如:
Content-Type: image/jpg
(注意:文件名filename="3.php"不需要修改,因为我们要的是 PHP 后缀来执行) - 放行: 点击 Forward 发送数据包。

第三步:验证与连接
网页提示“文件上传成功”,并返回路径 uploads/3.php。
此时使用哥斯拉 (Godzilla) 连接该 URL,成功获得 Shell。

3. 源码分析
根据泄露的后端源码,我们可以看到问题的根源:
if(isset($_POST['submit'])){
// 定义允许的 MIME 类型白名单
$mime=array('image/jpg','image/jpeg','image/png');
$save_path='uploads';
// upload_sick 内部逻辑仅仅是对比 $_FILES['uploadfile']['type'] 是否在 $mime 数组中
$upload=upload_sick('uploadfile',$mime,$save_path);
if($upload['return']){$html.="... 文件上传成功...";} else {$html.="... 错误...";}
}
核心漏洞点:
PHP 中的 $_FILES['file']['type'] 变量,其值是 直接从 HTTP 请求头的 Content-Type 字段读取的 。
也就是说,代码逻辑等同于:如果你告诉我 (HTTP Header) 你是一张图片,那我就相信你是一张图片。
它并没有深入去检查文件本身的内容(比如文件头部的二进制数据),所以我们只需修改 Header 就能骗过服务器。
4. 深度思考与防御修复
Content-Type 是客户端(浏览器)生成的,属于用户可控数据。在安全原则中,“所有来自客户端的数据都是不可信的”。任何可以通过抓包修改的数据,都不能作为安全验证的唯一依据。
防御修复方案:
要真正判断一个文件是不是图片,必须检查文件的 内容 ,而不是 标签。
- 检查文件头 (Magic Number/File Signature):
每种文件格式在文件开头都有特定的二进制标识。例如 JPG 是FF D8 FF,PNG 是89 50 4E 47。PHP 修复示例 (使用 Fileinfo 扩展):$finfo = finfo_open(FILEINFO_MIME_TYPE); // 获取文件真实的 MIME 类型 (通过读取文件内容)$mime = finfo_file($finfo, $_FILES['uploadfile']['tmp_name']);finfo_close($finfo);$allowed_mimes = ['image/jpeg', 'image/png'];if (!in_array($mime, $allowed_mimes)) {die("非法文件类型!"); } - 二次渲染 (Secondary Rendering):
对于图片文件,可以使用图像处理库(如 GD 库)将上传的图片重新压缩或重新生成一遍。因为 Webshell 代码通常隐藏在图片空隙中,重绘图片往往会破坏恶意代码的结构。 - 结合后缀名检查:
既检查 MIME,也检查后缀名,且必须是白名单机制。