PortSwigger file upload labs

距上次发文隔了好久,hexo 命令都忘了 emmm

1 Lab: Remote code execution via web shell upload

1
<?php echo file_get_contents('/home/carlos/secret'); ?>

头像上传模块未添加任何限制,直接上传 PHP 文件即可。


查看头像访问路径。

2 Lab: Web shell upload via Content-Type restriction bypass

下面是 usernamecsrf token 没截上,不过也用不上。

响应是个 403,且提示 “Sorry, file type application/x-php is not allowed, Only image/jpeg and image/png are allowed”,这里的 application/x-php 恰好是 Content-Type 的内容。

思路:将对应的 Content-Type 修改为 image/jpegimage/png 如果只检查该头部的话,应该就能上传出成功了。

响应状态码是 200 上传成功。

请求一下该 “头像”,这里可以刷新一下浏览器页面,之后在 Proxy -> 的 HTTP history 部分找 /files/avatars/test.php 请求(见 Lab 1),也可以直接请求该接口。


响应 200,成功。

3 Lab: Web shell upload via path traversal

首先,上传 test.php,轻而易举,轻车熟路!

但是当请求接口 /file/avatars/test.php 时,响应并未执行 test.php 而是把它当作文本传输了出来。要这么玩我可就不高兴了。

但响应中却仍然提示 “The file avatars/test2.php has been uploaded.”,难道只是名字没改?其实文件是上传到了 /file/ 下?

请求 /files/test2.php –> 404

请求 /files/avatars/test2.php –> 200

裂开,没上传成功。

使用 URL 编码,遇到问题先考虑编码绕过,还真给上传上了。

虽然但是,我传的文件去哪了?

保守一点,上传到上一级目录吧,也就是 files/filename="%2e%2e%2ftest3.php" 响应提示上传成功。

收工。

至于上面上传 %2e%2e%2f%2e%2e%2ftest2.php 的问题,我发现当时我给写错了,多加了一个 ‘.’,.%2e%2e%2f%2e%2e%2ftest2.php,后面我又试了一下,没上传成功。可能是服务端不让在根目录下上传?

4 Lab: Web shell upload via extension blacklist bypass

仅修改 Content-Type,仍报错。

修改文件扩展名为 .jpeg

提示上传成功。

请求用户头像,/files/avatars/test.jpeg,仅能拿到内容,但无法执行 php 代码,且报头仍是 Content-Type: image/jpeg

审题发现,本题使用黑名单过滤

使用 .php5 作为扩展名,上传文件,但是也无法执行,只能回显出文件的内容。

上传 .htaccess 文件,将 .caishao 拓展名映射成 PHP 文件。

1
AddType application/x-httpd-php .caishao

扩展名为 .caishao 的文件都被解析成 php 并执行。

5 Lab: Web shell upload via obfuscated file extension

使用黑名单过滤文件扩展名总有其局限性,这个 lab 可以使用一些经典的绕过方式:双写绕过、大小写绕过、编码、00截断等。

响应提示:”only JPG & PNG files are allowed”,看来不得不使用 00 截断绕过了,修改文件名为test.php%00.jpg,根据响应报文,上传后的文件名为 test.php.

请求我们上传的“头像” /files/avatars/test.php,php 代码执行,拿到 secret.

如果服务端能执行 .jpg.png 文件的话(文件包含漏洞),好像也可以上传图片马。

6 Lab: Remote code execution via polyglot web shell upload

不同类型的文件在其文件头/尾都包含一些特殊的字节序列,.jpg 图片文件总是以 FF D8 FF 开头,我们可以把一句话木马隐藏到这些文件以绕过检查。写入一句话木马后的图片文件叫做“图片马”。

图片马制作:

  1. windows : copy 1.jpg/b+2.php 3.jpg
  2. archlinux:
    1. exiftool -Comment="<?php echo file_get_contents('/home/carlos/secret'); ?>" potato.jpg
    2. 使用十六进制编辑器,bless, 01Editor

使用 exiftool 将一句话木马写入一张 jpg 图片文件中。

1
exiftool -Comment="<?php echo file_get_contents('/home/carlos/secret'); ?>" potato.jpg

使用 bless 打开 potato.jpg 写入一句话后的文件,可以看到文件以 FF D8 FF 开头,因为是 JPEG 图片文件。

搜索 “php” 找到我们写入的 php 代码,其实也可以直接用 bless 在末尾写入恶意代码。

问题
burp 抓与头像有关的包时总是卡死,裂开。

答:报文太长了,头像太大了,电脑太拉了

上传了 potato.jpg 之后,一直没找到 secret,也不知道 php 代码执行没执行,就又做了一个图片马,发现响应报文中,代码被当成文本展示了出来。

通过查资料,图片中的 php 代码要执行的话还需要有文件包含漏洞,即将任意类型的文件当成 php 文件执行。

============ 官方 solution ============

1
exiftool -Comment="<?php echo 'START' . file_get_contents('/home/carlos/secret') . 'END'; ?>" potato.jpg -o caishao.php

后端只检查了文件头,没有检查拓展名。

上传,并请求“头像”,拿到 secret。

话说刚刚咋没想到将 exiftool 的输出文件写成 php 呢,我一直想着把我的这两个小土豆完整且优雅地上传上去,又能执行藏在里面的一句话木马 emmmm.

7 Lab: Web shell upload via race condition

题目要求获取 /home/carlos/secret 文件的内容,php 指令应为:

1
<?php echo file_get_contents('/home/carlos/secret'); ?>

上传之后的文件在 /file/avatars/ 目录下,且文件名也没有随机化处理

直接修改文件类型上传,报错。只能上传JPG和PNG文件。

%00截断也不行,解析成了字符串。

根据题目描述,尝试使用条件竞争上传文件。一开始我以为的竞争窗口是 文件上传和验证。将正常的JPG图片和PHP文件同时上传,类似 limit-overrun。后面发现并不行…

尝试寻找其它竞争窗口,很多系统在上传文件后会先将文件保存在服务端,验证失败后再删除。但在保存文件和删除文件之间有个时间差(竞争窗口),在这个时间差中访问文件不久能执行了嘛。使用单包攻击并行发送 upload 24.phpget 24.php 两报文,访问成功。

时隔一年多,终于把最后一个 lab 做了。

完结撒花