双查询报错注入原理探索

上一篇讲了双查询报错查询注入,后又参考了一些博客,今天来探究其原理

实际上该报错是由于rand(),count(),group by 三个语句联合使用造成的,缺一不可。

上一篇的地址:https://www.cnblogs.com/laoxiajiadeyun/p/10278512.html

part 1 场景复现


首先我们新建一个数据库,并创建一个表用作实验:

mysql> CREATE DATABASE sql_test;
mysql> USE sql_test;
mysql> CREATE TABLE test(id int(2),name varchar(10));

接下来先插入一条数据测试:

mysql> INSERT INTO test VALUES("1","aaa");

下面看见已经插入了一条数据:

接下来我们构造一个报错条件,让其报错,显示出当前数据库名:

mysql> SELECT count(*),concat((SELECT database()),"~",floor(rand()*2))as a FROM test GROUP BY a;

查询的结果要么为sql_test0,要么是sql_test1,取决于随机数取整结果,不会触发报错。

接下来再在表中插入一条数据进行测试:

mysql> INSERT INTO test VALUES("2","bbb");

双查询语句与之前一样

运气很好,第一次就报错了,错误内容意思:group by 操作时主键 ‘sql_test~1’ 重复

还有其他正常执行不报错的情况:

可以看到,这里存在两条数据就可以引发报错,得到数据库信息。

part 2 形成原因


接下来我们再分析其报错的形成 原因:

先谈group by 函数:

在表中再插入两条数据,name值都为“bbb”:

mysql> INSERT INTO test VALUES("3","bbb");
mysql> INSERT INTO test VALUES("4","bbb");

成功后表如下:

这时候我们使用group by 语句时,MySQL会将查询结果分类汇总,重复的内容会合并为一项:

mysql> SELECT name FROM test GROUP BY name;

这时候再使用count()函数就可以对不同的条目计数:

mysql> SELECT count(*),name FROM test GROUP BY name;

如图:aaa有一条,bbb有3条

其背后的实现原理如下:

在执行group by name语句时,MySQL会在内部建立一个虚拟表,用来储存列的数据,表中会有一个group_key值作为表的主键,这里的主键就是用来分类的name列中获取,当查询数据时,取数据库数据,然后查看虚拟表中存在不,不存在则插入新记录

当读取到第一行数据时,aaa不存在,将aaa放入主键列中,1放在id列中

然后继续往下走,到了bbb,不存在,也放进去

往下执行,遇到多余的bbb,已经有bbb存在,就汇总在一起,内部情况如下:

如下,最后在查询的时候根据group by内部的实现方式返回分类后的结果:

当我们加上count(*)函数时,操作过程为:查看虚拟表是否存在该主键值,不存在则插入新记录,存在则count(*)字段直接加1

这样就能对上面的分类结果进行统计,然后将统计结果返回:

所以双查询报错的关键就在这里,主要的原因在于rand()函数在group by的过程中被触发了多次

part 3 报错原理


让我们回看一下构造的报错语句:

mysql> SELECT count(*),concat((SELECT database()),"~",floor(rand()*2))as a FROM test GROUP BY a;

执行前虚拟表为空:

当第一次执行时,group by 分组,其取的数据的是以a为别名的这条语句,假设这时的concat((SELECT database()),"~",floor(rand()*2))生成结果为sql_test~0,group就以sql_test~0查询虚拟表,发现表中没有该值的主键,于是将这条语句的结果插入到虚拟表中。

注意!是将这条语句的结果插入到虚拟表中,而不是将 sql_test~0 插入到虚拟表中,如下:

(将concat((SELECT database()),"~",floor(rand()*2)) 以a为别名,方便作图)

由于虚拟表没有内容,所以会将其插入到虚拟表中,这里的插入过程中,由于插入的是a语句的结果,所以在插入时a语句中的rand()函数会再次执行,即插入的值可能为sql_test~0 也可能为 sql_test~1 ,这里假设插入时a执行的结果为sql_test~0

所以上面的情况就是用sql_test~1这个结果查询虚拟表,不存在该数据,于是插入虚拟表,插入时又运算一次,然后插入的值变成了sql_test~0,所以这就是主要的冲突,表中只有一条数据还好,即使查询虚拟表的值和插入虚拟表的值不是同一个,但虚拟表也只生成一条记录,不会出现问题。

然而当表的数据出现两条以上的时候,第group by 在处理完第一条数据后会往下继续处理第二条,于是第二条还会按第一条的处理方式进行:

于是就会报错,报错内容如下:

ERROR 1062 (23000): Duplicate entry 'sql_test~0' for key 'group_key'

如果第二次查询和插入的结果都一致:就会有下面两种情况:

  • 都是sql_test~0:表里已存在,该主键的count(*)值+1

  • 都是sql_test~1:表里没有,插入形成新的主键

part 4 探索小结


所以成因已经明白了:当group by 在查询虚拟表和插入虚拟表时,如果这两次a语句执行的结果不一致就会引发错误,错误提示信息是插入的主键重复,通过自定义提示里报错信息中的主键值来获得敏感信息。

其中还可以通过修改rand()函数的随机因子,指定随机数生成方式来提高报错的效率,具体见深入分析的参考链接,这里不过多赘述。

希望这篇文章能给你带来帮助,如果文中有不正确的地方,还请私信或评论留言,我会仔细查看。

参考链接:


group by:https://blog.csdn.net/hao1066821456/article/details/69556644

双查询注入:https://www.cnblogs.com/BloodZero/p/4660971.html

http://www.lijiejie.com/mysql-injection-error-based-duplicate-entry/

Mysql报错注入原理分析:https://www.cnblogs.com/xdans/p/5412468.html#undefined

sql注入--双查询报错注入原理探索的更多相关文章

  1. sql注入--双查询报错注入

    sql注入--双查询报错注入 背景:在sqli-labs第五关时,即使sql语句构造成功页面也没有回显出我们需要的信息,看到了有使用双查询操作造成报错的方式获得数据库信息,于是研究了一下双查询的报错原 ...

  2. sqli注入--利用information_schema配合双查询报错注入

    目录 sqli-labs 5.6双查询报错注入通关 0x01 获取目标库名 0x02 获取库中表的数量 0x03 获取库中表名 0x04 获取目标表中的列数 0x05 获取目标表的列名 0x06 从列 ...

  3. sql盲注之报错注入(附自动化脚本)

    作者:__LSA__ 0x00 概述 渗透的时候总会首先测试注入,sql注入可以说是web漏洞界的Boss了,稳居owasp第一位,普通的直接回显数据的注入现在几乎绝迹了,绝大多数都是盲注了,此文是盲 ...

  4. SQL注入之Mysql报错注入

    --志向和热爱是伟大行为的双翼. 昨天偷懒了没学什么东西,先自我反省一下 - -. 今天认真的学习了一下Mysql报错注入利用方法及原理,好久之前就像认真的学一下这个了,是在上海市大学生网络安全大赛中 ...

  5. SQL注入之MySQL报错注入整理

    看大佬们的文章看得我虎躯一震,精神抖擞,于是心血来潮,整理一下MySQL报错注入常见的手段和方法,再举几个例子 <代码审计:企业级Web代码安全架构>一书中介绍过报错注入十大方法,依次是: ...

  6. SQL注入之Sqli-labs系列第三十关(基于WAF防护的双引号报错注入)和三十一关

    开始挑战第三十关和三十一关(Protection with WAF) 0x1 前言 这关其实和29关是同样的,login.php页面存在防护,只要检测到存在问题就跳转到hacked.php页面,不同的 ...

  7. 深入浅出带你玩转sqlilabs(四)-updatexml(),floor(),extractvalue()报错注入

    SQL各种参数类型下的注入测试 数字型-sqlilabs less2 前面文章已演示过 字符型-sqlilabs less1 前面文章已演示过 搜索型-自写测试 如: www.test.com/ind ...

  8. sql报错注入:extractvalue、updatexml报错原理

    报错注入:extractvalue.updatexml报错原理 MySQL 5.1.5版本中添加了对XML文档进行查询和修改的两个函数:extractvalue.updatexml 名称 描述 Ext ...

  9. sql注入之查询方式及报错注入

    当进行sql注入时,有很多注入会出无回显的情况,其中不回显的原因可能是sql语句查询方式的问题导致的,这个时候我们需要用到相关的报错或盲注进行后续操作,同时作为手工注入时,提前了解或预知器sqkl语句 ...

随机推荐

  1. Python学习案例之人脸检测识别

    前言 随着科技的发展,人脸识别技术在许多领域得到的非常广泛的应用,手机支付.银行身份验证.手机人脸解锁等等. 识别 废话少说,这里我们使用 opencv 中自带了 haar人脸特征分类器,利用训练好的 ...

  2. ASP.NET Core 2.2 十九. Action参数的映射与模型绑定

    前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string.int等类型,也包含Json等复杂类型,本文详细分享一下这一过程.(ASP.NET ...

  3. 随心测试_软测基础_008<测试对象整体认识>

    关于:软件测试的整体认识,首先:认识:测试 对象     与  测试主体(人) 之间的关系 核心理解如下: 不同的测试对象,选取 不同的测试方法 软件项目的周期中:提出 需求 ——>软件实现—— ...

  4. mycat入门--数据库分片

    配置mycat的用户名和密码: 连接mycat,就像连接mysql一样:

  5. qsort.c源码

    /* 版权所有(C) 1991-2019 自由软件资金会. 该文件属于是GUN C语言函数库,由Douglas C. Schmidt(schmidt@ics.uci.edu)所写. GUN C语言函数 ...

  6. android AVD 启动时报错

    AVD启动报错 1.提示:ANDROID_SDK_ROOT is undefined / ERROR: This AVD’s configuration is missing a kernel fil ...

  7. python之路8-内置模块介绍

    time & datetime模块 1 #_*_coding:utf-8_*_ 2 __author__ = 'Alex Li' 3 4 import time 5 6 7 # print(t ...

  8. 解决CentOS6.5下MySQL5.6无法远程连接的问题

    在CentOS6.5上安装了Mysql5.6,,本地服务启动成功,但是远程使用Navicat无法远程连接到MySQL数据库,为了解决这个问题,方法如下: (1)先将MySQL服务停掉# service ...

  9. 【dp】友好城市

    题目一: [题目描述] Palmia国有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市.北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同. 每对友好城市都 ...

  10. P4178 Tree(点分治)

    题面要求小于等于K的路径数目,我么很自然的想到点分治(不会的就戳我) 这道题的统计答案与模板题不一样的地方是由等于K到小于等于K 那么我们可以把每一个子节点到当前根(重心)的距离排序,然后用类似双指针 ...