文件上传Bypass安全狗

  • A+
所属分类:安全文章

0x00 前言

 

我们知道WAF分为软WAF,如某狗,某盾等等;云WAF,如阿里云CDN,百度云CDN等等;硬WAF,如天融信,安恒等等,无论是软WAF、云WAF还是硬WAF,总体上绕过的思路都是让WAF无法获取到文件名或者其他方式无法判断我们上传的木马(PHP、JSP、ASP、ASPX等等)。

 

这里总结下关于软waf中那些绕过文件上传的姿势和尝试思路,这里选择绕过的软waf为某狗4.0,可能其他软waf在拦截关键字方面可能会有差异,但绕过软waf的大体思想都是相同的,如果文章中有错误,欢迎师傅们斧正。

 

0x01 初探原理

 

写这篇文章时想过一个问题,如何总结哪些属于文件上传Bypass的范畴?打个比方:

 

上传正常.jpg的图片 #成功

上传正常.php #拦截

绕过.php文件的filename后进行上传 #成功

使用绕过了filename的姿势上传恶意.php #拦截


以上这么个逻辑通常来讲是waf检测到了正文的恶意内容。再继续写的话就属于免杀的范畴了,过于模糊并且跑题了,并不是真正意义上的文件上传Bypass,那是写不完的。

 

上传文件时waf会检查哪里?

 

请求的url

Boundary边界

MIME类型

文件扩展名

文件内容

 

常见扩展名黑名单:

 

asp|asa|cer|cdx|aspx|ashx|ascx|asax

php|php2|php3|php4|php5|asis|htaccess

htm|html|shtml|pwml|phtml|phtm|js|jsp

vbs|asis|sh|reg|cgi|exe|dll|com|bat|pl|cfc|cfm|ini

 

测试时的准备工作:

 

  • 什么语言?什么容器?什么系统?都什么版本?

  • 上传文件都可以上传什么格式的文件?还是允许上传任意类型?

  • 上传的文件会不会被重命名或者二次渲染?

 

0x02 环境介绍

 

实验环境:mysql + apache/iis +php

 

waf:某狗4.0

 

这里用了一个简单的上传页面判断,观察代码可以发现只允许上传Content-Type为image/gif、image/jpeg、image/pjpeg三种形式的文件


<html><body>

<form action="upload.php" method="post"enctype="multipart/form-data"><label for="file">Filename:</label><input type="file" name="file" id="file" /><br /><input type="submit" name="submit" value="Submit" /></form>

</body></html><?phperror_reporting(0);if ((($_FILES["file"]["type"] == "image/gif")|| ($_FILES["file"]["type"] == "image/jpeg")|| ($_FILES["file"]["type"] == "image/pjpeg")))//&& ($_FILES["file"]["size"] < 20000)){if ($_FILES["file"]["error"] > 0){echo "Return Code: " . $_FILES["file"]["error"] . "<br />";}else{echo "Upload: " . $_FILES["file"]["name"] . "<br />";echo "Type: " . $_FILES["file"]["type"] . "<br />";echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

if (file_exists("upload/" . $_FILES["file"]["name"])){echo $_FILES["file"]["name"] . " already exists. ";}else{move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $_FILES["file"]["name"]);echo "Stored in: " . "upload/" . $_FILES["file"]["name"];}}}else{echo "Invalid file";}?>


 

0x03 bypass

 

先上传一个asp,看一下返回值

 

文件上传Bypass安全狗

 

这里看到了404xxxdog的页面,那应该是拦截了,我这里先放过去看看,果然是某狗拦截了

 

文件上传Bypass安全狗

 

开始尝试绕waf

 

这里我先把Content-Type改成image/gif通用图片类型

 

文件上传Bypass安全狗

 

0x03.1 增大文件大小

 

测试发现 waf对于Content-Disposition字段的长度验证不是很准确,因为我们可以想到它进行拦截的规则肯定是基于正则,那么我们想办法让安全狗拦截的正则匹配不到即可

 

这里附一个对Content-Disposition字段的解释

 

在常规的 HTTP 应答中,Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

在 multipart/form-data 类型的应答消息体中,Content-Disposition 消息头可以被用在 multipart 消息体的子部分中,用来给出其对应字段的相关信息。各个子部分由在Content-Type 中定义的分隔符分隔。用在消息体自身则无实际意义。


Content-Disposition 消息头最初是在 MIME 标准中定义的,HTTP 表单及 POST 请求只用到了其所有参数的一个子集。只有 form-data 以及可选的 name 和 filename 三个参数可以应用在HTTP场景中。

 

这里对这个字段的长度进行篡改,绕过成功

 

文件上传Bypass安全狗

 

0x03.2 对文件名修改(卒)

 

我们在上传时候通常会把文件名后缀和解析漏洞,那么waf对于filename参数后的值的文件名后缀肯定是要正则去匹配的 这样正常上传肯定不行

 

那么绕过之前我们猜想,第一个它可能是对filename这样的键值对进行匹配,例如"ket = val"这样的键值对 那么这里我们就是filename=“shell.php” 

 

那这里把双引号去除,扰乱匹配,发现不行

 

文件上传Bypass安全狗

 

那么尝试可不可以多一个filename,因为文件在接收上传文件名时取的是最后一个filename,那么我们在最后一个filename参数前加一些干扰的filename参数试试

 

文件上传Bypass安全狗

 

发现还是不行  那么这里就知道他是对所有filename参数进行检测  那么我们能不能把前面的filename参数去掉值呢

 

Content-Disposition: form-data; name="file"; filename= ;  filename="shell.php"

 

文件上传Bypass安全狗

 

结果对文件名进行修改全卒,在之前版本的某狗在filename= ;是可以进行绕过的,4.0版本文件名修改全卒 

 

0x03.3 修改文件名后缀

 

经典的iis6.0解析漏洞尝试,拦截

 

文件上传Bypass安全狗

 

可以在文件名中间加符号扰乱某狗匹配,经测试 ";" " " " ' " 均可

 

文件上传Bypass安全狗

 

文件上传Bypass安全狗

 

文件上传Bypass安全狗

 

0x03.4 对filename动手脚

 

这里可以让waf对filename这个字符串匹配不到,但是服务器又可以接收,加入换行这类的干扰

 

先测试单个字符进行换行,都失败

 

文件上传Bypass安全狗

 

文件上传Bypass安全狗

 

切断filename= 和 之后的值,则可以绕过

 

文件上传Bypass安全狗

 

文件名换行,即hex加入0a,也可以绕过

 

文件上传Bypass安全狗

 

文件上传Bypass安全狗

 

0x03.5 修改匹配字段(卒)

 

我们的filename参数是在post包中的 Content-Disposition 字段,那么waf也是先匹配到这个http头在对内容进行检测,我们可以尝试对这个头的特征进行修改

 

我们尝试去掉这个form-data    (form-data;的意思是内容描述,form-data的意思是来自表单的数据,但是即使不写form-data,apache也接受。)

 

  Content-Disposition: name="file"; filename="shell.php"

 

发现失败,之前3.0版本可以绕,4.0卒

 

文件上传Bypass安全狗

 

对Content-Disposition进行参数污染,拦截

 

文件上传Bypass安全狗

 

对Content-Disposition进行大小写混淆,拦截

 

文件上传Bypass安全狗

 

加上额外的Content-Type进行干扰,拦截

 

文件上传Bypass安全狗

 

加上filename进行参数污染,拦截

 

文件上传Bypass安全狗

 

加一个额外的Content-Length头,拦截

 

文件上传Bypass安全狗

 

0x03.6 多个等号

 

经测试两个=或者三个=都可以达到绕过的效果

 

文件上传Bypass安全狗

 

 

文件上传Bypass安全狗

 

 

0x03.7 %00截断

 

%00截断产生的原因是0x00为十六进制的表示方法,ASCII码里就为0,而有些函数在进行处理的时候会把这个当作结束符

 

这里直接尝试在文件名后面加上%00形成00截断,成功绕过

 

文件上传Bypass安全狗

 

0x04 后记

 

某狗4.0版本对于3.0版本又有了一定的改进,对于之前的文件名修改和修改匹配字段已经不能够绕过waf,但是对于绕waf的思想总结起来可以有如下几点:

 

大小写转换、干扰字符污染、字符编码、拼凑法,


总体来说,这些思想不仅在文件上传bypass中有用,对于sql注入绕waf等一系列地方思想都大体相同,师傅们可自行拓展,文章中若有错或不足的地方欢迎师傅们交流。

文件上传Bypass安全狗


推荐阅读:


本月报名可以参加抽奖送暗夜精灵6Pro笔记本电脑的优惠活动


文件上传Bypass安全狗


点赞,转发,在看


原创投稿作者:Drunkmars

文件上传Bypass安全狗


本文始发于微信公众号(HACK学习呀):文件上传Bypass安全狗

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: