upload-labs
BBUCTF的upload-labs关卡
概述
下图为upload-labs的上传漏洞分类

PASS-01(JS检查)
1.分析
1 | function checkFile() { |
选择php文件之后,上传显示

数据还没有发送,就开始检测,说明是客户端检测
2.绕过思路
1.将php文件后缀名改为jpg
2.打开burpsuite->Proxy->intercept->Option,开启Remove all JavaScript

2.开始上传并使用burpsuite拦截

3.将文件后缀名改为php

PASS-02(MIME验证)
1.分析
1 | $is_upload = false; |
代码中定义MIME类型为image/jpeg的才能上传
1 | if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) |
2.绕过思路
使用burpsuite修改content-type类型

PASS-03(黑名单绕过)
1.分析
1 | $is_upload = false; |
服务器端检测asp、aspx、php、jsp
2.绕过方法
除了以上四个后缀不能上传,我们可以上传其他任意后缀,比如:.phtml .phps ,.php3.php5 .pht。所以,将文件后缀名改为php3开始上传。
PASS-04(.htaccess绕过)
1.分析
黑名单限制了更多的后缀不允许上传,但是并没有限制.htaccess文件。
2.htaccess文件
这类文件是apache服务器的一个配置文件,他负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。
3.绕过方法
1.首先上传一个内容为SetHandler application/x-httpd-php的.htaccess文件,让之后上传的所有文件解析成php文件。

2.之后开始上传php文件

PASS-05(大小写绕过)
1.分析
1 | $is_upload = false; |
查看源码还是黑名单限制,也加上了.htaccess,但是没有将后缀大小写统一,所以大小写绕过
2.绕过方法
将文件后缀改换大小写
PASS-06(空格绕过)
1.分析
1 | $is_upload = false; |
2.绕过方法
黑名单中添加了更多的后缀名,但是没有对后缀名去除空格,所以可以才后缀名中添加空格。

PASS-07(点绕过)
1.分析
1 | $is_upload = false; |
从代码上看,虽然加上了首位去空,但是缺少尾部去点,因此可以利用windows文件命名规则绕过。
2.绕过方法
burpsuite中改包加上.

PASS-08(::$DATA绕过)
1.分析
1 | $is_upload = false; |
依然是黑名单,但是没有对后缀名去“::$DATA”处理,利用windows特性,在后缀名中加上“::$DATA”绕过。
2.DATA为什么能绕过
NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$
DATA。
简单讲就是在php+windows的情况下:如果文件名+”::$DATA” 会把::DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::$DATA”之前的文件名。
3.绕过方法
使用burpsuite改包,在后缀名中加上”::$DATA”

PASS-09(点空格点绕过)
1.分析
1 | $is_upload = false; |
黑名单类型,有大小写处理,去::$DATA处理,首尾去空处理,去点处理。但是这里的代码逻辑是先删除文件末尾的点,再进行首尾去空。都只进行一次。所以可以在后缀名中加上点空格点绕过。
上传时,代码会先将末尾的.去除,剩余.+空格,利用windows文件命名规则,windows会忽略文件末尾的.和空格。
2.绕过方法
使用burpsuite改包

PASS-10(双写绕过)
1.分析
1 | $is_upload = false; |
| str_ireplace()函数 | |
|---|---|
| 功能 | 替换字符串中的一些字符(不区分大小写)。 |
这里将文件的后缀名替换为空,于是可以利用双写绕过。
2.绕过方法
我们可以使用双写后缀绕过,如果将后缀改为pphphp,服务器端检出到中间的php会替换为空,剩下的正好组成php,但是改为pphhpp就不行,源代码只会把第一次出现相连的php替换为空。

前十关总结
做了十关,我得到了一些结论,如果想要做好防御,开发的时候必须考虑:
| 1.使用trim()函数移除字符串两端的空白字符或其他预定义字符 | |
| 2.使用deldot()函数删除文件名末尾的点 | |
| 3.使用strtolow()函数将字符转为小写 | |
| 4.去除::$DATA字符串 | |
| 5.使用trim()首尾去空 |