闪退没由报错_关于floor()报错注入,你真的懂了吗?

0x01 简述

floor报错注入也有叫group报错注入的,都一样,指的都是他们。floor报错注入我想大多数人跟我一样,都是会用而不明白其中的原理。这个问题困扰了在下好长时间了,所以决定好好研究下,最终产出了这篇文章。

0x02 环境

介绍下我的测试环境:

MySQL版本:5.5.53

使用的数据库:security.users,这数据库是sqli-labs的,大家都很熟悉。

0x03 搞起

a46b331dcf581fe75986e6b6f48bb55c.png

咱就直接抛出常用的报错语句了,语句的利用格式相对固定,咱们一点一点的拆解,一点一点说。

select count() from users group by concat(database(),floor(rand(0)2));select count(),concat(database(),floor(rand(0)2)) as x from users group by x;

61a2bf3998f102ce7922e3ff314ebdbe.png

它们表达的意思是一样的,第一个中的asx其实就是concat(database(),floor(rand(0)*2))的代指(别名),这两个SQL语句表达的意思并没什么区别。

来,让我们瞅瞅它报了什么错:

ERROR 1062 (23000): Duplicate entry ‘security1’ for key ‘group_key’

它说’group_key’的主键’security1’重复了,嗯?’security1’从哪里来的?哪个表的主键重复了?

36d9ffb76a081f2d8dcee32ce7a05e98.png

虽然刚开始,咱们还不知道原理,但是可以看到报错提示语句中的数据库函数已经被执行了。

就像我之前说的那样,我本身有用到sqli-labs的数据库,所以database()执行后是’security’很正常吧。

0x04 floor(rand(0)*2)

‘security1’中的1便是来自floor(rand(0)2),它说’security1’重复,那说明之前的表中已经有这个主键了。因为database()固定,我们继续来看下产生’1’的这个floor(rand(0)2)

rand()同样是一个数学函数,它返回一个随机浮点值[0,1]

751634ab920a5be374c24bc93368c68c.png

若指定一个整数参数N,则它被作用种子值(也被叫为随机因子),(rand()会根据这个种子值随机生成)用来产生重复序列,也就是rand(0)的值重复计算是固定的。

6e91c8ea564f9d56846a937b1cb84b7c.png

而它后面的*2,则是选定获取数据的范围[0,2],其实就是乘以2。

ad46eed0e2f096fced926b3d39647bd8.png

floor()同样是一个数学函数,返回不大于x的最大整数值,比如floor(3.3)返回3,floor(-3.3)返回-4。

81a7b507f3871c80479717311067f465.png

现在让我们看下计算users表数据的次数,floor(rand(0)*2)的值。

d617432d7f20645db5237925a0843e78.png

可以看到rand(0)的值确实是固定的。同时1也出现了。

concat()是字符串拼接函数,拼接多个字符串,如果字符串中含有NULL,则返回结果为NULL。这样来看,concat后的结果为’security0’或’security1’,’security1’出现了。

分析到这,我们后半部分没什么好说的了,rand()还有一个非常重要的特性我们之后跟group by一起说。

0x05 group by 与 count(*)

咱们再来说这个count(*),这是一个聚合函数,返回值的数目,它与count()的区别是它不排除NULL。

咱们通过select count(*) from users group by username;这个查询语句来了解下group by的工作过程。

539c4b0df5838cef8b08d8cb3a4a13aa.png1cfabc9a54300e01d46b8428a4705e76.png

group by在执行时,会依次取出查询表中的记录并创建一个临时表,group by的对象便是该临时表的主键。如果临时表中已经存在该主键,则将值加1,如果不存在,则将该主键插入到临时表中,注意是插入!

查询前创建的空临时表。

388a183b1b43fc4726fb49a4896ab850.png

取第一条记录,username是Dumb,发现临时表中没有该主键,则将Dumb插入到主键,count(*)值计1,取第二条记录。

317ac5a9359c10e64ddf0c552260655a.png

同样,取第二条记录,username为Angelina,同样没有该主键,则将Angelina插入到主键,count(*)值计1。

feebf9cf4be5eb979030cbdc4cbc5765.png

当取到原表中第8条admin时,同样将admin作为主键插入到临时表中,并将count()计1.当取第15条数据时,发现临时表中已经有admin作为主键了,则直接count()加1。最终结果:

01014c7bc30727a9d1a2203e36790b73.png

5b98f679e52425b31c1bac0350943c29.png

虽然在命令行中的显示结果跟咱的不太一样,但是思路是正确的(它貌似对结果按照字母进行了排序,又或者在插入临时表前就先进行了排序)。

写到这里,那按照上面的逻辑,报错语句应该是 select count(*) from users group by ‘security0’或’security1’;啊?!然后group by时创建临时表,第一个是security0,发现没有这个主键,此时将security0插入主键的位置,计1,然后取from表中的下一条记录。

fb3ab6e479df8aea25c0660f48bc47be.png

下一条是group by ‘security1’,临时表中不存在security1的主键,则将security1插入主键位置,计1,然后取下一条记录。

86f0cf87738bf39dd642f4dfa58bda90.png

之后group by 只有security0或security1,那应该只是计数上的变化了啊。最终应该是:

6d7d4dade834fafa3f1e587dd6e9705b.png

那为什么不是这个结果,反而报了主键重复的错误了呢?

因为还有一个最重要的特性,就是group by与rand()使用时,如果临时表中没有该主键,则在插入前rand()会再计算一次(也就是两次,但有些博客写的是多次,这个多次到底是几次并不知道,但是以两次来理解下面的实验都能说的通)。就是这个特性导致了主键重复并报错。我们来看:

当group by 取第一条from 表记录时,此时group by的是’security0’,发现临时表中并没有’security0’的主键,注意,这个时候rand(0)*2会再计算一次,经floor()后,率先插入临时表的主键不是security0,而是security1,并计数1。

369ab67b5b514d9527e66ac6f1f5a1b6.png

然后取第二条记录,第二条记录group by 的key中的01仍由floor(rand(0)2)继续计算获得,也就是security1。此时临时表中已经有security1的主键了,所以count()直接加1就可以。

1013c13aba05151adb28b195b0b427ca.png

继续从from的表中取第三条记录,再次计算floor(rand(0)2),结果为0,与database()拼接为security0,临时表的主键中并不存在,在插入前,floor(rand(0)2)又计算一次,拼接后与secruity1,但是是直接插入,即使临时表中已经有了主键security1也硬要插入,从而导致主键重复报错,也就是:ERROR 1062 (23000): Duplicate entry ‘security1’ for key ‘group_key’。

写道这里报错的原理已经说完了,不知道大家跟我呼应上了没,有没有感受到我的倔强及小宇宙。

0x06 优化

咱们继续看,咱们共从from的表中取了三条记录,因为floor(rand(0)2)的值为011011…,但其实第三次计算的1可以不要的,如果某个floor(rand(x)2)满足0101或1010,那么from的表中两条数据就是可以报错的。我经过多次实验,发现floor(rand(14)*2)的值为101000…,那么咱们创建一个有两条数据的表试一下看看。

f78bdbd104ce5f5f1f5b8d74d10b26c5.png

创建一个test表,里面只有两条数据。

2dbcd09bf6e7f9f68904e166c943e7f3.png

分别用rand(0)2和rand(14)2做实验。

362c2723be8c8052f90ae609a76f8d35.png

也就是说,在测试过程中,其实使用rand(14)*2更好一丢丢。如果from的表中只有一条数据的话floor()报错注入就没法用了,毕竟是重复,只插入一条数据怎么主键重复,对吧。

0x07 总结

最后一句话总结下:floor()报错注入的原因是group by在向临时表插入数据时,由于rand()多次计算导致插入临时表时主键重复,从而报错,又因为报错前concat()中的SQL语句或函数被执行,所以该语句报错且被抛出的主键是SQL语句或函数执行后的结果。

参考链接:

https://www.freebuf.com/column/235496.html

http://8rr.co/8bjS

34868d0c0239fde49bbbdf07832fc760.gif

精彩推荐

c817f75c4ce2bb64069835bdf9b871f3.png96077982f23490250f2819808a89543c.png97d9e65065eb96eb4a2f9a709dd8ad46.png

418a80907f8717c7d57f8a85df82b86c.png

ab04595f705c57151876202026809e8e.png

f805e641d828445fb0216eb0d446fee8.png

1c63f2c9a9e1093d7109e8810159c283.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/575109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS十六进制转浮点、字符串转为ArrayBuffer、ArrayBuffer转16进制字符串、16进制转10进制、crc校验位、十六进制转中文字符串(小程序、浏览器)、十六进制字符串转ascall字串

h5实现一键复制文本到剪切板 // 复制文本到剪切板 export function copyText (text) {// 将内容转换为字符串:const textString text.toString()// 获取input输入框,没有dom元素的话需要自动生成let input document.querySelector(#copy-input)if (!i…

Photoshop(CC2020)未完

基础知识: 概括: Adobe Photoshop,简称PS,是由美国Adobe Systems开发和发行的图像处理软件。属于再加工型软件,是对很多素材的再次加工处理,并非原创型软件。 功能:Photoshop主要处理以像素构成的位图图像…

使用 做签名的post_基础实操|使用jmeter对聊天软件进行接口测试

前言准备上架一款聊天app,上架之前准备做一些测试工作,模拟用户进入房间,维持心跳,房间送礼,发言等行为(因为用的第三方im以及声网,这些都是基于http的),也不是很懂测试,听老大说过一…

spring boot配置ip_Spring Cloud 配置中心高可用搭建

本文通过config server连接git仓库来实现配置中心&#xff0c;除了git还可以使用svn或者系统本地目录都行。引入依赖<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artif…

MySQL中主键的选择与磁盘性能

偶然看到了“Fotolog: Scaling the World\s Largest Photo Blogging Community”&#xff0c;才发现很多数据库的优化其实道理都很简单&#xff0c;至高境界是当你面对问题时&#xff0c;是否真正做出了自己的思考&#xff0c;而不仅仅只是经验主义的惯性使然&#xff1a;本文案…

python找钱_python 递归 找零钱

首先回答你的问题 count 1 coins_changeREC(coin_values, change-value)#1.when reached here, one recursion link ends if count < min_count: min_count count #2. update the minimum count of coins 每次走到注释1的地方的时候&#xff0c;对于一个coin_value开始的…

qt 等待线程结束_c – 停止Qt线程:调用exit()或quit()不会停止线程执行

在main()即主线程中创建了一个QThread.将一个worker类移动到新线程.该线程执行worker类的’StartThread’方法.工人线程&#xff1a;//header fileclass Worker : public QObject{Q_OBJECTpublic:Worker(QThread* thread);public slots:void StartThread();void EndThread();pr…

rcnn spp_net hcp

rcnn开创性工作&#xff0c;但是计算时间太长&#xff0c;重复计算太大。 spp_net将重复计算避免了。 hcp是yan shuicheng那边的&#xff0c;是用bing生成regions&#xff0c;然后用normalized cut将这些regions进行聚类&#xff0c;然后将聚类后剩下较小数量的regions进cnn&am…

eslint语法报错解决

今天将之前一个项目加入了eslint&#xff0c;发现很多变报错&#xff0c;但是反复检查自己代码是没有错误的&#xff0c;根据报错信息可知是某些api在eslint语法中使用不规范导致&#xff0c;大概总结如下&#xff1a; 1.setup中接收props 报错&#xff1a;Getting a value f…

MediaRecorder录像怎么旋转呀?

问题描述最近做的项目摄像头是跟手机按90度安装的&#xff0c;用MediaRecorder录像还是按摄像头的方向而不是手机的方向&#xff0c;录出来的是90度旋转的&#xff0c;试了很多方法都不管用。MediaRecorder.setOrientationHint没有效果&#xff0c;在底层AuthorDriver那都没有对…

简述python定义中的五个要点_Python基础知识复习

1.切片操作三个参数的意义&#xff1a;切片是Python序列的重要操作之一&#xff0c;适用于列表、元组、字符串、range对象等类型。切片使用2个冒号分隔的3个数字来完成&#xff0c;第一个数字表示切片开始位置(默认为0)&#xff0c;第二个数字表示切片截止(但不包含)位置(默认为…

matlab畸变校正代码_关于OpenCV中的去畸变

在opencv中&#xff0c;有关图像或像素点&#xff08;角点&#xff09;去畸变的函数有cv::undistort()&#xff0c;cv::getOptimalNewCameraMatrix()&#xff0c;cv::initUndistortRectifyMap()&#xff0c;remap()&#xff0c;cv::undistortPoints()。其中undistort可以直接对…

redis数据库简介、redis下载及安装(win64位)、node操作redis、redis实现短信校验注册接口

redis简介&#xff1a; 1:内存数据库,同时也能够保存数据到磁盘&#xff1b; 2:比其他的内存数据库有着更多的数据类型&#xff1a; 列表,集合,排序集合,哈希表等; 3:主从结构&#xff1a;数据可以备份到从服务器&#xff1b; 4: Redis数据操作速度快; 5:所有的操作都是原…

go func()和 go_Go的泛型真的要来了—如何使用以及它们是怎么工作的

点击上方蓝色“Go语言中文网”关注我们&#xff0c;领全套Go资料&#xff0c;每天学习 Go 语言你没看错&#xff0c;这里讲的就是 Go 中的泛型。只不过还没有正式发布&#xff0c;是基于草案设计的&#xff0c;已经是实现了可运行的版本。所以&#xff0c;泛型到来真的不远了&a…

bios设置_bios怎么设置显存 bios设置显存教程【图文】

有些用户可能会发现打开电脑系统信息窗口显示的内存容量与实际容量不同&#xff0c;例如系统内存显示4G&#xff0c;可用3.73G。那么不可用的那部分内存到哪里去了呢?其实是被集成显卡占用当做显存使用了。下面我们就通过 bios设置显存 来调整占用内存容量的大小&#xff0c;我…

4变形物体_Houdini基础(二)曲线变形物体

设想&#xff1a;先从二维上来看直角坐标系。物体是由x&#xff0c;y两个轴向的数据组成的。少了其中一组数据物体就只能是分布在单一轴向上的点。单独保留物体x、y情况下的点分布情况现在将x、y加起来&#xff0c;可见在三维空间中形成了一个平面。仅有x、y坐标的物体从目前的…

node.js+mysql实现分库分表存查数据:

node.jsmysql实现分库分表&#xff1a; 1.分库分表使用场景&#xff1a; 互联网项目中常用到的关系型数据库&#xff0c;如MySQL&#xff0c;随着用户和业务的增长&#xff0c;传统的单库单表模式难以满足大量的业务数据存储以及查询&#xff0c;单库单表中大量的数据会使写入…

Linux 添加新硬盘

1.识别分区和硬盘 在 /dev/ 目录下找到新的硬盘&#xff0c;sda 为本地硬盘&#xff0c;sda1、sda2.. 为分区&#xff0c;sdb 就是新添加的硬盘&#xff0c;如: [rootwusuyuan ~]# ls -ltr /dev/sd*brw-rw----. 1 root disk 8, 0 11月 14 14:12 /dev/sdabrw-rw----. 1 root di…

mybatis 映射成多个list_SSM:Mybatis架构与原理

MyBatis功能架构设计功能架构讲解&#xff1a;我们把Mybatis的功能架构分为三层&#xff1a;API接口层&#xff1a;提供给外部使用的接口API&#xff0c;开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。数据处理层&…

10无法勾选隐藏的项目_Excel超好用的隐藏操作,不可多得

日常工作中&#xff0c;表格数据的展示与隐藏也是有大学问的&#xff0c;为了表格更加简洁明了、美观大气&#xff0c;实用的隐藏技巧就派上用场了。且听小翼慢慢分享~1、隐藏行列方法1&#xff1a;选中目标区域&#xff0c;右击鼠标选择“隐藏”即可。如图&#xff1a;方法2&a…