floor报错注入原理详解

用了这么旧却不直到原理,想起来有些不舒服,索性就学习了一下,没有直接转贴,怕师傅们哪天删了,自己再拟一份
大概流程是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 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值