Sql注入中 Group by rand() floor() Count(*)报错原理
一般组合为Group by floor(rand()*2)
rand() 是个伪随机函数,产生的随机数有一定的规律可循。例如:
select floor(rand(0)*2) from information_schema.columns;
这段语句产生的结果恒定不变始终是下面的序列:
结合count() 和group by 就可以爆出数据库名。
select count(*), concat(database(),floor(rand(0)*2)) as col from information_schema.columns Group by col;
其原理是Count()
和group by()
联合使用的时候会产生一个虚表
Key | Value |
---|---|
0 | 4 |
1 | 6 |
并且查询的时候如果使用rand()
的话,该值会被计算多次,那这个“被计算多次”到底是什么意思?就是在使用group by
的时候,floor(rand(0)*2)
会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次。
floor(rand(0)*2)产生的序列如下
0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
---|
处理上述序列流程如下
1、查询key时执行floor(rand(0)*2
= 0
不存在又执行一次得到 1
插入到虚表变为:
Key | Value |
---|---|
1 | 1 |
2、查询key时执行floor(rand(0)*2
= 1
, 存在则将 1
插入到虚表变为:
Key | Value |
---|---|
1 | 1+1 |
3、查询key时执行floor(rand(0)*2
= 0
, 不存在再执行一次将 1
插入到虚表。但是虚表中已经存在1
这个索引所以报错。