upload-labs通关详解

upload-labs通关详解

一、Pass-01

查看源码,发现变量前有var,可以代码语言是JS

substring():裁剪字符串

lastIndexOf():返回某个子字符串在字符串中最后出现的位置

var ext_name = file.substring(file.lastIndexOf("."));的含义为把"."和"."后面的字符串裁剪出来放到ext_name中

方法1:

由代码可知是JS语言且为前端验证,可以直接禁用JS直接上传php文件

方法2:

上传一个普通图片,使用burp抓包,修改图片内容和文件后缀

1

打开图像地址,输入参数phpinfo验证是否执行木马

2

二、Pass-02

由源码可知,代码语言为PHP,且此题判断MIME类型

只需要使用burp修改Content-Type即可成功上传

三、Pass-03

查看代码,此题为黑名单过滤

array():数组

trim():删除首尾的空

deldot():删除文件名末尾的点

strrchr():用某一字符去分割字符串,本题为用"."分割文件名获取后缀名

strtolower():转为小写

str_irplace():替换,本体为把文件名中的"::$DATA"替换为空

修改文件名,直接上传即可

四、Pass-04

代码和上一题差不多,只是增加了黑名单的内容

我们可以上传htaccess,通过h来指定某个后缀名用php引擎解析(Apache特性)

3

此.htaccess的作用:让服务器访问当前目录下的文件时,遇到app后缀文件就使用php的引擎去解析并执行

先上传shell.app文件,成功后可以打开图片地址,但它内部的一句话木马并不会执行被当作php脚本执行,而是直接展示出来

之后再上传.htaccess文件,刷新图片地址,一句话木马就可以执行了

4

五、Pass-05

这道题是针对Nginx环境的题目,但此靶场用的是Apache环境,所以这里就不涉及了

六、Pass-06

由源码可知,这一关没有强制将大写转换为小写,所以我们可以上传纯大写或者大小写结合的后缀名

修改文件名为纯大写,直接上传即可

七、Pass-07

查看源码,发现和前面相比缺少了trim()【首尾去空】,可尝试用空格绕过

【strrchr()用点去分割时,分割到了.php 的内容,但.php 并不在黑名单中于是上传成功,又因为在存储文件时windows会自动去除文件名末尾的空格,所以就只剩下了.php】

先用burp拦截,在文件名的后缀后面加上空格后发包,即可上传成功

5

八、Pass-08

此题没有了删去末尾的点,我们可以利用windows自动去除文件名后缀后面的点这一特性进行绕过

先上传shell.php,使用burp拦截,在后缀后面加上点

6

发包即可成功上传

九、Pass-09

此题缺少了把"::$DATA"替换为空,那么我们就可以使用burp拦截并在后缀后面加上”::$DATA“发包即可成功上传(访问图片地址时要去掉”::$DATA“)

::$DATA为NTFS文件流的特性,其表示为文件内容本身,大部分windows系统都是NTFS文件系统

十、Pass-10

此题为代码逻辑的问题,先删除首尾的空格(如,asdad a ,其只会删除a后的空格变成asdad a),然后删除文件名末尾的点(如a. .删除末尾的点后变成a. ),所以我们可以构造一个特殊的后缀(根据代码反着来),使其经过删除后还能保留一些东西

构造好的后缀:xxx.php. .

先经过首尾去空(首尾没有空)——>xxx.php. .——>去除末尾的点——>xxx.php. ——>首尾去空——>xxx.php.

获取到的文件名后缀为.php.,并不在黑名单中,而windows在复制或移动文件时自动去掉后缀名中的“.”,后缀名就变为了php

使用burp拦截,更改后缀名

7

发包,成功绕过

十一、Pass-11

由代码可知,此题将文件名后缀与黑名单匹配,若在黑名单中则替换成空

看到replace,尝试双写绕过

两种双写:pphphp和phphpp,文件读取是从左往右读取,后者会直接读取到php然后删除

我们直接双写文件名后缀然后上传,即可成功

8

十二、Pass-12

计算机存储字符串是通过其结尾的结束符(00)来分辨是否结束读取(如,8023占5个空间,包含了一个结束符),这也是截断漏洞的产生原因

substr(被裁剪的字符串,从哪个位置开始裁剪)

strrpos(待寻找的字符串,要寻找的字符):在字符串中寻找某个字符并返回它的位置

9

由代码可知,此题为白名单

我们先上传一个jpg文件,开启burp拦截,然后修改save_path

10

发包,复制图片地址,成功访问(去掉php后面的东西)

12

save_path拼接原理:

11

%00为url编码,但服务器接收的是一个ASCII码为00的字符(字符串结束符)

所以把"../upload/xxx.php[]/5520230110152511.jpg"传进去后,系统保存时要读取变量,当读取到php后的字符串结束符时会认为文件名已读完,从而把文件存储为"../upload/xxx.php"【jpg后面本身也有一个字符串结束符】

十三、Pass-13

代码和Pass-12基本完全一样,只是把GET请求换成了POST请求

13

我们可以上传一个图片抓包验证一下

14

我们可以看到save_path在POST请求中

这样就不能和Pass-12一样直接在路径后面加上xxx.php%00绕过了(%00为URL编码,只能在GET请求中使用,在POST请求会把%00的三个ASCII码而不是一整个字符串结束符发送给服务器)

那么我们可以先上传jpg文件,用burp拦截,然后在路径后写上yyy.php,并在后面随便输入一个占位符(如:#,ASCII码为23或空格,ASCII码为20)

15

使用Hex模块,找到路径位置,修改#的ASCII码为00,使其变为字符串结束符

16

17

此时,回到Raw模块,我们就可以看到php后面有个像空格而不是空格东西

18

发送数据包即可成功上传,删除截断后的内容即可成功访问图片地址

十四、Pass-14

点击文件包含漏洞,查看代码

$file = $_GET['file'];含义为:把用户使用get请求传输的file参数赋值给新定义的变量file,然后判断用户 是否为file,若不是file则显示源代码(当前页面);若是,则包含此文件

再查看源码

$bin = fread($file, 2);含义读文件的两个字节,用来判断文件头是否是真的图片文件(每一个图片的文件头都是固定的,如ping的开头为GIF89a)

所以,我们需要制作一个图片码

38

上传制作好的图片码,利用文件包含漏洞去包含我们上传的图片码即可成功执行

39

十五、Pass-15

$info = getimagesize($filename); 含义为获取图片大小(像素信息),若是php文件重命名为图片文件,是没有像素、尺寸等信息的

所以我们可以继续使用图片码来绕过

操作同Pass-14

十六、Pass-16

$image_type = exif_imagetype($filename);检验图片的扩展信息,如下图所示

40

本题通过exif信息来检测是否为图片文件,那么我们依旧可以使用图片码来绕过

操作同Pass-14和Pass-15

十七、Pass-17

此题使用了imagecreatefromjpeg()二次渲染(可以理解成将上传的图片再另存为一份,虽然图片一样,但内部信息会有所不同),所以图片码中的php脚本会消失

jpg内容少,php代码无论插入哪个位置都容易被压缩掉;png有严格的格式(每隔几位都有校验)【这两个都可以插入,但是要特别精细,需要第三方软件的帮助】

所以我们选择gif插入php语句

上传一个gif文件,开启burp拦截并且插入php代码(在中间偏下的位置)

41

发包后,图片底色变绿,说明没有什么问题

42

使用文件包含,成功执行

43

十八、Pass-18

此题为条件竞争漏洞

unlink():删除

由代码可知此题整个上传的流程为:①把文件移动到web可访问的目录②判断文件是否合法,合法则重命名,不合法则删除

22

但是此逻辑存在问题,在把文件移动到web可访问的目录到删除非法文件之间的时间里,我们是可以访问非法文件的(此时文件还在验证或还没删除),于是就可以利用这个时间差进行攻击

因为我们上传的文件是一个不持久的文件,无论怎样其只能存在很短的时间(不到1ms),若用这1ms去提交一个请求,那完全是可以的,但要是想用蚁剑或菜刀进行连接,我们就需要一个稳定的,可持续化的连接(有一个持久的文件放在服务器上供我们访问),但因为由过滤存在,只要是不合法文件,最后必然会被删除,我们只能尽量去延长其存在的时间(ms级别的延长),于是我们可以制作一个生成木马的木马

例如,上传一个生成木马的木马gen.php,我们在文件移动到删除的时间差里访问该木马,其就会输出一个shell.php放到服务器中,那么此时时间线向后推移,服务器开始删除非法文件,但服务器删除的是gen.php(因为用户上传的是gen.php,而前面验证的也是gen.php,也就是说gen.php生成的shell.php是排除在时间线之外的,不参与整个程序的逻辑,前面所有流程,上传、移动、验证、删除都是针对gen.php的),于是我们就可以通过gen.php获取持久化的连接

解决了持久化连接的问题,我们还需要解决如何快速触发gen.php的问题(尽快、频繁的访问,也可以尽快、频繁的上传【发包】)

首先,制作生成木马的木马

23

然后我们可以使用burp抓包(访问和上传两个包),发送到攻击器,从而达到频繁访问/上传

上传gen.php,此时提示上传失败(说明文件已经通过了流程,并进行了最后一步的删除)

24

再上传一个jpg,访问其图片地址,但要把文件名改为gen.php,从而获取访问gen.php的数据包

25

把这两个包发送至攻击器

不需要变量(清空),设置no payload,只需要提交请求即可(两个都这么设置)

26

修改线程数(拉高)

27

开始爆破(先上传后访问)【可能不能一次成功,多尝试几次】

根据长度排序(状态码排序找不出),找到成功上传

28

将图片地址改为shell.php即可访问

29

十九、Pass-19

require_once()为文件包含:在一个文件中引入另一个文件

require_once("./myupload.php");含义为在index.php中引入 myupload.php

由代码可知,此题有后缀名检查的白名单(checkExtension),可以考虑截断/解析漏洞

并且可由代码看到上传的流程:检查后缀名——>移动——>重命名

31

所以,此题可以使用Apache解析漏洞(因为没有用户可控的文件名和路径,所以不能用截断)

我们需要找到一个在白名单中,但Apache不识别的后缀名(如7z和rar),进行尝试

先上传一个jpg找到重命名规则,访问图片地址,发现文件名被重命名为一个随机数

30

所以我们只有在移动和重命名之间访问才能触发解析漏洞,那么此题也是条件竞争【Apache解析漏洞+条件竞争的综合利用】,和Pass-18差不多

首先使用burp抓两个包(上传gen.php.7z和访问gen.php.7z)发送至攻击器

32

其余设置同Pass-18

此题成功率较高,访问大部分都是200(因为代码较长,执行时间比Pass-18长),与Pass-18相反

33

上传成功,访问shell.php

34

二十、Pass-20

$file_name = $_POST['save_name'];含义为获取文件名

$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);含义为取后缀名

此题也是截断漏洞

看到文件路径和文件名是可控的,首先要想到截断漏洞!!!

我们可以在保存名称处同Pass-12、Pass-13一样,设置截断

开启burp拦截,上传一个jpg文件(保存名称随意),在burp中修改保存名称

19

在Hex模块中修改占位符为00

20

回到Raw中,可以看到修改成功

21

发送数据包即可成功上传

二十一、Pass-21

$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];含义为:若用户没有使用post表单定义文件名,则使用文件本身的文件名;若提交了名称,则用提交的名称赋值

explode():把字符串用某一字符打散,如:‘aaa.bbb.ccc’——>【‘aaa’,‘bbb’,'cc'】

end():取末尾元素

reset():取开头元素

count():计算数组中元素个数

此题使用了MIME和后缀名白名单,且通过拼接无法使用Apache解析漏洞

开启burp拦截,上传shell.jpg

将下图的内容复制一份

35

修改内容

37

发送数据包即可成功上传

36

因为我们上传的是jpg文件,所以一开始的MIME验证就已经绕过了

检查文件名和:若用户提交的save_name为空,则用文件名;若不是空,则用用户提交的save_name,而我们提交了save_name[0]

接下来判断数组,很明显save_name[0]是数组(只有数组才有下标),所以没有用”.“打散

而在上图中,我们可以看到,我们给数组0号元素赋值为webshell.php,2号元素赋值为jpg,所以上传上去的数组内容是[‘webshell.php’, ,'jpg'](没有上传1号元素)

然后end()取文件末尾元素(后缀名)jpg,通过判断jpg符合白名单

reset()取头元素webshell.php,加上一个”.“,count()计算数组中的元素个数为2,然后$file[count($file)-1]取数组的第一个元素(空),所以此时存在服务器的文件名为webshell.php.,而windows会自动把最后的点去掉,那么最后剩下一个webshell.php

于是我们就通过数组的特性来绕过本题的过滤

posted @ 2023-01-15 12:57  佐迦  阅读(1090)  评论(0编辑  收藏  举报