Table of Contents
upload的一般的检测手段及绕过方法总结:
一,前端的javascript检测:
一般的绕过方法:
1,禁用前端的javascript检测
2,直接F12,修改页面中的js检测代码
3,用burp suite进行中间修改:
二,服务端的MIME检测:
1,修改multipart/form-data,
2,修改content-type
三,服务端的文件后缀名检测:
一般的检测手段:
黑名单: 1,大小写绕过
2,特殊文件(.htaccess文件)的绕过
3,截断(0x00)绕过
4,利用系统特性绕过
5,Web Server解析漏洞绕过
IIS解析漏洞:
Nginx解析漏洞:
Apache解析漏洞:
白名单:1,截断(0x00)绕过
2,Web Server解析漏洞绕过
四,服务端的目录路径检测:
一般的绕过方法:(条件:目录路径可控)
1,若路径可控,则可以使用0x00或%00截断来绕过。
2,利用web容器(Apache,Ngnix,IIS)的解析漏洞
五,服务端的文件内容的检测:
一般的检测手段:(以图片上传为例)
一般的绕过方法:(以图片上传为例)
1,文件幻数检测绕过:
2,文件相关信息检测绕过:
3,文件加载检测(图像渲染,二次渲染)绕过:
六,WAF检测:
1,条件竞争
upload的一般的检测手段及绕过方法总结:
文件上传看起来是比较简单的,其实不然,因为涉及到了很多的情况,并且比赛中往往是结合文件包含,sql注入等,所以往往还是非常难搞的啊!下面就只简单梳理一下上传的绕过检测的方法,至于利用上传的木马,后门文件这里先不做讨论
(水平有限,错误缺漏,欢迎大佬指摘!)
一,前端的javascript检测:
该类检测代码直接写在网页中,一般提交后,立即有弹窗提示禁止上传,就可以判断为前端检测,或者直接右键查看页面源代码也能看到javascript的检测代码
一般的检测手段:文件后缀名检测,文件大小检测
一般的绕过方法:
1,禁用前端的javascript检测
可以直接将浏览器上的javascript 按键关闭,如果使用的是 Chrome ,firefox浏览器的话可以下载一个插件 Noscript 随时禁止js
2,直接F12,修改页面中的js检测代码
3,用burp suite进行中间修改:
先写一个一句话木马1.php,先将文件名修改为允许上传的后缀名(png,gif,jpg),然后再使用burp suite截取数据包,将后缀名修改为 php
二,服务端的MIME检测:
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。
是设定某种扩展名的文件用一种应用程序来打开的方式类型。
即在传输过程中标记文件类型的一种方法,也就是 HTTP 文件请求头中的 Content-Type 。Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以
什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是
下载一个文件或一张图片的原因。
这个地方我一直有点模糊,
为什么有时看到的Content-Type为 multipart/form-data,application/x-www-form-urlencoded,application/json,
有时看到的Content-Type为:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
- application/octet-stream 二进制流数据 (常见的文件下载)
怎么说呢?
第一个是包的headers的content-type,指代的是数据的编码方式
默认的是application/x-www-form-urlencoded,就会按照urlencode编码数据
有时还会碰到 application/json,就是数据按照json的格式编码
当为multipart/form-data 或者 Multipart/form-data时,代表在上传文件,boundary是一个字符串,用来切分数据
另一个代表上传文件类型的content-type(我是这样理解的)
例如当我们上传一个php文件的时候,content-type为 application/octet-stream 二进制流数据
当上传一个jpg图片的时候 content-type为 image/jpeg :jpg图片格式。。。。。
我们再文件上传的时候说的content-type都是指的第二个content-type
他是根据文件的后缀名决定的,一般有这几种:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
- application/xhtml+xml :XHTML格式
- application/xml: XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json: JSON数据格式
- application/pdf:pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
一般的检测手段:
一般采取白名单的方式来进行检测,如只能上传图像文件的话就Content-Type头就必须为image/jpeg或image/png或image/gif。
一般的绕过方法:
1,修改multipart/form-data,
一般文件上传是不会对 headers中的 content-type做限制,因为上传文件的时候它只会是 multipart/form-data或者Multipart/form-data,但不排除特殊情况,
例如 bugku中一个题: 求getshall
这个题有3个检测点,1:headers中的content-type必须是 Multipart/form-data;2:第二个content-type必须是图片类型即(image/png,image/jpeg);3:文件后缀名采用了黑名单的过滤方式,但少了一个php5
2,修改content-type
一般是利用burp suite进行抓包,然后修改Content-Type为image/png,image/jpeg,image/gif
三,服务端的文件后缀名检测:
一般的检测手段:
黑名单过滤:黑名单的安全性比白名单低很多,服务器端,一般会有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,常见黑名单:
文件类型 | 扩展名 |
---|---|
HTML | html、htm、sthml、shtm |
PHP | php、php2、php3、php4、php5、phtml、pwml |
ASP | asp、aspx、ascx、ashx、asa、cer、cdx |
JSP | jsp、jspx、jspf |
其他 | xml、ini、htaccess、cgi、pl、js、exe、bat、swf |
白名单过滤:仅允许指定的文件类型上传,比如仅允许上传jpg | gif | doc | pdf等类型的文件,其他文件全部禁止。
一般的绕过方法:
黑名单: 1,大小写绕过
也可以叫做 列表穷举绕过,原理的是使用 黑名单中不存在并且能正常解析的有害的文件名,如Php,PHp5,等,有时还会忘记一个特别重要的文件后缀 htaccess(这个一会再说)
这里我们可以制作一个专门的文件后缀名的字典 suffixname.txt,然后用burp suite上的爆破模块去爆破,这样就可以快速的检测出到底哪些 文件后缀被过滤了,哪些没有:
2,特殊文件(.htaccess文件)的绕过
如果发现可以上传.htaccess文件的情况,该文件仅在Apache平台上存在,IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。该文件的写法如下:
<FilesMatch "_php.gif">SetHandler application/x-httpd-php
</FilesMatch>
保存为.htaccess文件。该文件的意思是,只要遇到文件名中包含有”_php.gif”字符串的,统一按照php文件来执行。该文件在Apache里默认是启用的,如果没启用,启用方法见:http://www.jb51.net/article/25476.htm 然后就可以上传一个带一句话木马的文件,例如a_php.gif,会被当成php执行。该方法其实不是漏洞,是Apache的特性。该方法常用于黑客入侵网站之后,不想被发现,留一个隐蔽的后门。
3,截断(0x00)绕过
最常见的截断绕或要数 00 截断了,但是这种情况有很大的局限性,只有在 PHP 版本小于5.3.4 且 magic_quotes_gpc=Off时
Name = getname(http requests)//假如这一步获取到的文件名是dama.asp .jpg
Type = gettype(name)//而在该函数中,是从后往前扫描文件扩展名,所以判断为jpg文件
If(type == jpg)
SaveFileToPath(UploadPath.name , name)//但在这里却是以0x00作为文件名截断,最后以dama.asp存入路径里
(1)0x00截断:基于一个组合逻辑漏洞造成的,通常存在于构造上传文件路径的时候
test.php(0x00).jpg
test.php%00.jpg
路径/upload/1.php(0x00),文件名1.jpg,结合/upload/1.php(0x00)/1.jpg
Burp抓包,将文件名改为dama.php%00.jpg,选中%00,进行url-decode
或者将文件命名为123.php.jpg再在 burp suite 的proxy下 的hex中将 php后面的. 的2e改为 00
ascii 特殊字符包含
这里的例子是上海网安赛的 web4 ,参考了 sn00py 师傅的 wp
这道题先是前台 sql 注入拿到 admin 的密码之后,登录后台会发现有上传点
这里的上传有两个重要的参数,一个是文件目录(uploaddir),一个是文件名(filename)
上传之后会对 uploaddir 和 filename 直接进行拼接,然后直接加上 .txt 后缀。没办法从正面直接绕过,00 截断也是无效的,这里就尝试用 0x00~0xff 之内的 ascii 字符来截断。
burp 中发送数据包到 intruder 模块,将范围控制在 0~255 之间
用 intuder 模块的 payload 进行处理,先加上 % ,再进行 urldecode
在 0x02 时可以截断成功
4,利用系统特性绕过
在Windows系统中,上传index.php.
会重命名为index.php,可以绕过后缀检查。 也可尝试 index.php空格
,index.php:1.jpg
, index.php::$DATA
等。
在Linux系统中,可以尝试上传名为 index.php/.
或 ./aa/../index.php/.
的文件
5,Web Server解析漏洞绕过
一般最常用的web容器,IIS, Nginx, Apache
IIS解析漏洞:
版本:IIS5.X / IIS 6.0:
1,目录名中含有.asp字符串的(目录下)均按照asp文件进行解析;例如:index.asp/目录中的所有文件都会asp解析
当出现xx.asp命名的文件名,访问目录下任意一个文件,均会送给asp.dll解析(执行asp脚本)
2,文件名中含有.asp;
字符,即使时jpg格式文件,IIS也会按照asp对文件进行解析
当文件名xx.asp;xx.jpg,IIS6会将文件送给asp.dll解析(按照asp脚本解析);请求时:IIS从左往右检查.号,查询到;或/号则(内存)截断;如此执行后,IIS认识的就是xx.asp
3,默认解析:.asp .asa .cer .cdx IIS6 同时默认解析前面三个文件后缀,都会给asp.dll解析
版本 IIS 7.0 /7.5
1,默认开启 Fast-CGI 状态,在一个服务器文件URL地址后面添加xx.php
会将xx.jpg/xx.php
解析为PHP文件
Nginx解析漏洞:
Nginx <= 0.8.37 影响版本:0.5/0.6/<0.7.65/<0.8.37
1,Fast-CGI开启状态下,存在如同IIS7一样的漏洞:URL地址后面添加xx.php
会将xx.jpg/xx.php
解析为PHP文件
http://ultramangaia.cn/gg.jpg,在这个网址后面加上1.php,
即http://ultramangaia.cn/gg.jpg/1.php,会被解析成PHP脚本
2,空字节:http://ultramangaia.cn/gg.jpg
,在这个网址后面加上%00.php
,即http://ultramangaia.cn/gg.jpg%00.php
会导致解析为PHP脚本
Apache解析漏洞:
1,Apache解析文件的规则时从右到左开始判断,如果后缀名为不可识别文件解析,则会继续向左判断,直至可以正确识别
白名单:1,截断(0x00)绕过
跟黑名单的截断绕过一样,详情参考黑名单的截断绕过
2,Web Server解析漏洞绕过
跟黑名单的解析漏洞一样
四,服务端的目录路径检测:
一般是检测上传的目录路径是否合法。
一般的绕过方法:(条件:目录路径可控)
1,若路径可控,则可以使用0x00或%00截断来绕过。
这里的%00截断是用于GET方式中的,主要在目录路径上做手脚
2,利用web容器(Apache,Ngnix,IIS)的解析漏洞
解析漏洞的详情参考上文黑名单的绕过,区别是黑名单绕过时主要在filename上做手脚,而这里主要是在目录路径上做手脚
五,服务端的文件内容的检测:
如果文件内容检测设置的比较严格,那么上传攻击将变得非常困难。以最常见的图片类型内容检测举例。
一般的检测手段:(以图片上传为例)
文件幻数检测(文件头)
文件相关信息检测
文件加载检测(渲染加载)
一般的绕过方法:(以图片上传为例)
1,文件幻数检测绕过:
即文件头检测,主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下:
JPG文件:FF D8 FF E0 00 10 4A 46 49 46
GIF文件: 47 49 46 38 39 61
PNG文件:89 50 4E 47
只需要用winhex打开一句话木马文件然后在16进制内容中将上面的图片头放在文件开始的位置就ok了
或者 找一个图片 在文件头后面插入一句话木马就行了
特殊情况是按照黑名单检测,比如检测php的头,<?php
这时候我们可以用 <script language="php">绕过(自PHP 7.0.0起,被移除)
<script language="php">
@eval($_POST["pass"]);
</script>
制作图片马:http://gv7.me/articles/2017/picture-trojan-horse-making-method/
2,文件相关信息检测绕过:
图像文件相关信息检测常用的就是getimagesize()函数和exif_imagetype()函数等。
getimagesize()函数的返回结果类型是个数字,其中索引2表示的是图像的类型,返回的是数字,
其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF,8 = TIFF,9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。
exif_imagetype():读取一个图像的第一个字节并检查其签名。
基本的绕过原理就是,先把文件头部分伪造好,再在幻数加上了一些文件信息,比如GIF文件中添加的信息:
GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)
用图片马的方法可以通杀,但是是需要能够正常显示的图片马。
深入了解 getimagesize()和imagemagick()函数:
https://www.leavesongs.com/PENETRATION/when-imagemagick-meet-getimagesize.html
3,文件加载检测(图像渲染,二次渲染)绕过:
这个是最变态的检测,一般是调用API或函数去进行文件加载检测。常见的是图像渲染和二次渲染。
二次渲染的原理是调用imagecreatefromjpeg()函数对图像进行二次编译即进行了二次渲染。
imagecreatefromjpeg():由文件或URL创建一个新图象。
渲染绕过:先用 GIMP 对一张图片进行代码注入
用 winhex 看数据可以分析出这类工具的原理是 在不破坏文件本身的渲染情况下找一个空白区进行填充代码 一般是图片的注释区
对于渲染测试基本上都能绕过
但如果碰到变态的二次渲染 基本上就没法绕过了,估计就只能对文件加载器进行攻击了
二次渲染:是关于upload-labs pass16 的详细分析 https://xz.aliyun.com/t/2657
六,WAF检测:
一般的检测手段较为复杂
一般的绕过手段也是千奇百怪,
大小上限:有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验;
当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。
可以将垃圾数据加上Content-Disposition参数后面,参数内容过长,可能会导致waf检测出错。
filename:针对早期版本的安全狗,可以多加一个filename来绕过,
3 POST/GET
有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。
此种情况可以上传一个POST型的数据包,抓包将POST改为GET。
1,条件竞争
条件竞争是指一个系统的运行结果依赖于不受控制的事件的先后顺序。
当这些不受控制的事件并没有按照开发者想要的方式运行时,就可能会出现 bug。
尤其在当前我们的系统中大量对资源进行共享,如果处理不当的话,就会产生条件竞争漏洞。
如果文件检测是先保存后检测,文件不合法再删除的方式进行的,典型的“引狼入室”。
就可以利用条件竞争的方式在木马文件在被删除之前访问它,使他成功的执行
具体的操作过程就是,利用工具,一边不断地快速上传木马文件,一边不断的请求访问上传的木马文件,使一些来不及被删除的木马文件被成功执行
具体例子:
upload-labs pass17 条件竞争:
$is_upload = false;
$msg = null;if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_name = $_FILES['upload_file']['name'];$temp_file = $_FILES['upload_file']['tmp_name'];$file_ext = substr($file_name,strrpos($file_name,".")+1);$upload_file = UPLOAD_PATH . '/' . $file_name;if(move_uploaded_file($temp_file, $upload_file)){if(in_array($file_ext,$ext_arr)){$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;rename($upload_file, $img_path);$is_upload = true;}else{$msg = "只允许上传.jpg|.png|.gif类型文件!";unlink($upload_file);}}else{$msg = '上传出错!';}
}
可以看到文件先经过保存,然后判断后缀名是否在白名单中,如果不在则删除,此时可以利用条件竞争在保存文件后删除文件前来执行php文件。
先利用burp suite抓一个文件上传的包,右键 Send to Intruder 》添加爆破点 》添加payload,先暂时不开始爆破
我是在一句话后面加了个 爆破点,不影响一句话的执行,至于payload我随便找了个相对较长的字典10000.txt
然后再在浏览器上访问 127.0.0.1/upload-labs/upload/1.php,利用 burpsuite抓包,右键 Send to Intruder 》添加爆破点 》添加payload字典, 字典还用 10000.txt
然后两个爆破 同时点击 Start Attack ,一个上传,一个访问,然后你就会发现有成功访问的包
成功访问到了还没来得及删除的非法文件
参考文章:https://thief.one/2016/09/22/%E4%B8%8A%E4%BC%A0%E6%9C%A8%E9%A9%AC%E5%A7%BF%E5%8A%BF%E6%B1%87%E6%80%BB-%E6%AC%A2%E8%BF%8E%E8%A1%A5%E5%85%85/
https://www.mi1k7ea.com/2019/10/14/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93/
https://www.secpulse.com/archives/95987.html
https://xz.aliyun.com/t/2657