mysql的count报错_Mysql报错注入原理分析(count()、rand()、group by)

报错需要count(*),rand()、group by,三者缺一不可

前提:当行数大于等于3行时才会报错。

原链接:https://www.cnblogs.com/xdans/p/5412468.html

几个fool()原理解释:

select

count(*),floor(rand(0)*2) from test group by floor(rand(0)*2)

首先看经典的floor注入语句:

and select 1 from (select

count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables

group by x)a)

第一眼看起来有些懵逼,我们来从最基本的入手,最后在分析这个语句

首先是floor()报错产生的条件:

select count(*)

,floor(rand(0)*2)x from security.users group by x(自定义数据库的一张表)

这里解释一下x是什么意思,可能有些同学不太熟悉sql语句,floor(rand(0)*2)x的x是为floor(rand(0)*2)添加了一个别名,就是x就等于floor(rand(0)*2),这样做的目的是

让group by 和 floor(rand(0)*2)相遇(请原谅我这么解释),

06944e9d3676f7e0a1e6ae6bcb525a1b.png

下一步我们在报错位置处加上我们想要的子查询,用concat()拼接:

select count(*)

,concat(database(),floor(rand(0)*2))x from security.users group by x

76af3eadadce1531338329c3f2c24bef.png

security就是我们想要的数据库名,1是上一步拼接的。

但现在是不是就可以直接使用了呢?还有几个步骤,先看直接拼接到and 后会怎样:

select * from security.users

where id=1 and (select count(*) ,concat(database(),floor(rand(0)*2)x) from

security.users group by x)

c07092964666ae2affc1114cbb1d8bc1.png

报了一个错,百度一番发现引发这个错误的原因很多,这里我是觉得我们构建的select语句的结果是一个结果表,而and 需要一个布尔值,也就是0或非零的值,那我们在嵌套一个查询,前面说了select 的结果是一个结果表,那我们就可再从这个表执行查询,只不过这次select的值是非零数字:

select 1 from (select

count(*) ,concat(database(),floor(rand(0)*2))x from security.users group by x)a

再啰嗦一句,最后这个a和之前解释的x的作用是一样的,是前面括号内容的别名,

sql语句要求在查询结果的基础上再执行查询时,必须给定一个别名。

嵌套进and后执行

select * from security.users

where id=1 and(select 1 from (select count(*)

,concat(database(),floor(rand(0)*2))x from security.users group by x)a)

bed160d800fabd1d4e476f9c103a53ca.png

大功告成

我们完成了刚开始引入的floo()注入语句

一 随机因子具有决定权(rand()和rand(0))

随机因子指的是rand(x)

x是否有。

当插入一条记录时,不报错。

2363ad8fe0615e1e0ffaa83ae85d5743.png

增加一条记录,有时候报错。

fd5271fdc567b1e31b8d9cd21800ab90.png

68f83de4d82c1b87c80dde930104295b.png

再增加一条记录也和2条记录一样进行随机报错。

三条及以上和2条记录一样进行随机报错。

分别对floor(rand()*2)和floor(rand(0)*2)在多记录表中执行多次(记录选择10条以上),在有12条记录表中执行结果如下图:

5eb2e90ef1a77935aea729583a691a4b.png

连续3次查询,毫无规则,接下来看看select floor(rand(0)*2) from T-Safe;,如下图:

e425deccbb33b4e0e3382097006d02a2.png

可以看到floor(rand(0)*2)是有规律的,而且是固定的。

二 count与group by的虚拟表

在使用还有count() 和group by 的查询语句时,mysql在遇到select count(*) from TSafe group by x;这语句的时候到底做了哪些操作呢,我们果断猜测mysql遇到该语句时会建立一个虚拟表(实际上就是会建立虚拟表),那整个工作流程就会如下图所示:

1.先建立虚拟表,如下图(其中key是主键,不可重复):

5a58de7f3ceb9271f2a96e2b2b2f293c.png

2.开始查询数据,取数据库数据,然后查看虚拟表存在不,不存在则插入新记录,存在则count(*)字段直接加1,如下图:

760cf63389d14c15a84d80e17a85b0a6.png

由此看到 如果key存在的话就+1, 不存在的话就新建一个key。

三 floor(rand(0)*2)报错

1.查询的时候如果使用rand()的话,该值会被计算多次,就是在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次,以此类推。

注:使用group by,即虚表存储是按照group by 计算的那一列来从上往下来计算,取一条记录判断虚表是否存在时会使函数执行一遍,当存入的时候(即表中key值无此值)会将原函数存入,但是存的内容是最终结果,即原函数会被再次执行结果存入虚表,当表中有此键值对,那么只需count+1,不用再存key,所以比较时会计算一次,存入时又会计算一次。

2.在使用count(*)时,如

select count(*) from test group by x;  x=floor(rand(0)*2)

mysql执行此句时会创建一个虚表,虚表一共两个字段主键是x,另外一个字段是count(*)

3.首先知道floor(rand(0)*2)的值为011011...,

4.执行的过程(floor(rand(0)*2)报错的原因):(插入之前是表面显示数据,实际比较时和存储时为表面数据计算之后的结果,这取决于数据库的一种存储机制,表面的sql语句会被审查,然后执行存入数据库,再回显数据库中存的内容,即结果)

select count(*) from test group by floor(rand(0)*2) ;

select count(*),floor(rand(0)*2) from test group by floor(rand(0)*2) ;

(这个位置的floor(..))有没有无所谓用不到

1).查询前默认会建立空虚拟表如下图:

34c79cbd79fd0eb81f348212060b31f6.png

2).开始执行,查询第一条记录(即数据),在使用group by时 floor(rand(0)*2)执行一次,结果为0,即x=0(第一次执行),然后发现虚表中没有key=0的键值对记录,则floor(rand(0)*2)会被存入虚表,存入时会被计算为实际的值,即会被再执行一次(第二次执行),结果为1插入虚表,同时count由0变1。

ab896b506231102a032016eafc957672.png

3)取第二条记录,floor(rand(0)*2)执行一次,结果为1(第三次执行),查询虚表,发现虚表中有1,则直接count+1,不用再存key,所以floor(rand(0)*2)不会再被计算。

c2ef4c8c3376459eb719a0405c897a27.png

4).取第三条记录,floor(rand(0)*2)执行一次,结果为0,发现虚表中没有key=0,那么floor(rand(0)*2)会再次执行并存入虚表,此次计算结果为1(第五次执行),与已有的key冲突了,所以插入时报错。

5).整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要3条数据,使用该语句才会报错的原因。

四 floor(rand()*2)报错

由此我们可以同样推理出不加入随机因子的情况,由于没加入随机因子,所以floor(rand()*2)是不可测的,因此在两条数据的时候,只要出现下面情况,即可报错,如下图:

3af32db2ab6912d5219fd71b4b92011d.png

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

c70eb954266711f9f535d32f8e2f3755.png

当前面记录让虚表长成这样子后,由于不管查询多少条记录,floor(rand()2)的值在虚表中都能找到,所以不会被再次计算,只是简单的增加count()字段的数量,所以不会报错,比如floor(rand(1)*2),如图:

ac2edaf8a072847c0b9d54583de994b1.png

在前两条记录查询后,虚拟表已经存在0和1两个键值了,所以后面再怎么弄还是不会报错。

总之报错需要count(*),rand()、group by,三者缺一不可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349416.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.0jpa 2.0_EasyCriteria 2.0 – JPA标准应该很容易

1.0jpa 2.0在今天的帖子中,我们将看到名为EasyCriteria的框架的新版本。 在这篇文章的结尾,我们将在博客中看到这里的内容。 不幸的是,JPA标准存在一个巨大的问题,即冗长。 为什么不变得更容易? 像这样认为EasyCriteri…

python 从入门到实践_Python编程从入门到实践日记Day15

Python编程从入门到实践日记Day15第5章 字典(三)1.使用字典(三)—由类似对象组成的字典在前面的示例中,字典存储的是一个对象(游戏中的一个外星人)的多种信息,但你也可以使用字典来存储众多对象的同一种信息。例如,假设你要调查很多人&#x…

mysql创建文章表_创建表--文章表article

建MySQL数据表需要以下信息:表名表字段名定义每个表字段字段名 数据类型 数据属性数据属性:1. 无符号 unsigned(非负限定 ,即不能取负值) 取值范围 0–255;2. 主键索引 primary key(唯一,一张表推荐一个主键) ;3. 自增 auto_increment &…

什么是JavaServer Faces(JSF)

这是一个分为两部分的系列,其中我介绍了JSF 2及其如何适合Java EE生态系统。 在第1部分中,我将介绍JavaServer Pages(JSF)背后的基本思想 ,在第2部分中,将介绍Facelets声明语言 。 在构建Web应用程序时&a…

python地图散点图_在地图上叠加散点图(img)

好吧,这个问题是老问题,但我有一个不同的答案,可能会有人感兴趣。。。在 我一直在研究同一个问题。GitHub(https://github.com/ageron/handson-ml.git)上提供的代码可以满足您的需要(请参见02“端到端机器学…

mysql创建表时添加范式_MySql三大范式与数据库设计和表创建常用语句

【数据库设计的三大范式】1.第一范式(1NF First Normal Fromate):数据表中的每一列(字段),必须是不可拆分的最小单元。也就是确保每一列的原子性。例如: userInfo: ‘山东省烟台市 13181621008’> userAds:’山东省烟台市’tel:’13181621…

asp listview 单元格文字颜色_如何替换CAD表格中特定区域单元格中的文字?

下面是本公众号文章分类目录,点击标题文字可打开分类文章列表:安装卸载 异常、退出 文件及输入输出 基本操作技巧 各种设置及相关问题 界面和显示相关问题 快捷键 视图设置和调整 图层 颜色 线型 字体、文字样式和文字输入 标注、引线和标注…

jvm 方法内联_方法内联在JVM中有多积极?

jvm 方法内联在IntelliJ IDEA中使用Ctrl Alt M 提取方法 。 Ctrl Alt M。 这就像选择一段代码并按此组合一样简单。 Eclipse也有它 。 我讨厌冗长的方法。 对于我来说,闻起来太久了: public void processOnEndOfDay(Contract c) {if (DateUtils.add…

php ssh 连接mysql_通过PHP中的SSH连接到MySQL服务器?mysql-问答-阿里云开发者社区-阿里云...

SSH隧道解决方案 设置到MySQL数据库服务器的SSH隧道(最好是通过Jumpbox以获得安全性)。(A)GUI工具 根据您的要求,您可以使用具有内置SSH隧道支持的GUI MySQL客户端(例如SequelPro),使用Visual Studio代码 转发端口/创建SSH隧道或使用PuTTY设置端口转发。…

mybatis delete返回值_面试:谈谈你对MyBatis执行过程之SQL执行过程理解

前言在了解了MyBatis初始化加载过程后,我们也应该研究看看SQL执行过程是怎样执行?这样我们对于Mybatis的整个执行流程都熟悉了,在开发遇到问题也可以很快定位到问题。更重要的,在面试中遇到面试官咨询Mybatis的知识点的时候&#…

GC解释:堆

世代垃圾收集器 JVM堆分为两个不同的世代。 一种称为“年轻”,另一种称为“老”(有时称为终身制)。 年轻一代又分为两个主要的逻辑部分:伊甸园和幸存者空间。 垃圾收集人员还使用了虚拟空间供年轻人和老年人使用,以调整…

ubuntu设置mysql可以非本地访问_ubuntu server下设置mysql的远程访问权限

安装mysql安装mysql的方式较多主要有使用源安装,使用本地压缩包进行安装的方式。 具体参照 【ubuntu安装mysql5.5】检查mysql的远程访问权限eniZ944qtakg9Z:~$netstat -tl | grep mysql#tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTE…

python调用mysql数据库sql语句过长有问题吗_python操作mysql数据库,一次性执行多条语句不执行...

总结:1、使用这种方法,获取到的返回值总是最后一条命令的返回值,如果最后一条命令是update或者delete这种sql,则返回为() 2、sql的每一条语句后面都需要添加一个分号,不然最后splice时候 &#…

mysql sql wait 写法_有关SQL语句写法注意的那些事情(原创整理)

前段时候针对开发做的SQL语句写法方面注意点的培训,特意总结了一下,也共享一下。书写SQL需要注意的若干问题(MySQL版)一、基本问题1,在系统中运行的SQL查询,先考虑一下能不能在Slave上检索,目前各个项目中Master上的不…

mysql 时间函数多了8小时_MySQL时间函数了解

NOW() -- 获取当前格式化时间原表mysql> CREATE TABLE blog (-> id INT PRIMARY KEY auto_increment,-> NAME CHAR (32),-> sub_time datetime-> ); Query OK, 0 rows affected (0.01 sec)mysql> INSERT INTO blog (NAME, sub_time)-> VALUES…

JUnit 5 –基础

JUnit 5是适用于Java的下一代单元测试框架,具有许多有趣的功能,包括嵌套测试,参数化测试,新的扩展API或Java 8支持。 本文展示了JUnit 5的基本概念,包括测试生命周期,参数注入和断言(基本&…

mysql explain output_MySQL查询优化之explain的深入解析【转载】

在分析查询性能时,考虑EXPLAIN关键字同样很管用。EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作、以及MySQL成功返回结果集需要执行的行数。explain 可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我…

char强制类型转换为int_C语言学习第5篇---类型转换概念理解

类型之间的转换1.C语言中的数据可以进行转换---强制类型转换---隐式类型转换强制类型转换1.强制类型转换的语法---(Type)var_name;---(Type)value;2.强制类型转换的结果---目标类型能够容纳目标值,结果不变---目标类型…

python 中求最大值问题_Python中用max()方法求最大值的介绍

max() 方法返回其参数最大值:最接近正无穷大的值。语法以下是max()方法的语法: max( x, y, z, .... )参数 x -- 这是一个数值表达式。 y -- 这也是一个数值表达式。 z -- 这是一个数值表达式。返回值此方法返回其参数的最大值。例子下面的例子显示了max(…

在项目中使用fastreport_如何在项目管理中使用里程碑

不管您的项目是什么,完成大工作都意味着朝目标端点迈出几步。正如您无法结束旅程一样,您的团队必须完成第一步,以便从下一个步骤开始并最终完成项目。这可能是设定里程碑的最大原因。毕竟,如果没有完成日期,则项目的一…