sql注入报错之注入原理实例解析


Posted in MySQL onJune 10, 2022

前言

我相信很多小伙伴在玩sql注入报错注入时都会有一个疑问,为什么这么写就会报错?曾经我去查询的时候,也没有找到满意的答案,时隔几个月终于找到搞清楚原理,特此记录,也希望后来的小伙伴能够少走弯路

0x01

我们先来看一看现象,我这里有一个users表,里面有五条数据:

sql注入报错之注入原理实例解析

然后用我们的报错语句查询一下:

select count(*),(concat(floor(rand()*2),(select version())))x from users group by x

sql注入报错之注入原理实例解析

成功爆出了数据库的版本号。

要理解这个错误产生的原因,我们首先要知道group by语句都做了什么。我们用一个studetn表来看一下:

sql注入报错之注入原理实例解析

现在我们通过年龄对这个表中的数据进行下分组:

sql注入报错之注入原理实例解析

形成了一个新的表是吧?你其实应该能够想到group by 语句的执行流程了吧?最开始我们看到的这张sage-count()表应该时空的,但是在group by语句执行过程中,一行一行的去扫描原始表的sage字段,如果sage在sage-count()不存在,那么就将他插入,并置count()置1,如果sage在sage-count()表中已经存在,那么就在原来的count(*)基础上加1,就这样直到扫描完整个表,就得到我们看到的这个表了。

注:这里有特别重要的一点,group by后面的字段时虚拟表的主键,也就是说它是不能重复的,这是后面报错成功的关键点,其实前面的报错语句我们已经可以窥见点端倪了

sql注入报错之注入原理实例解析

0x02

正如我前面所说的,报错的主要原因时虚拟表的主键重复了,那么我们就来看一下它到底是在哪里,什么时候重复的。这里rand()函数就登场了。
首先我们先来了解rand()函数的用法:

1.用来生成一个0~1的数

2.还可以给rand函数传一个参数作为rand()的种子,然后rand函数会依据这个种子进行随机生成。

那他们的区别是什么呢?我们来看一下,这两个语句的执行效果:

sql注入报错之注入原理实例解析

可以看到rand()生成的数据毫无规律,而rand(0)生成的数据则有规律可循,是:
0110 0110

注:如果你觉得数据不够,证明不了rand()的随机性,你可以自己多插入几条数据再查询试一下。

0x03

现在我们弄清楚了group by语句的工作流程,以及rand()与rand(0)的区别,那么接下来就是重点了,mysql官方说,在执行group by语句的时候,group by语句后面的字段会被运算两次。

**第一次:**我们之前不是说了会把group by后面的字段值拿到虚拟表中去对比吗,在对比之前肯定要知道group by后面字段的值,所以第一次的运算就发生在这里。

**第二次:**现在假设我们下一次扫描的字段的值没有在虚拟表中出现,也就是group by后面的字段的值在虚拟表中还不存在,那么我们就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致错误!

所以我们现在通过一个例子来验证我们的理论,拿出我们最开始的例子:

select count(*),(concat(floor(rand(0)*2),'@',(select version())))x from users group by x

声明:users表就是本文第一个表,表中有五条数据

注意我这里用的是rand(0),不是rand(),rand(0)生成的有规律的序列:

sql注入报错之注入原理实例解析

我们跟着刚刚的思路走,最开始的虚拟表是空的,就像下面一样:

count(*) x
   

当我扫描原始表的第一项时,第一次计算,floor(rand(0)*2)是0,然后和数据库的版本号(假设就是5.7.19)拼接,到虚拟表里去寻找x有没有x的值是x@5.7.19的数据项,结果显然是没有,那么接下来就将它插入到上表中,但是还记得吗,在插入之前会进行第二次计算,这时x的值就变成了1@5.7.19,所以虚拟表变成了下面这样:

count(*) x
1 1@5.7.19

现在扫描原始表的第二项,第一次计算x==’1@5.7.19‘,已经存在,不需要进行第二次计算,直接插入,得到下表:

count(*) x
2 1@5.7.19

扫描原始表的第三项,第一次计算x==‘0@5.7.19’,虚拟表中找不到,那么进行第二次计算,这时x==‘1@5.7.19’,然后插入,但是插入的时候问题就发生了,虚拟表中已经存在以1@5.7.19为主键的数据项了,插入失败,然后就报错了!

上面是使用rand(0)的情况,rand(0)是比较稳定的,所以每次执行都可以报错,但是如果使用rand()的话,因为它生成的序列是随机的嘛,所以并不是每次执行都会报错,下面是我的测试结果:

sql注入报错之注入原理实例解析

执行了五次,报错两次,所以是看运气。

总结

总之,报错注入,rand(0),floor(),group by缺一不可

到此这篇关于sql注入报错之注入原理实例解析的文章就介绍到这了!


Tags in this post...

MySQL 相关文章推荐
MySQL Router的安装部署
Apr 24 MySQL
MySQL安装后默认自带数据库的作用详解
Apr 27 MySQL
解决MySQL存储时间出现不一致的问题
Apr 28 MySQL
MySQL完整性约束的定义与实例教程
May 30 MySQL
为什么MySQL选择Repeatable Read作为默认隔离级别
Jul 26 MySQL
MySQL创建定时任务
Jan 22 MySQL
MySQL 开窗函数
Feb 15 MySQL
MySQL派生表联表查询实战过程
Mar 20 MySQL
如何创建一个创建MySQL数据库中的datetime类型
Mar 21 MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
Jun 14 MySQL
MySQL外键约束(Foreign Key)案例详解
Jun 28 MySQL
MySql按时,天,周,月进行数据统计
Aug 14 MySQL
MySQL如何修改字段类型和字段长度
Jun 10 #MySQL
mysql数据库实现设置字段长度
Jun 10 #MySQL
MySQL优化之慢日志查询
Jun 10 #MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 #MySQL
Mysql中@和@@符号的详细使用指南
Jun 05 #MySQL
MySQL中JOIN连接的基本用法实例
Jun 05 #MySQL
MySQL中order by的执行过程
You might like
高亮度显示php源代码
2006/10/09 PHP
写php分页时出现的Fatal error的解决方法
2011/04/18 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
2013/04/15 PHP
基于PHP生成静态页的实现方法
2013/05/10 PHP
PHP基于GD2函数库实现验证码功能示例
2019/01/27 PHP
游戏人文件夹程序 ver 3.0
2006/07/14 Javascript
Javascript绝句欣赏 一些经典的js代码
2012/02/22 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
JS(JQuery)操作Array的相关方法介绍
2014/02/11 Javascript
JS实现点击按钮后框架内载入不同网页的方法
2015/05/05 Javascript
jQuery左侧大图右侧小图焦点图幻灯切换代码分享
2015/08/19 Javascript
Angular2 (RC5) 路由与导航详解
2016/09/21 Javascript
js实现导航吸顶效果
2017/02/24 Javascript
原生js简单实现放大镜特效
2017/05/16 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
微信小程序日期时间选择器使用方法
2018/02/01 Javascript
vue+echarts实现动态绘制图表及异步加载数据的方法
2018/10/17 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
2020/07/11 Javascript
Vue 数据绑定的原理分析
2020/11/16 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
Python中使用item()方法遍历字典的例子
2014/08/26 Python
Python计算三角函数之asin()方法的使用
2015/05/15 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
通过字符串导入 Python 模块的方法详解
2019/10/27 Python
python Plotly绘图工具的简单使用
2020/03/03 Python
Pytorch mask-rcnn 实现细节分享
2020/06/24 Python
HTML5 Video/Audio播放本地文件示例介绍
2013/11/18 HTML / CSS
个人生活学习自我评价范文
2013/11/26 职场文书
给民警的表扬信
2014/01/08 职场文书
元旦晚会邀请函
2014/02/01 职场文书
管理标语大全
2014/06/24 职场文书
物业管理专业自荐信
2014/07/01 职场文书
应聘教师求职信范文
2015/03/20 职场文书
22句经典语录:送给优柔寡断和胡思乱想的朋友们
2019/12/13 职场文书
经典《舰娘》游改全新动画预告 预定11月开播
2022/04/01 日漫