SQL注入:floor报错注入的形成原理分析

文章深入剖析了SQL注入中的floor报错注入机制,涉及到rand()、floor()、concat()、count(*)和groupby等函数。通过实例分析,解释了如何利用这些函数构造报错注入,导致数据库返回错误信息,从而获取数据。文章还提供了一个小挑战,帮助读者检验对原理的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL注入:floor报错注入的形成原理分析

我们知道在前端不回显查询结果时,可以尝试使用报错注入来将目标数据作为错误提示的一部分显示出来。

常见的报错注入有:利用updatexml()extractvalue()"floor报错",其中"floor报错"报错的原因相对比较复杂,本文将用图文和实机操作过程来分析它的原理。

一、涉及的函数(或语法)

“ floor报错注入 ”的原理相对复杂的一个原因是在构造这种注入时使用到的sql函数(或sql语法)很多,如rand()floor()concat()count(*)order by

(如果您对它们都比较了解的话,可以直接点此阅读本文的第二部分

1.rand()

rand()函数用于随机生成一个介于0~1之间的随机浮点数

请添加图片描述在这里插入图片描述

​ 可以看到,同样的语句,每一次执行会返回不同的值。(这里添加后面from users是为了能够多展示几个由rand()生成的连续随机数)

  • 可以向rand()中传入一个参数,来得到一个固定的随机数序列

在这里插入图片描述

但当向rand()中传入参数0,无论执行多少次,都会返回相同的结果,如上图。

2.floor()

floor意为“地板”,和它的字面意思一样,它可以实现对输入参数的向下取整(去除小数部分)
在这里插入图片描述

  • 如果我们将rand()floor()结合

    那么将永远得到0
    在这里插入图片描述

    ​ 如果我们将rand()乘以2,那么将永远得到0或1

    rand()得到一个零点几的数,(rand() * 2)得到一个零点几或一点几的数,经由floor()后自然得到一个0或1)
    在这里插入图片描述

3.concat()

一个用于拼接参数的函数

在这里插入图片描述

​ 这里使用concat()来将users表中的first_namelast_name使用-拼接了起来。

4.count()

一种聚合函数,用于统计“表”中个项出现的次数,count(*)会统计NULL

5.group by

根据by后面的“某种规则”来对数据进行筛选分组

  • group by常常配合聚合函数来使用,比如count()
    在这里插入图片描述

​ 这里的SQL语句从users表中查询出first_name列对应所有值,然后group by 后面的first_name为"分组依据",并使用count(*)来对该组中的各个项来计数,最终展现为如上图的查询结果。


二、报错原理

1.原理分析

使用group bycount(*)来得到表的过程,不是" 一蹴而就 "的

​ 而是先创建一个虚拟表,将查询到的各项一个个地作统计
在这里插入图片描述

​ 如下图,每接收到一个项,数据库都会判定虚拟表中是否有何该项值相等的组键(group_key),若没有则会重新"调用"一次该项并以调用结果创建一个新的组键,若已有则给该组键对应行的count(*)列加一。

在这里插入图片描述

到目前为止,好像还是没什么问题啊?

是的,如果写入虚拟表中的键名是“死的,不变化的普通字符串”,那么没有任何问题,如上述的users表中的first_name

​ 但如果这个项是“活的、变化的”呢?

​ 前面提到给rand()中输入参数会返回一个固定的连续随机数序列,那么floor(rand(0) * 2)将固定返回" 0、1、1、0,1…"
在这里插入图片描述

​ 那么concat(floor(rand(0)*2),0x7c,(select version()))就将返回"0|5.7.26"“1|5.7.26”“1|5.7.26”“1|5.7.26”“1|5.7.26”… (0x7c代表了 | 字符)

在这里插入图片描述

如果在补全虚拟表的时候,每一次调用我们的构造项(concat(floor(rand(0)*2),0x7c,(select version()))),它都会“向下“变化。

我们假设虚拟表中有且只有"1|5.7.26",这时刚好读取到的项是"0|5.7.26",因为虚拟表中没有组键"0|5.7.26",那么会重新调用该项并以调用结果创建新组键(但因为被重新调用,该项“向下”变化,变为了"1|5.7.26",所以虚拟表是为为"1|5.7.26"创建了新组键,而此时就会报错——试图创建重复(已存在)的组键"1|5.7.26")。

2.实例验证与分析

我们可以构造"payload"来验证我们所想:

select count(*), concat(floor(rand(0)*2),0x7c,(select version()))as alia from users group by alia;
(这里的as alia是为我们构造的长长的表达式concat(floor(rand(0)*2),0x7c,(select version()))起了别名alia

在这里插入图片描述

可以看到数据库的版本信息被连带进了报错信息。
具体的报错流程如下:

在这里插入图片描述

3.一个小挑战

以下有一个选项也可以达到floor(rand(0) * 2)一样的效果

您可以通过将它们的返回前几位固定数像上面一样带入“虚拟表”来判断是哪一个?

以此检测一下自己是否真的理解了floor报错注入相关的原理。

floor(rand(1) * 2)floor(rand(2) * 2)floor(rand(3) * 2)floor(rand(4) * 2)floor(rand(5) * 2)
01100
10011
01010
01100
00110
# 答案是...
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# .
# floor(rand(4) * 2),可以验证得知其余的构造均不可行(都会正常地创建拼接了0和1的对应组键)
### 关于 SQLi Labs 中 Floor 函数错误注入的学习与解决 SQL 注入是一种常见的安全漏洞,其中攻击者通过输入恶意的 SQL 查询来操纵数据库的行为。Floor 错误注入属于一种基于错误的 SQL 注入技术,在这种情况下,MySQL 数据库会返回详细的错误消息,这些消息可能泄露有关查询结构的信息。 #### 地址与环境准备 为了测试 Floor 错误注入,可以按照以下方式设置实验环境: 1. **下载并安装 sqli-labs** 可以访问 GitHub 上的项目页面[^2],克隆或下载 `sqli-labs` 到本地,并将其放置在 Web 服务器的根目录下(例如 PHPStudy 的默认路径)。完成后启动服务。 2. **创建数据库和用户权限** 使用 MySQL 创建名为 `security` 的数据库以及相应的表数据[^1]。具体操作如下: ```sql CREATE DATABASE security; USE security; SOURCE /var/www/html/sqli-labs/Less-1/to-Less-55/DB/Dumb.sql; GRANT ALL PRIVILEGES ON security.* TO 'sqli'@'localhost' IDENTIFIED BY 'sqli'; FLUSH PRIVILEGES; ``` 3. **验证 Floor 错误注入场景** 在某些练习中可能会遇到 Floor 函数引发的语法错误提示,类似于以下内容[^3]: ``` You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1' LIMIT 0,1' ``` #### Floor 错误注入原理分析 当利用 Floor 函数进行错误注入时,通常依赖于 MySQL 对非法参数处理的方式。如果传递给 Floor 的值不是合法数值,则可能导致内部计算失败从而触发异常。此时可以通过精心构造 payload 来提取目标系统的敏感信息。 以下是实现 Floor 错误注入的一个典型例子: ```sql SELECT FLOOR(POWER(EXTRACTVALUE(NULL,(SELECT VERSION())),RAND()*9e8)); ``` 此语句尝试调用 EXTRACTVALUE() 方法读取版本号字符串作为 XML 节点解析器的内容,但由于传入 NULL 参数而故意制造了一个致命错误。与此同时,FLOOR 和 POWER 组合用于放大随机数范围以便更容易捕获特定模式下的回显片段。 需要注意的是,实际应用过程中应当调整 Payload 形式适配不同上下文中变量名长度限制等因素的影响。 #### 学习资源推荐 对于希望深入理解 Floor 错误注入机制及其防御措施的人士来说,可以从以下几个方面入手获取更多知识: - 官方文档:查阅官方手册了解每种内置函数的具体行为特征。 - 社区讨论:参与 OWASP 或其他信息安全论坛上的主题交流分享经验技巧。 - 教程视频:观看 YouTube 平台上由专家录制的相关教学录像获得直观演示效果。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neonline

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值