SQL注入:报错型盲注利用的BUG #8652详解

参考

原理参考
mysql-bug #8652

BUG #8652

BUG #8652的主要内容就是在同时使用RAND()函数,聚集函数COUNT()GROUP BY子句进行操作时会返回duplicate key 错误,而这个错误将会披露关键信息,如

“Duplicate entry ‘####’ for key 1”

这里的####正是返回了攻击者希望查询的内容

如果没有用到COUNT()的话是不会报错的
在这里插入图片描述

影响版本

目前测试结果为5.x版本有影响
8.x版本不会回显payload的结果,只会返回一个发生错误的临时表的位置(?)
在这里插入图片描述

复现

SELECT COUNT(*), CONCAT(0x23, 0x23, (SELECT database()), 0x23, 0x23, FLOOR(RAND(0)*2)) AS wuming from information_schema.columns GROUP BY wuming;

在这里插入图片描述中间的security正是SELECT database()的结果
至于从哪个表中查找数据是无所谓的,唯一重要的是你得确定这张表存在而且表中的数据列数应该大于某个特定的值(稍后做解析),所以选用INFORMATION_SCHEMA下表的原因是因为它肯定存在,比如换一个数据库也一样,反正最后是利用报错爆出信息
在这里插入图片描述

餐前准备

在这里插入图片描述INFORMATION.SCHEMATA一共有11行所以执行了11次
在这里插入图片描述在这里插入图片描述这样使用 rand 函数生成的小数序列都是一样的
具体原因不知道…
在这里插入图片描述
还有很重要的一点是COUNTGROUP BY的顺序
在这里插入图片描述在这里插入图片描述
先根据class对选回来的数据建立临时表并进行分组
边分组边统计每组数目
在这里插入图片描述

正餐

看一下payload

SELECT 
COUNT(*), 
CONCAT(0x23, 0x23, (SELECT database()), 0x23, 0x23, FLOOR(RAND(0)*2)) AS wuming 
FROM information_schema.columns 
GROUP BY wuming;

使用EXPLAIN可以看到这个查询建立了临时表
临时表参考
在这里插入图片描述
payload的执行也类似
在这里插入图片描述可以看到没有用到COUNT()时运行良好,并不会报错
如果加了COUNT(*)
首先看一下报错信息

Duplicate entry '##security##1' for key '<group_key>'

什么是<group_key>
使用临时表实现GROUP BY
按我的理解<group_key>应该是分组后唯一标识一个组的字段
就好像Primary Key是唯一标识一行数据的字段
所以<group_key>的值也不可以重复
如果重复了就会报上面的错误
那为什么会报错呢
看一下官网给的描述
画重点:查询同一行时会多次调用RAND()
在这里插入图片描述
先看一个不会报错的RAND(8)
不进行COUNT()时调用RAND(8)生成的wuming如下
在这里插入图片描述
调用COUNT时
在这里插入图片描述
限制条件id < 2使得只查出了一条记录
正常情况下临时表中wuming的值应该是 调用一次RAND()时生成的'##security##0'
此时临时表中并无'##security##0'这个group_key,于是需要插入键值为'##security##0'的记录
这时就触发了BUG #8652,使其又调用了一次RAND(),所以实际插入的是第二次得到的'##security##1'

查出两条记录时
在这里插入图片描述
此时已经调用过了两次RAND(),查出第二条记录时再次调用RAND(),得到的是'##security##1'
这时临时表中已经有这个group_key了,无需插入新记录,所以不触发BUG,而只是COUNT += 1

查出三条记录时,发现需要插入group_key为'##security##0'的新记录,又触发了BUG,再次调用RAND(),只不过这次生成的刚好也是'##security##0'
在这里插入图片描述查四条记录时,可以自己推一下
在这里插入图片描述

BUG #8652 至此可以总结为,同时调用聚集函数,RAND(),和GROUP BY时,当临时表中需要插入新记录时,会调用两次RAND(),实际插入的是第二次调用RAND()的返回值,当不需要插入新记录时,只调用一次,正常,无BUG。

那什么情况下会报错呢
以RAND(0)为例
在这里插入图片描述
设产生的一个临时表(字段wuming为<group_key>)如下

wumingcount

初始时为空

  1. 在INFORMATION_SCHEMA.SCHEMATA中查到了第一行数据,调用一次RAND(),得到wuming字段的值为'##security##0',需要插入新记录,触发8652号BUG使其又调用了一次RAND(),得到了 '##security##1',这时才会把第二次得到的'##security##1'插入临时表中
wumingcount
##security##11
  1. 查到了第二行数据,得到了 '##security##1',不需插入新记录,只是 COUNT += 1
wumingcount
##security##12
  1. 查到了第三行数据,得到了 '##security##0',需要插入,触发了BUG,又调用了一次RAND(),得到了 '##security##1',它想把 '##security##1'这条“新”记录插进去,然而表中实际上已经有了这个group_key,所以这时就发生了Duplicate entry '##security##1' for key '<group_key>'
  2. 如开头所说,选用哪张表不是关键,只要它存在,并且其中的行数要大于某一个特定的值,比如使用RAND(0)时至少得有三行,其它类推。

用途

能搜到这篇博客的肯定是知道怎么利用这个BUG了
不过还是贴几张嘻嘻

在这里插入图片描述在这里插入图片描述

一些问题

在这里插入图片描述最核心的payload

SELECT username FROM users WHERE id=1

返回值是Dumb
会报错,没问题
但是换一个核心payload却不报错了
返回值同样也是Dumb
在这里插入图片描述
观察下面的两个payload可以猜想出应该是GROUP_CONCAT产生了影响
在这里插入图片描述
但是也不太确定
因为爆表名时是可以使用的
在这里插入图片描述
然后分开SELECT也是可以的
在这里插入图片描述所以有些奇怪
先留坑吧
我太菜了

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值