sql注入 报错注入_sql原理

sql注入 报错注入_sql原理sql注入报错注入原理详解前言我相信很多小伙伴在玩sql注入报错注入时都会有一个疑问,为什么这么写就会报错?曾经我去查询的时候,也没有找到满意的答案,时隔几个月终于找到搞清楚原理,特此记录,也希望后来的小伙伴能够少走弯路0x01我们先来看一看现象,我这里有一个users表,里面有五条数据:然后用我们的报错语句查询一下:selectcount(*…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

这里写图片描述



sql注入报错注入原理详解

前言

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

0x01

我们先来看一看现象,我这里有一个users表,里面有五条数据:
这里写图片描述
然后用我们的报错语句查询一下:

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

这里写图片描述
成功爆出了数据库的版本号。
要理解这个错误产生的原因,我们首先要知道group by语句都做了什么。我们用一个studetn表来看一下:
这里写图片描述
现在我们通过年龄对这个表中的数据进行下分组:
这里写图片描述
形成了一个新的表是吧?你其实应该能够想到group by 语句的执行流程了吧?最开始我们看到的这张sage-count()表应该时空的,但是在group by语句执行过程中,一行一行的去扫描原始表的sage字段,如果sage在sage-count()不存在,那么就将他插入,并置count()置1,如果sage在sage-count()表中已经存在,那么就在原来的count(*)基础上加1,就这样直到扫描完整个表,就得到我们看到的这个表了。

注:这里有特别重要的一点,group by后面的字段时虚拟表的主键,也就是说它是不能重复的,这是后面报错成功的关键点,其实前面的报错语句我们已经可以窥见点端倪了这里写图片描述
####0x02
正如我前面所说的,报错的主要原因时虚拟表的主键重复了,那么我们就来看一下它到底是在哪里,什么时候重复的。这里rand()函数就登场了。
首先我们先来了解rand()函数的用法:
1.用来生成一个0~1的数
2.还可以给rand函数传一个参数作为rand()的种子,然后rand函数会依据这个种子进行随机生成。
那他们的区别是什么呢?我们来看一下,这两个语句的执行效果:
这里写图片描述
可以看到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)生成的有规律的序列:
这里写图片描述
我们跟着刚刚的思路走,最开始的虚拟表是空的,就像下面一样:

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()的话,因为它生成的序列是随机的嘛,所以并不是每次执行都会报错,下面是我的测试结果:
这里写图片描述
执行了五次,报错两次,所以是看运气。

总结

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187359.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • FGMap API 帮助文档

    FGMap API 帮助文档

  • psd效果预览转成网站首页(html+css)

    psd效果预览转成网站首页(html+css)1.先确定结构按结构划分区块,从整体到部分2.切图:ctrl+缩览图可以载入选区(1)logo类:包括一些小图标+文字+数字(透明背景)首先选择这些图片的图层(shift选择多个),转成智能对象,双击图标进入,存储为web格式(png-24,颜色不需要太丰富,24即可)注意,这些logo一般放在<a>链接中,href="#"链接到首页(本页)(2)海报、设计图…

  • Opencv中width和widthStep的区别

    Opencv中width和widthStep的区别在Opencv的结构Iplimage中,widthStep并不一定等于width*nChannel*(数据类型所占字节),这是因为Opencv中对内存有管理的机制,这一机制会对内存进行对齐,也就是当每一行所占的字节数不等于4的倍数时会自动补齐。例如:width=117,depth=8U,nChannel=1,则widthStep=120,因为117不是4的倍数,所以补齐到120。如果dep

  • pycharm的使用教程_gg修改器使用教程基础

    pycharm的使用教程_gg修改器使用教程基础PyCharm这款IDE功能虽然强大,但正因为它的强大,所以对于刚入手的人来说,在初期使用时会显得困难。那么,今天这篇文章我就来写一下PyCharm的基本操作,让那些刚使用的新手们能快速入手。2基本配置我们安装好PyCharm后,首先要进行一些小配置,比如主题,字体,字体颜色等。我们打开PyCharm后,点开file,找到Setting然后就会跳出Setting的窗口可以说PyC…

  • 使用RSS实现自动动漫更新提醒及下载(追番)

    使用RSS实现自动动漫更新提醒及下载(追番)喜欢追动漫番并且喜欢下载下来看和收藏的各位应该都有个觉得不方便的地方,那就是每天都得跑去下载的网站进行查看追的剧是否更新。而这并不是难受的地方,更麻烦的是还要记每部剧上个星期放到了第几集,有时候忘记看了,下个星期跳过了一集下载下来,打开看了才发现,然后还得回去下,这真是gay得一批。。好吧闲话有点多了。进入正题吧。作为程序狗的各位对这种需求自然有自己的解决办法,自己写程序进行定时检查是最直接

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号