upload-labs通关记录

upload-labs


项目地址:https://github.com/c0ny1/upload-labs

靶机包含漏洞类型分类

如何判断上传漏洞类型?

文件上传漏洞测试流程

  1. 对文件上传的地方按照要求上传文件,查看返回结果(路径,提示等)
  2. 尝试上传不同类型的“恶意文件”,比如xx.php文件,分析结果
  3. 查看html源码,看是否通过js在前端做了上传限制,可以绕过
  4. 尝试使用不同方式进行绕过:黑名单绕过/MIME类型绕过/目录0x00截断绕过等
  5. 猜测或者结合其他漏洞(比如敏感信息泄露等)得到木马路径,连接测试

Pass 1-JS脚本


上传脚本,提示文件类型不对,可能是前端js脚本检验文件

查看源代码,限制上传文件后缀名

方法一

可以通过burpsuite阻断抓包修改文件后缀名

将脚本修改为png,阻断抓包修改文件后缀名,转发给服务器

验证上传脚本

方法二

通过火狐中插件Script Blocker Ultimate,阻止js脚本运行

选择脚本进行上传

验证上传脚本

Pass 2-Content-Type


上传脚本,文件类型不正确,可能是前端js脚本检验文件

查看源代码,检验上传文件媒体类型,

方法一(步骤同上)

先将脚本后缀名修改为png,通过burpsuite阻断抓包修改文件后缀名

方法二

通过burpsuite阻断抓包修改文件媒体类型

选择脚本进行上传,阻断抓包将Content-Type:修改为image/png,转发给服务器

验证上传脚本

Pass 3-黑名单


上传脚本,不允许上传.asp,.aspx,.php,.jsp后缀文件!,可能是前端js脚本设置黑名单

查看源代码,分析源代码

设置文件后缀名黑名单,先删除文件末尾的点,在将文件后缀分离

将文件后缀名转成小写(不能进行后缀名大小写绕过黑名单)

去除字符串::$DATA(不能通过后缀名::$DATA绕过黑名单)----(这个绕过方法只适用于windows系统,在window的时候如果文件名+"::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名)

最后将过滤的后缀名对照黑名单进行判断

末尾去空格(不能通过末尾加空格绕过黑名单)

修改上传文件名,进行存储

方法一

通过使用黑名单之外的可以被解析的后缀名,进行绕过

用黑名单不允许上传.asp,.aspx,.php,.jsp后缀的文件
但可以上传.phtml .phps .php5 .pht
前提是apache的httpd.conf中有如下配置代码,并重启apache服务

AddType application/x-httpd-php .php .phtml .php2 .php3 .php4 .php5 .phpt

方法二

::$D::$DATAATA

网站的js脚本只进行一遍过滤,通过::$DATA嵌套的方式,绕过上传检验

可以通过burpsuite阻断抓包修改文件名+::$D::$DATAATA

js脚本::$DATA将替换成空格,但是只是替换一次,::$DATA绕过黑名单依然有效

验证上传脚本时,将链接中::$DATA去掉

Pass 4-.htaccess


上传脚本,此文件不允许上传!

查看源代码,检验脚本除黑名单增加后缀名,代码几乎一致

方法一

还是存在着黑名单过滤,所以需要找到黑名单之外的一个文件后缀

找到的就是.htaccess文件,可以重写规则

htaccess文件:是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

.htaccess文件生效,

需要两个条件

一、在Apache的配置文件中写上:AllowOverride All

二、Apache要加载mod_Rewrite模块

原理:他没有过滤 .htaccess后缀,我们可以构建一个htaccess配置文件,让所有格式文件都解析为php,然后再上传图片马(只要后缀是允许的,随便都可以)就会被解析了。

上传.htaccess文件

上传图片木马

验证上传脚本

Pass 5(适用于php-nts版本).user.ini


上传脚本,此文件类型不允许上传!

查看源代码,检验脚本除黑名单增加后缀名,代码几乎一致

方法一

上传.user.ini配置文件,在当前目录下生效,将1.gif包含到文件夹中php文件中

将脚本修改为1.gif,进行上传

打开文件夹中readme.php,验证上传脚本

Pass 6-大小写绕过


上传脚本,此文件类型不允许上传!

查看源代码,没有进行后缀名的大小写绕过

方法一

将脚本后缀名修改为.Php,进行绕过,转发给服务器

验证上传脚本

Pass 7-空格绕过


上传脚本,此文件类型不允许上传!

查看源代码,没有对首尾的空格进行限制

方法一

Pass 3的方法二

方法二

网站的js脚本没有对首尾的空格进行限制

可以通过burpsuite阻断抓包将文件修改文件名+空格,绕过黑名单

选择脚本进行上传,进行抓包,修改

验证上传脚本

Pass 8-点号绕过


查看源代码,没有去除末尾的点

方法一

网站的js脚本没有对末尾的点进行限制

可以通过burpsuite阻断抓包将文件修改文件名+.,绕过黑名单

选择脚本进行上传,进行抓包,修改

验证上传脚本

Pass 9-::$DATA


查看源代码

方法一

没有对::$DATA进行限制,同PASS 3 方法一,但是不用进行嵌套

Pass 10-.点空格点绕过


查看源代码

方法一

删除末尾的点,以点切割后缀名,去空格,去::$DATA,最后用的删除末尾的点的文件名

原理同Pass 7 方法二,将文件名修改为文件名. .,即可绕过

Pass 11-(黑名单验证,双写绕过)


查看源代码

方法一

将符合的字符串,替换为空,可以通过后缀名嵌套,绕过

例如:555.pphphp

Pass 12-GET-%00


查看源代码,设置白名单

漏洞利用条件

截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

1、php版本小于5.3.4

2、php的magic_quotes_gpc为OFF状态

白名单判断,但$img_path是直接拼接,因此可以利用%00截断绕过。

Pass 13-POST-%00


查看源代码

与Pass-12的区别是这里使用POST传地址

为何POST型需要进行URL编码:

这是因为 %00 截断在 GET 中被 url 解码之后是空字符。

但是在 POST 中 %00 不会被 url 解码,

所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。

Pass 14-图片马绕过


查看源代码,只检查前两个字节,判断是否图片,并将判断的图片类型作为文件

方法一

伪造头部GIF89A

在脚本第一行写上GIF89a,将脚本伪造gif文件

方法二

将图片和脚本合成新的图片

Cmd: copy /b 6png + 111.php ccc.png

方法三

使用010Editor软件在图片中写入脚本

结合文件包含漏洞,进行利用

http://localhost/upload-labs-master/include.php?file=./upload/3120210813181355.jpg

Pass 15-图片马绕过


方法同Pass 14

Pass 16-图片马绕过


方法同Pass 14

注:适用于php-nts版本,需要勾选php扩展php_exif

Pass 17-图片马加二次渲染


二次渲染后的图片,使用用户上传图片生成的新图片,上传图片,和原图片对照,将脚本插在未被渲染的位置

Gif

Pass 18-白名单验证-条件竞争


查看源码

方法一

直接上传图片马

方法二

当我们上传webshell后,没有第一时间做文件后缀名的校验,而是临时存放,移动到新位置后,再做文件名检验。

这时系统代码执行过程会有时间消耗,我们利用这个极短的时间,利用Burp进行发包和范文,就有可能访问到没来得及做文件校验的webshell

1.php 执行php在创建一个php文件

');

?>

使用burp suite分别抓取上传文件和打开上传文件地址的数据包,传到Intruder模块,设置数据包无限重发

上传文件数据包

手工打开浏览器快速点击URL访问1.php,抓取数据包

http://localhost/upload-labs-master/upload/1.php 上传文件地址

将两个数据包进行无限重发

访问http://localhost/upload-labs-master/upload/shell.php

Pass 19-白名单验证-图片马


验证过程:依次检查文件是否存在、文件名是否可写、检查后缀(白名单)、检查文件大小、检查临时文件存在、保存到临时目录里、然后再重命名

方法一

直接上传图片马

Pass 20-代码审计-黑名单验证-点号绕过


查看源码

pathinfo($file_name,PATHINFO_EXTENSION)

获取获取上传文件后缀名

pathinfo(string $path [,int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME])

/*

返回一个关联数组包含有path的信息。返回关联数组还是字符串取决于options

PATHINFO_DIRNAME:文件所在目录

PATHINFO_BASENAME:文件+后缀名

PATHINFO_EXTENSION:后缀名

PATHINFO_FILENAME:文件名

方法一( . 绕过)

使用 . 进行绕过文件后缀名检查

http://localhost/upload-labs-master/upload/111.Php.

方法二(post的%00截断)

截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

方法三(适用于php-nts版本)

上传.user.ini配置文件,将1.gif包含到php文件中

Pass 21-代码审计-白名单验证-数组绕过


查看源码

验证过程:先检查MIME,通过后检查文件名,保存名称为空的就用上传的文件名。再判断文件名是否是array数组,不是的话就用explode()函数通过.号分割成数组。然后获取最后一个,也就是后缀名,进行白名单验证。不符合就报错,符合就拼接数组的第一个和最后一个作为文件名,保存。

绕过过程:绕过MIMIE,改一下包的Content-Type,为了绕过explode()函数,需要传入数组,绕过白名单,由于取的是end()也就是数组最后一个,需要传入数组的最后一个为jpg|png|gif,最后是拼接文件名,取的是reset()第一个,即索引为0,和索引count()-1(数组内元素个数-1)。所以令索引0为1.php,索引2为jpg(只要是索引1之后都可),这样数组元素个数为2,拼接的就是索引0和索引1,也就是1.php和空,结果还是1.php,这样就可以使得拼接后的文件名为1.php。如下:

总结防御

1、黑白名单;

2、对上传的文件重命名,不易被猜测;

3、对上传的内容进行读取检查;

4、不要暴露上传文件的位置;

5、禁用上传文件的执行权限;

posted @ 2021-09-22 09:54  纸机  阅读(1012)  评论(0编辑  收藏  举报