Upload-Labs 第1至第10关通关教程
引言
Upload-Labs 是一个专注于文件上传漏洞练习的开源靶场,旨在帮助网络安全初学者深入理解各类文件上传漏洞的成因、利用方式及防御措施。该靶场通过设置不同难度和类型的关卡,模拟了真实Web应用中常见的安全缺陷,涵盖了从前端校验到服务端解析的多种攻击场景。
本教程将详细讲解 Pass-01 至 Pass-10 的通关方法,每关均包含漏洞原理分析、具体操作流程以及实操截图说明。建议读者在本地搭建 PHPStudy 环境(Apache + PHP 5.x)进行实验,以确保与靶场运行环境一致,避免因版本差异导致无法复现问题。
Pass-01 前端验证绕过
本关考察前端JavaScript对文件类型进行限制的安全机制及其绕过方法。
漏洞原理说明
此关卡仅在客户端使用 JavaScript 函数 checkFile() 对上传文件的扩展名进行检查,阻止 .php 等可执行脚本的上传。然而,这种校验完全依赖于浏览器端,攻击者可通过禁用或修改JS代码轻松绕过,而服务器并未对文件类型做任何后端验证,存在严重的安全风险。
具体操作流程
-
尝试上传一个名为
shell.php的一句话木马文件,浏览器会弹出提示"只允许上传 .jpg/.png/.gif 类型文件",并阻止提交。
-
打开浏览器开发者工具(F12),切换至"Elements"或"Sources"面板,找到页面中的
<script>标签,定位到checkFile()函数。
-
删除或注释掉该函数的核心判断逻辑,例如将
return false;改为return true;,或者直接删除整个函数定义。
-
在修改后的页面中重新选择
shell.php文件并上传,此时可成功绕过前端限制。
-
上传成功后,复制返回的文件路径,在蚁剑(AntSword)中新建连接,填入URL地址和密码(如
kfc),即可连接获取 WebShell。



防御建议
应始终在服务端对上传文件的类型、内容和扩展名进行严格校验,不能依赖前端JS作为唯一防线。同时建议对上传文件重命名,并存储在无执行权限的目录下。
Pass-02 MIME 类型校验绕过
本关考察服务器仅通过 HTTP 请求头中的 Content-Type 字段判断文件类型的安全缺陷。
漏洞原理说明
虽然前端未做限制,但服务端通过 PHP 的 $_FILES['upload_file']['type'] 获取文件的 MIME 类型,并仅允许 image/jpeg、image/png 等图片类型。由于该值由客户端控制,攻击者可使用抓包工具(如 Burp Suite)篡改请求中的 Content-Type 头部,从而伪造文件类型实现绕过。
具体操作流程
-
准备一个包含一句话木马的 PHP 文件,例如
shell2.php,内容如下:php<?php @eval($_POST['shell2']); ?> -
在网页中选择该文件并点击上传,使用 Burp Suite 抓取 POST 请求包。


-
在拦截的请求中找到
Content-Type: application/octet-stream或类似字段,将其修改为image/png。

-
放行数据包,服务器将误认为上传的是合法图片文件,从而允许保存。

-
访问上传成功的文件路径,使用蚁剑连接,成功获取 WebShell 控制权。

防御建议
不应依赖 Content-Type 判断文件类型,因其极易被伪造。应结合文件头(Magic Number)、扩展名白名单和服务端内容检测等多种手段综合判断。
Pass-03 黑名单不全绕过
本关考察基于黑名单过滤机制中存在的遗漏扩展名所带来的安全隐患。
漏洞原理说明
服务端采用黑名单方式禁止 .php、.php3、.php4、.php5 等常见PHP扩展名上传。但由于配置不当或考虑不周,某些服务器仍支持其他可解析的扩展名(如 .phtml、.php7、.inc)。若未将这些扩展纳入黑名单,则可被用于绕过。
此外,Apache 需要在 httpd.conf 中显式配置 AddType application/x-httpd-php 才能识别非标准扩展,因此需手动添加支持。
具体操作流程
-
编辑 Apache 的配置文件
httpd.conf,查找是否存在以下语句:apache#AddType application/x-httpd-php .php .phtml


-
取消注释并在末尾添加
.php5,修改为:apacheAddType application/x-httpd-php .php .phtml .php5

-
保存文件并重启 PHPStudy 服务,使配置生效。

-
将原始的
shell.php文件重命名为shell.php5。

-
上传该文件,服务器将根据新配置将其作为PHP脚本解析执行。


-
使用蚁剑连接
shell.php5,成功获得 WebShell。
防御建议
应优先使用白名单而非黑名单策略。即使使用黑名单,也必须覆盖所有可能被解析的扩展名,并定期更新规则库。同时,建议关闭不必要的文件解析功能。
Pass-04 .htaccess 文件利用
本关考察通过上传 .htaccess 文件来改变 Apache 解析行为的高级绕过技术。
漏洞原理说明
.htaccess 是 Apache 提供的一种分布式配置文件,可用于控制目录级的行为,包括文件解析方式。当目标服务器允许上传 .htaccess 文件且开启了 AllowOverride All 时,攻击者可上传自定义规则,强制将特定扩展名(甚至任意文件)解析为 PHP 脚本。
具体操作流程
-
创建一个名为
.htaccess的文本文件,内容如下:apacheSetHandler application/x-httpd-php此指令表示该目录下所有文件都将被视为 PHP 文件处理。

-
将该文件上传至服务器。如果提示不允许上传
.htaccess,可尝试大小写变换(如.HtAccess)或编码绕过。


-
准备一张图片马:在正常 GIF 图片头部插入一句话木马,并确保前六个字节为
GIF89a,以便通过类型检测。

-
将该图片另存为
shell.jpg并上传。


-
访问
shell.jpg的URL,由于.htaccess规则作用,服务器会将其当作 PHP 脚本执行,触发木马代码。

-
使用蚁剑连接该 URL,成功建立会话。
防御建议
应在 Web 目录中禁用 .htaccess 文件的解析功能,或在 Apache 主配置中设置 AllowOverride None。同时,禁止上传点所在目录具有脚本执行权限。
Pass-05 .user.ini 文件利用
本关考察利用 PHP 的用户配置文件 .user.ini 实现持久化代码执行的技术。
漏洞原理说明
从 PHP 5.3.0 开始,CGI/FastCGI 模式下支持每个目录下的 .user.ini 文件自动加载。该文件可用于设置 auto_prepend_file 或 auto_append_file,使得每次请求 PHP 文件时都会自动包含指定文件。若攻击者能上传 .user.ini 和恶意图片马,则可在后续访问中触发包含,实现命令执行。
前提条件:
- PHP 版本 ≥ 5.3.0
- 运行模式为 CGI/FastCGI
- 上传目录可写且能访问
具体操作流程
-
创建
.user.ini文件,内容如下:iniauto_prepend_file=shell.jpg表示每个 PHP 页面执行前都会包含
shell.jpg。

-
上传该
.user.ini文件。

-
准备一个图片马
shell.jpg,其内容开头为GIF89a并嵌入一句话木马。

-
上传
shell.jpg。

-
等待缓存刷新(默认
user_ini.cache_ttl=300秒),或修改 php.ini 将其设为较小值(如10秒)并重启服务。


-
访问任意已存在的 PHP 页面(如
readme.php),服务器将自动包含shell.jpg,触发木马。

-
使用蚁剑连接该页面,成功获取 WebShell。

防御建议
应禁止上传 .ini 类型文件,或在 PHP 配置中设置 user_ini.filename="" 来禁用 .user.ini 功能。同时,避免在用户可控目录中启用 FastCGI 模式。
Pass-06 大小写绕过
本关考察黑名单过滤过程中未统一转换文件名大小写所导致的绕过漏洞。
漏洞原理说明
服务端黑名单虽列出了 .php、.php3 等扩展名,但在比对时未使用 strtolower() 统一转为小写,导致如 .Php、.pHp、.PHP 等混合大小写的扩展名未被识别,从而绕过检测。而 Windows 系统本身不区分文件扩展名大小写,仍可正常解析执行。
具体操作流程
- 将原始的一句话木马文件
shell.php重命名为shell.Php。 - 直接在网页上传该文件。
- 服务器因黑名单匹配失败而放行,文件被保存为
shell.Php。 - 由于 Apache/PHP 对扩展名不敏感,该文件仍会被当作 PHP 脚本解析。
- 使用蚁剑连接
shell.Php,成功建立控制通道。
防御建议
在进行黑名单或白名单校验前,应对文件扩展名统一转换为小写(使用 strtolower()),确保比较一致性。更推荐使用白名单机制配合严格的格式校验。
Pass-07 空格绕过
本关考察未使用 trim() 清除文件名首尾空白字符所引发的安全问题。
漏洞原理说明
服务端黑名单检查时未调用 trim() 函数去除文件名两端的空格或其他空白字符(如 %20、\x09 等)。攻击者可在 .php 后添加空格(如 shell.php ),使黑名单匹配失效。而在实际保存时,操作系统或PHP函数可能会自动忽略末尾空格,最终生成合法的 .php 文件。
具体操作流程
- 准备
shell.php文件。 - 使用 Burp Suite 抓包,在上传请求中将文件名字段改为
shell.php(注意末尾有一个空格)。 - 查看请求体中
filename="shell.php "是否正确显示。 - 放行数据包,服务器因黑名单未命中而允许上传。
- 文件系统通常会忽略末尾空格,实际保存为
shell.php。 - 使用蚁剑连接原文件名
shell.php(无需带空格),成功连接。
注意 :蚁剑连接时填写的路径是
shell.php,而不是带有空格的名称。
防御建议
应对上传文件名调用 trim() 函数清除前后空白字符,并在正则匹配或字符串比较前进行规范化处理。
Pass-08 文件名末尾加点绕过
本关考察 Windows 文件系统自动去除文件名末尾"."所导致的绕过漏洞。
漏洞原理说明
Windows 文件系统不允许文件名以"."结尾,在保存时会自动移除末尾的点号。而服务端黑名单若仅简单地检查扩展名是否为 .php,未对文件名进行标准化处理,则攻击者可通过上传 shell.php. 成功绕过检测,最终被系统保存为 shell.php。
具体操作流程
- 将
shell.php重命名为shell.php.。 - 使用 Burp Suite 抓包确认请求中文件名为
shell.php.。 - 放行数据包,服务器接收该文件。
- 操作系统在保存时自动去除末尾的".",实际文件名为
shell.php。 - 该文件可被正常解析执行。
- 使用蚁剑连接
shell.php,成功获取 WebShell。
提示:此技巧仅适用于部署在 Windows 系统上的服务器。
防御建议
应在服务端对文件名进行预处理,移除末尾的点号和空格,并拒绝包含非常规字符的文件名。同时建议使用随机文件名存储上传文件。
Pass-09 ::$DATA 绕过
本关考察 NTFS 文件流特性在文件上传绕过中的应用。
漏洞原理说明
NTFS 文件系统支持"替代数据流"(ADS),其中 ::$DATA 表示主数据流。当文件名形如 shell.php::$DATA 时,Windows 会将其视为主流文件 shell.php,但在黑名单检测阶段,由于扩展名部分变为 ::$DATA,常规 .php 检查将失效,从而实现绕过。
具体操作流程
- 构造文件名为
shell.php::$DATA。 - 使用 Burp Suite 抓包,在请求中将文件名字段修改为此值。
- 放行数据包,服务器因无法识别
::$DATA而放行上传。 - 文件系统将其解释为
shell.php并保存。 - 使用蚁剑连接时,路径应填写
shell.php,不要包含::$DATA。
易错点 :连接时务必删除
::$DATA后缀,否则无法访问。
防御建议
应禁用 NTFS 替代数据流功能,或在上传前对文件名进行清洗,移除特殊符号。也可在 Linux 环境下部署服务以规避此类问题。
Pass-10 特殊字符组合绕过
本关考察对文件名处理函数 deldot() 逻辑缺陷的理解与利用。
漏洞原理说明
服务端使用自定义函数 deldot() 处理文件名,其逻辑是从后往前扫描,遇到第一个"."即停止处理,不会继续检查之前的字符。攻击者可构造 shell.php. .(点+空格+点)的形式,使得函数在遇到最后一个"."时停止,未能检测到前面的 .php. 结构,从而绕过黑名单。
具体操作流程
- 将
shell.php重命名为shell.php. .(注意中间有空格)。 - 使用 Burp Suite 抓包,确认文件名字段为
shell.php. .。 - 放行数据包,服务器因
deldot()函数逻辑缺陷而放行。 - 文件系统忽略末尾的"."和空格,最终保存为
shell.php。 - 使用蚁剑连接
shell.php,成功建立连接。
关键点 :
deldot()函数设计不合理,未完整清理文件名结构。
防御建议
应彻底重构文件名处理逻辑,使用正则表达式或循环方式完整清理所有无效字符。更安全的做法是使用哈希值(如 md5)加时间戳重命名上传文件。