首发于独立博客《若水斋》。
0x00 什么是Double Injection
这个定义是我自己下的,读起来很拗口。如果不能理解这个定义请先暂时跳过:
Double Injection(双查询注入)是一种利用Mysql在按含rand函数的列分组(group by)并计数(count)的情况下创建临时表后,查询临时表中分组键(group_by)是否存在和向临时表插入新行时均计算rand函数返回值的特性,通过巧妙地构造SQL语句,将有用信息显示在SQL报错信息中的SQL注入技术。
在SQL注入中有时会遇到这样的情况:若SQL语句正确,则页面正常返回,但返回的页面中不包含任何有用的信息,而当SQL语句错误时,页面会显示SQL错误信息。在这种情况下,Double Injection是十分有用的。
0x01 Double Injection的原理
0. concat函数
在Mysql中,concat函数用于拼接字符串,如:
mysql> select concat('1', '<-');
+-------------------+
| concat('1', '<-') |
+-------------------+
| 1<- |
+-------------------+
1 row in set (0.00 sec)
也可以拼接查询结果,如:
mysql> select concat('->', (select database()), '<-');
+-----------------------------------------+
| concat('->', (select database()), '<-') |
+-----------------------------------------+
| ->information_schema<- |
+-----------------------------------------+
1 row in set (0.00 sec)
1. rand函数
在Mysql中,rand函数用于返回一个0到1之间的随机数,包含0不包含1,用高数的表示方法便是:[0, 1)。如:
mysql> select rand();
+-------------------+
| rand() |
+-------------------+
| 0.847016541144826 |
+-------------------+
1 row in set (0.00 sec)
mysql> select rand();
+------------------+
| rand() |
+------------------+
| 0.08670779791354 |
+------------------+
1 row in set (0.00 sec)
rand函数接受一个整数参数作为随机数的种子。当种子固定时,产生的随机数(随机数列)也是固定的。如:
mysql> select rand(0);
+-------------------+
| rand(0) |
+-------------------+
| 0.155220427694936 |
+-------------------+
1 row in set (0.00 sec)
mysql> select rand(0);
+-------------------+
| rand(0) |
+-------------------+
| 0.155220427694936 |
+-------------------+
1 row in set (0.00 sec)
上面的例子是产生的随机数固定,下面的例子是产生的随机数数列固定:
mysql> select rand(0) from information_schema.columns limit 3;
+-------------------+
| rand(0) |
+-------------------+
| 0.155220427694936 |
| 0.620881741513388 |
| 0.638747455215778 |
+-------------------+
3 rows in set (0.01 sec)
mysql> select rand(0) from information_schema.columns limit 3;
+-------------------+
| rand(0) |
+-------------------+
| 0.155220427694936 |
| 0.620881741513388 |
| 0.638747455215778 |
+-------------------+
3 rows in set (0.01 sec)
information_schema是系统模式,所有Mysql数据库中都会有这个模式,columns是其中的一个表,记录了所有数据表的列信息。这里只是随便举一个随机数列的例子,如果你不明白information_schema.columns也不要紧,只要知道是从某个有很多行的表中查询数据就可以了。
2. floor函数
Mysql中floor函数是取下整函数,接受一个float型参数,返回小于等于输入参数的最大整数。如:
mysql> select floor(1.4);
+------------+
| floor(1.4) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(1.0);
+------------+
| floor(1.0) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql> select floor(0.4);
+------------+
| floor(0.4) |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
3. 产生随机整数
在Double Injection中我们会综合利