用了这么旧却不直到原理,想起来有些不舒服,索性就学习了一下,没有直接转贴,怕师傅们哪天删了,自己再拟一份
大概流程是group by与count冲突导致报错,输出错误包含concat里面的数据
正文
floor()报错注入在MySQL版本8.0 已失效,但是能爆出来AppData这个路径(亲测),7.3.4nts也已失效(听说的,因为phpstudy没有这个版本,我也没听过这个版本)/(ㄒoㄒ)/~~,这确定不是phpstudy里面的php吗
相关函数,
rand(x) 创建一个0-1之间的随机数,参数称为随机数种子,会使随机数固定,这里为空即可。
floor(x) 向下取整,即floor(1,99),输出为1,
count() 汇总统计数量 //结合group by使用,获取重复的数量
group by x 指定对x这一列去重,也可以理解为只获取第一个不重复的
concat(1,2,3)将里面的参数整合为一体 输出为123
concat_wa(1~2) 他的输出结果为:1~2
as: 别名
下面_的图,演示一下这几个函数的作用
rand():记得看里面的注释
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.7948578817721995 |
+--------------------+
1 row in set (0.00 sec)
=======================================
mysql> select rand()*2;
+-------------------+
| rand()*2 |
+-------------------+
| 1.860260257367287 |
+-------------------+
1 row in set (0.00 sec)
======================================
mysql> select rand() from security.users; // 根据表中的行数随机显示结果
+---------------------+
| rand() |
+---------------------+
| 0.2660770288352641 |
| 0.5399947888590347 |
| 0.9017428885230263 |
| 0.8887301067716722 |
| 0.7384218990229274 |
| 0.02591920553326533 |
| 0.9143303613311894 |
| 0.49389422078979595 |
| 0.7264800506890565 |
| 0.15071762180953996 |
| 0.5741479877141751 |
| 0.4185871038759007 |
| 0.3704915869706232 |
+---------------------+
13 rows in set (0.00 sec)
floor():记得看注释
mysql> select floor(1.2);
+------------+
| floor(1.2) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
========================================================================================
mysql> select floor(rand()*2);// *2的原因是,使用floor函数之后,
可能出现的结果有两个值0或1
+-----------------+
| floor(rand()*2) |
+-----------------+
| 1 |
+-----------------+
1 row in set (0.00 sec)
========================================================================================
mysql> select floor(rand()*2) from security.users; // 每次结果不同
+-----------------+
| floor(rand()*2) |
+-----------------+
| 1 |
| 0 |
| 0 |
| 0 |
| 0 |
| 1 |
| 0 |
| 1 |
| 1 |
| 1 |
| 0 |
| 1 |
| 0 |
+-----------------+
13 rows in set (0.00 sec)
concat_ws():
mysql> select concat_ws('~',1,2);
+--------------------+
| concat_ws('~',1,2) |
+--------------------+
| 1~2 |
+--------------------+
1 row in set (0.00 sec)
mysql> select concat_ws('~',version(),floor(rand()*2));
+------------------------------------------+
| concat_ws('~',version(),floor(rand()*2)) |
+------------------------------------------+
| 5.5.53~0 |
+------------------------------------------+
1 row in set (0.00 sec)
as 加个别名,group by 去重,count(统计数列重复的数量)
select concat_ws('?',database(),floor(rand()*2))as x,count(*) from users group by x;
// 使用 group by 对别名为x的字段进行分组
+------------+----------+
| x | count(*) |
+------------+----------+
| security?1 | 3 |
| security?0 | 2 |
+------------+----------+
2 rows in set (0.00 sec)
至于为什么报错,因为group by 和count起了冲突,一个是去重,一个是记录数列重复数
总结:虚拟表中不存在key则重新计算后存入,存在key,count列对应值+1
报错原因:第一次匹配虚拟表时没有存在,重新计算后值发生变化,插入时导致key重复
看完下面再看总结吧,表名暂定为:dbname,下面语句:
select concat_ws('_',database(),floor(rand()*2)as key,count(*) from table_name group by key;
总结里的key可以理解为group by ___这里的列名,也就是那个别名,换别的也可以
第一步,首先计算floor(rand()*2),这里设为0
第二步,去虚拟表格里找table_name找dbname_0//因为concat_ws将dbname与0合体了
第三步,在上一步中,虚拟表格刚建立,为空,所以不会有dbname_0
第四步,这时,他就会将这个值写入虚拟表格中,但是注意,这里floor(rand()*2)要重新计算
第五步,重新计算后暂定为1,最终写入dbname_1
+------------+----------+
| key | count(*) |
+------------+----------+
| dbname_1 | 1 |
+------------+----------+
差不多就这个样子把,继续
第六步,继续计算floor(rand()*2)这里设他的值为0,即dbname_0,
去虚拟表里找发现没有,回来重新计算floor(rand()*2)后写入,
但是重新计算后floor(rand()*2)的值变成了1,即dbname_1
发现第五步插入的数据冲突,因为已经去重了,不能写入重复的 这时就会报错
所以,表里数据最少要求有两条数据(亲测,~ o(* ̄▽ ̄*)o)
有概率不成功?,是的,他是一团程序,你多试几次,总会有的
不知道哪写错了没,挺不喜欢写这个的,,哪里错了麻烦评论一下吧,还没有被评论过呢,
下面是去sqli_labs做的实验
数据库中只有两条数据
下面都是同一条sql语句
Bye