sql报错注入 之 floor 函数报错:主键重复

2024-02-20 02:36

本文主要是介绍sql报错注入 之 floor 函数报错:主键重复,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Mysql报错注入之floor报错详解

updatexml extractvalue

floor 是mysql的函数

groupby+rand+floor+count

一、简述

利用 select count(*),(floor(rand(0)*2))x from table group by x,导致数据库报错,通过 concat 函数,连接注入语句与 floor(rand(0)*2)函数,实现将注入结果与报错信息回显的注入方式。

基本的查询 select 不必多说,剩下的几个关键字有 count 、group by 、floor、rand。

二、关键函数说明

1.rand函数

rand() 可以产生一个在0和1之间的随机数。

img

可见,直接使用rand函数每次产生的数都不同,但是当提供了一个固定的随机数的种子0之后:

img

每次产生的值都是一样的。也可以称之为伪随机(产生的数据都是可预知的)。
查看多个数据看一下。(users是一个有6行数据的表)

img

这样第一次产生的随机数和第二次完全一样,也就是可以预测的。
利用的时候rand(0)*2为什么要乘以 2 呢?这就要配合 floor 函数来说了。

2.floor(rand(0)*2)函数

floor() 函数的作用就是返回小于等于括号内该值的最大整数。

而rand() 是返回 0 到 1 之间的随机数,那么floor(rand(0))产生的数就只是0,这样就不能实现报错的:

img

而rand产生的数乘 2 后自然是返回 0 到 2 之间的随机数,再配合 floor() 就可以产生确定的两个数了。也就是 0 和 1:

img

并且根据固定的随机数种子0,他每次产生的随机数列都是相同的0 1 1 0 1 1。

3.group by 函数

group by 主要用来对数据进行分组(相同的分为一组)。

还是按照下表进行实验

img

首先我们在查询的时候是可以使用as用其他的名字代替显示的:

img

但是在实际中可以缺省as直接查询,显示的结果是一样的:

img

然后就可以用group by函数进行分组,并按照x进行排序

注意:最后x这列中显示的每一类只有一次,前面的a的是第一次出现的id值

img

4.count(*)函数

count(*)统计结果的记录数。

这里与group by结合使用看一下:

img

这里就是对重复性的数据进行了整合,然后计数,后面的x就是每一类的数量。

5.综合使用产生报错:

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

0 1 1 0 1 1

0 2

1 4

img

根据前面函数,这句话就是统计后面产生随机数的种类并计算每种数量。

分别产生0 1 1 0 1 1 ,这样0是2个,1是4个,但是最后却产生了报错。

0 2

1 4

三、报错分析

这个整合然后计数的过程中,中间发生了什么我们是必须要明白的。
首先mysql遇到该语句时会建立一个虚拟表。该虚拟表有两个字段,一个是分组的 key ,一个是计数值 count()。也就对应于实验中的 user_name 和 count()。
然后在查询数据的时候,首先查看该虚拟表中是否存在该分组,如果存在那么计数值加1,不存在则新建该分组。

然后mysql官方有给过提示,就是查询的时候如果使用rand()的话,该值会被计算多次,那这个"被计算多次"到底是什么意思,就是在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次,我们来看下floor(rand(0)*2)报错的过程就知道了,从上面的函数使用中可以看到在一次多记录的查询过程中floor(rand(0)*2)的值是定性的,为011011 (这个顺序很重要),报错实际上就是floor(rand(0)*2)被计算多次导致的,我们还原一下具体的查询过程:

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

img

(2)取第一条记录,执行floor(rand(0)*2),发现结果为0(第一次计算), 0 1 1 0 1 1

img

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

0 1 1 0 1 1 0

0 1 1

img

(4)查询第二条记录,再次计算floor(rand(0)*2),发现结果为1(第三次计算)

img

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

img

(6)查询第三条记录,再次计算floor(rand(0)*2),发现结果为0(第4次计算)

0 1 1 0

img

(7)查询虚表,发现键值没有0,则数据库尝试插入一条新的数据,在插入数据时floor(rand(0)*2)被再次计算,1作为虚表的主键,其值为1(第5次计算),插入

img

然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以插入的时候就直接报错了。

0 1 1 0 1

四、总结

select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by xsecurity1
security1
security1

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

另外,要注意加入随机数种子的问题,如果没加入随机数种子或者加入其他的数,那么floor(rand()*2)产生的序列是不可测的,这样可能会出现正常插入的情况。最重要的是前面几条记录查询后不能让虚表存在0,1键值,如果存在了,那无论多少条记录,也都没办法报错,因为floor(rand()*2)不会再被计算做为虚表的键值,这也就是为什么不加随机因子有时候会报错,有时候不会报错的原因。

比如下面用1作为随机数种子,就不会产生报错:

img

img

这篇关于sql报错注入 之 floor 函数报错:主键重复的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/726771

相关文章

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Mysql实现范围分区表(新增、删除、重组、查看)

《Mysql实现范围分区表(新增、删除、重组、查看)》MySQL分区表的四种类型(范围、哈希、列表、键值),主要介绍了范围分区的创建、查询、添加、删除及重组织操作,具有一定的参考价值,感兴趣的可以了解... 目录一、mysql分区表分类二、范围分区(Range Partitioning1、新建分区表:2、分

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客