BYPASS WAF
BYPASS WAF概念
BYPASS WAF实际是去寻找位于WAF设备之后处理应用层数据包的硬件或软件的特性。利用特性构造WAF不能命中,但是在应用程序能够成功执行的载荷,绕过防护。
WAF的分类
- 云WAF
在配置云WAF时,DNS需要解析到CDN的IP上,在请求url时,数据包就会先经过云WAF进行检测,如果通过再将数据包送给主机。 - 主机防护软件
在主机上预先安装了这些防护软件,可用于扫描和保护主机,在监听web端口的流量是否有恶意的,所以这种从功能上讲比较全面,但是升级成本可能比较高。 - 硬件IDS/IPS、硬件WAF
使用专门硬件防护设备的方式,当向主机请求时,会先将流量经过此设备进行流量清洗和拦截,如果通过再将数据包发给主机。 - 软WAF
软件WAF则是安装在需要防护的服务器上,实现方式通常是WAF监听端口或以web容器扩展方式进行请求检测和阻断。
BYPASS WAF的各种绕过姿势
Web架构层bypass
-
寻找真实IP
云WAF通过修改DNS解析隐藏了真实IP地址;
查找域名解析记录;
利用邮件发送功能来抓包,获取真实IP。 -
畸形数据包bypass
GET型请求转POST型;
Content-length头长度大于4008;
正常参数放在垃圾数据后边。
WEB Server层bypass
Apache
1.畸形method
某些Apache版本(version 2.*)在做GET请求的时候,无论method为何值均会取出GET的内容,如请求为method为DOTA2,依然返回了aid为2的结果。
如果某些WAF在处理数据的时候严格按照GET,POST等方式来获取数据,就会因为Apache的宽松的请求方式导致bypass。
实例:
环境:DVWA+PHPstudy,burpsuite
目的:测试某些Apache版本与WAF解析request时的不同。
进入靶场后更换等级为LOW,来到Command INjection页面。
打开burpsuite开启浏览器代理截获请求。
这里我们点击右下角View source按钮发送一个GET请求。
我们可以看到burpsuite拦截率request,在这个页面我们将第一行的GET随意改成其他,点击forword通过该请求。
之后我们点击bp的target页面找到我们刚刚发送的ZSYYY请求。
我们可以发现request中的头部信息并不是GET请求,而是我们刚刚输入的ZSYYY。然而repose则给我们返回了正常的页面,并且我们成功跳转出了源码页面,证明我们的畸形method被解析成了GET依旧可以正常得到reponse。
这种方式就是通过Apache与waf解析请求头部的差异达到bypass的目的。
2.php+apache畸形的boundary
php在解析multipart data的时候有自己的特性,对于boundary的识别,只取逗号前边的内容,例如我们设置的boundary为------aaaa,1234,php在解析的时候只识别了------aaaa,后边的内容均没有被识别。然而WAF在做解析的时候,可能获取的是整个字符串,此时就可以BYPASS。
什么是multipart data?
Multipart/from-data的请求方式来完成上传图片等服务器交互操作,这需要我们去严格按照规范的格式去组装请求体,每个换行和空格都是不可忽略的。
实例:
DVWA切换到file upload。
上传1.png,抓包查看数据包。
可以看到存在四个分割符,点击forward,正常上传成功。我们接着上传2.png,将分隔符后边的内容进行修改,查看是否可以上传成功。
将原始的分隔符后边添加,1,在第一个和最后一个后边同样添加,1,点击forward,发现也可以上传成功,也就是说,php在解析分隔符时会自动忽略,之后的内容正常解析请求,某些WAF可能会把这些content-disposition识别为一整串内容,从而达到bypass的效果。
IIS
1.%特性
在asp+IIS的环境中存在一个特性,特殊符号%,在该环境下当我们输入s%elect的时候,waf层可能解析出来的结果是s%elect,但是在iis+asp的环境下解析的结果为select。
实例:
环境:asp+iis
- 在IIS服务器的根目录创建一个名为index.asp的文件。
<form method="get" action="simpleform.asp">
<p>First Name:<input type="text" name="fname"/></p>
<p>Last Name:<input type="text" name="lname"/></p>
<input type="submit" value="Submit"/>
</form>
- 再创建一个名为simpleform.asp的文件。
<boby>
Welcome
<%
response.write(request.querystring("fname"))
response.write("" & request.querystring("lname"))
%>
</boby>
- 打开浏览器输入IP/index.asp。
我们可以看到一个简单的登录框。
分别输入se%lect/pass,随后点击submit,
为什么没有忽略%,因为IIS把%解析为%25带入了,在URL地址栏中删除25只保留%,再次查看。
我们发现省略了%。在url地址栏中的%并没有被iis+asp解析处理。
这就是IIS的%特性,我们可以利用这个特性构造诸如se@lect的语句利用waf与IIS服务器的解析差异打到BYPASS的目的。
2.%u特性
IIS服务器支持对unicode的解析,例如我们对于select中的字符进行unicode编码,可以得到s%u0065%u006cect,在登录框输入查看结果。
我们可以看到用unicode编码将el进行替换,但iis服务器在此处处理时会将%转化为%25,只需在URL地址栏将多余的25删掉,回车后可以看到IIS自动将unicode解析为select,一些WAF会接受原本的%u0065%u006,从而产生差异达到BYPASS的效果。
3.另类%u特性
该漏洞主要利用unicode中的e对应的unicode为%u0065,但是%u00f0同样会被转换为e。
(1)s%u0065lect=>select
(2)s%u00f0lect=>select
WAF层可能会识别(1)的形式不会识别(2)的形式,可以利用做WAF的绕过。
可以看到,无论是(1)还是(2)都被处理为e。
Web应用层bypass
1.双重url编码
双重url编码,即对于浏览器发送的数据进行了两次urlencode操作,比如s做一次的url编码为%73,再对%73做一次编码为%25%37%33.一般情况下数据经过WAF设备的时候只会做一次url编码,这样解码之后的数据一般不会匹配到规则,达到bypass的效果。
%73elect
%25%37%33elect
虽然我们的实验并不存在waf,本质的原理一样,就是通过WAF可能没有进行多重解码的漏洞达到bypass的效果,如果存在waf,输入%25%37%33elect可能会被解析为%73elect,iis服务器接着将%73elect解析为select。
2.变更请求方式
- GET、POST、COOKIE
zaiweb环境下有时候会出现统一参数的获取的情况,主要目的就是对于获取的参数进行统一的过滤。
实例:
打开dvwa靶场,将安全级别调整为low,进去sql injection一栏。
随后我们在该页面尝试进行sql注入,注入语句如下:
?id=-1' union select 1,version()#
使用bp抓包显示如下:
如果存在WAF对GET请求方式进行了过滤,我们可以尝试使用POST方式进行sql注入。
右击选择change request method即可切换提交方式。
- urlencode和from-data POST
在提交数据的时候有两种提交方式,第一种是urlencode,第二种是from-data。当我们在测试站点的时候,如果发现POST提交的数据被过滤了,可以考虑使用from-data的方式去提交。
实例:
前提WAF对get和常规的post请求方式进行了过滤,则我们尝试使用from-data格式进行注入。
在重发器右击选择change boby encoding。
因此,我们可以通过转换GET和POST请求,并且改变POST请求格式来达到bypass的效果。
3.HPP
HPP是指HTTP参数污染。
?id=1&id=2&id=3的形式,这种形式在获取ID值的时候不同的web版本获取的值不一样。
假设提交的参数为:
id=1&id=2&id=3
Asp.net+IIS 获取的值为id=1,2,3
Asp+IIS获取的值为id=1,2,3
Php+Apache获取的值为id=3
可以分析:当waf获取参数的形式与web程序参数不一样时,就可能会出现bypass waf的可能。
关键还是要分析WAF对于参数的获取方式是如何处理的。对于HPP的灵活运用,一些CMS基于url白名单,可以利用hpp,在参数一的位置添加白名单目录,在参数二的位置添加恶意的payload,形如Index.php?a=[whilelist]&a=se;ect 1 union select 2
数据库层bypass
数据库层bypass通常是在bypass waf的sql注入防护规则。我们需要针对数据库使用该数据库的特征即可。如mysql,sqlserver等。
Mysql数据库
1.参数和union之间的WAF规则
-
\Nunion的形式;
-
浮点数的形式;
-
8e0的形式;
-
/!50000/的形式
2.union和select之间的WAF规则
- 空白字符绕过;
- 注释符绕过;
/**/
/letmetest/ - 使用括号绕过。
3.常见过滤函数
- 字符串截取函数
mid(version(),1,1)
substr(version(),1,1)
substring(version(),1,1)
lpad(version(),1,1)
rpad(version(),1,1)
left(version(),1,1)
reverse(right(reverse(version()),1)
- 字符串连接函数
concat(version(),'|',user())
concat_ws('|',1,2,3)1
- 字符转换
ascii(1)
hex('a')
unhex(66)
4. 过滤了逗号的WAF规则
- limit处的逗号;
limit 1 offset 1
- mid处的逗号;
mid(version() from 1 for 10)
- union处的逗号;
通过join拼接
sqlserver数据库
- select from后的位置
(1)空白符号
01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20需要做urlencode,mssql中表示空白字符比较多,靠黑名单去阻断不太合适。
(2)注释符/**/
(3)其他符合:.符号
例如:
select * from. table1;
- select from中间的位置
(1)空白字符
(2)注释符号
例如:
select /**/ * from table1;
- and之后的位置
(1)空白字符
(2)注释符号
(3):号在sqlserver2017版本以前可以
- 使用exec的方式
实例:
构造一个查询语句:
select * from t1 where quantity>152; exec(‘wa’+‘itfor delay’‘0:0:5’‘’)
可以延时5秒,分割字符串达到绕过WAF的效果。
- 使用sp_executesql的方式