最常见的WAF绕过技巧
举个栗子,比如基于黑名单的空格过滤绕过,在Mysql5下,%0A/%0B/%0C/%0D/%A0/%09/%20均可以起到空格的作用,测试WAF的时候如果发现以上存在未过滤,那么就可以成功绕过辣
除此之外,空格还可以用其他方式代替,像科学计数法(1e0),注释符等
对于空格以外的其他字符(a),unicode转义(%u0061),nibble转义(%%361)等都是常见的绕过技巧
/* 比如nibble转义,WAF里可能只进行一次解码,那么解码后%%361变成%61,而非a,那么成功绕过WAF!到服务器上后,再自动进行一次解码(%61 -> a),如果后台安全处理存在漏洞,即达到想要的效果。虽然可能性小的一匹
下面介绍基于HTTP协议的WAF绕过技巧
-
HTTP 0.9协议
HTTP 0.9协议只有GET方法,且没有HEADER信息等,WAF就可能认不出这种的请求包,于是达到绕过WAF的效果 -
HTTP pipeline
因为WAF在保证安全的同时,也要保证性能,所以经常会去检查HTTP协议里的Content-Length。又因为超出Content-Length的部分并不在本次请求(单次)的数据包中,所以WAF放弃检查。于是我们可以将有威胁的信息插入在超出Content-Length部分的数据包中,达到绕过的效果
接下来是黑摸仙的绕过膜法步骤:
0X00:令Connection: keep-alive (这是实现一次传输多个数据包的关键)
0X01:令Content-Length为想要的值 (隐藏后面的威胁信息) , 这里要注意的是如果用的burp抓包,那么默认Update Content-Length,于是我们要取消勾选Update Content-Length这个选项,才能使Content-Length固定
0X02:在第一个完整的HTTP请求下继续构造其他完整的含有威胁信息的HTTP请求 (注意不同请求间要有一个空行,且每个请求的Host一定一定要保持相同)
0X03:这条是补充上一条的技巧说明:可以利用畸形包增大WAF检查的难度
小栗子:原HTTP数据包 => a=1,现在令Content-Length=3,再构造畸形包,如a=1GET XXX HTTP/1.1,(到此都不换行),然后再换行跟上Host和Connection等信息 -
HTTP chunked transfer
头信息Transfer-Encoding: chunked (声明分块传输,HTTP1.1下才有)
当要绕过WAF时,采用分块传输可以把原本的数据包实现分割效果
例如要传输的数据为a=-1’ union select database()||‘1
那么分块传输的数据包可以为 (格式为长度-数据-长度-数据-…)
2
a=
4
-1’
3
uni
10
on select
5
datab
9
ase()||'1
(Tips: 如果在burp的repeater里发包无响应,试着在最后多敲两行回车,不要问我怎么知道的ojz)
分块传输进一步混淆WAF的技巧:(其实它已经可以绕过某狗了2333)
比如为了防止Transfer-Encoding: chunked被识别,
可以选择再添加一个Transfer-Encoding: trashmsg,或是把原来的Transfer-Encoding: chunked改为Transfer-Encoding: trashmsg chunked(注意有空格)
对于这样的操作,服务器还是会正常按照分块传输来解析数据,但有的WAF可能只判断它读到的第一个Transfer-Encoding,发现是识别不了的字符串,则完成绕过 -
HTTP 协议未覆盖
先回顾一哈基础知识:四种常见的Content-Type类型
text/html
application/json
application/x-www-form-urlencoded
multipart/form-data
利用协议未覆盖来绕过,就是尝试互相替换Content-Type来绕过WAF过滤机制
下面介绍一种较为常见的绕过方式- 绕过原理:现在大部分WAF会先去检测Content-Type,但有的WAF未覆盖协议form-data,或是检测到form-data以后只去当作文件上传来检测。同时form-data不仅能支持文件上传,还能支持传键值对,所以在x-www-form-urlencoded下被拦截的数据包,能通过该方法绕过一部分的WAF(这个测试后发现某狗拦截,但是某所的好几个老版本都可以成功绕过)
- 下面是利用form-data传值的HTTP请求部分内容
- 几个小技巧:
0X00:在boundary上动动手脚
对于服务器来说,boundary=----test1和boundary=----test1,hhhhtrash;boundary=----test2是一样的,简而言之,服务器会忽略第一个boundary加逗号后的所有信息
但有的WAF的检查边界可能是boundary=----test2,这样就找不到下面的数据包,从而完成绕过
0X01:协议未覆盖可以和分块传输结合使用(具体方法就不赘述,合起来就猴)
0X02:增加filename字段进一步让WAF认为是文件上传,同样的,以下方法服务器认为filename无效,但能达到混淆WAF效果 - name=“key”; filename =“empty.jpg” (注意细节,这里是"filename “,而不是"filename”,所以服务器不认)
- name=“key”;"; filename=“empty.jpg”,利用双引号闭合字符串"; filename=",服务器不解析。但假如WAF查找filename的方法是看在分号后有无filename,则这种方法达到很好的绕过效果(而且由于filename后没有空格,所以比第一种方法更佳)
-
HTTP charset
利用Content-Type: xxx; charset=xxx编码绕过,payload转义后,由于大部分的WAF默认用UTF8编码检测,所以能用此方法来达到绕过关键词过滤的效果(例如转为charset=ibm037)
绕过的姿势还很多,这篇blog就说到这辣(填坑告辞