前言
Mysql在执行语句的时候会抛出异常信息信息,而php+mysql架构的网站往往又将错误代码显示在页面上,这就让一些不法分子有机会从中获取敏感信息
通过floor报错
利用方式
|
|
公式解析
|
|
报错过程
- rand()用于产生一个0~1的随机数
- floor()向下取整
- rand()函数生成0~1的整数,向下取整,值是固定的’0’,将rand*2,得到的值就是不固定的,’0’或’1’
- concat()将符合条件的同一列中的不同列数据拼接,0x3a是十六进制的”:”
- 将之前的rand()函数和floor()函数整合起来
- 查询名字太长,起一个别名
- 再次查询.information_schema.tables有多少表,会显示多少列
- group by 依据我们想要的规矩对结果进行分组
- count()统计元组的个数
- 接着,多重复几次
floor(rand()2)与floor(rand(0)2)的不确定性与确定性
floor(rand()*2)不加随机因子的时候是随机出错的,而在3条记录以上用floor(rand(0)*2)就一定报错,由此可猜想floor(rand()*2)是比较随机的,不具备确定性因素,而floor(rand(0)*2)具备某方面的确定性。
通过测试发现,floor(rand()*2)毫无规律可言,而floor(rand(0)*2)是有规律的
那么mysql在遇到`select count(*)from tables group by x`这句话(实际就是建立虚拟表)
1.先建立虚拟表,其中key是主键,不可重复
2.开始查询数据,取数据库数据,然后查看虚拟表存在不,不存在则插入新纪录,存在则count(*)字段直接加,即如果key存在就+1,不存在话就新建一个key
其实mysql官方有给过提示,就是查询的时候如果使用rand()的话,该值会被计算多次,那这个“被计算多次”到底是什么意思,就是在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次,我们来看下floor(rand(0)*2)报错的过程就知道了,从0x04可以看到在一次多记录的查询过程中floor(rand(0)*2)的值是定性的,为`011011…`(记住这个顺序很重要),报错实际上就是floor(rand(0)*2)被计算多次导致的。
完整过程
- 查询前默认建立空虚拟表
- 取第一条记录,执行floor(rand(0)2),发现结果为0(第一次计算),查询虚拟表,发现0的键值不存在,则floor(rand(0)2)会被再计算一次,结果为1(第二次计算),插入虚表,这是第一条记录
- 查询第二条记录,再次计算floor(rand(0)2),发现结果为1(第三次计算),查询虚表,发现1的键值存在,所以floor(rand(0)2)不会被计算第二次,直接count(*)加1,第二条记录查询完毕
- 查询第三条记录,再次计算floor(rand(0)2),发现结果为0(第四次计算),查询虚表,发现键值没有0,则数据库尝试插入一条新的的数据,再插入数据时floor(rand(0)2)被再次计算,作为虚表的主键,其值为1(第5次计算),然而1这个主键已经存在与虚拟表中,而新计算的值也为1(主键键值必须唯一),所以插入的时候就直接报错了
整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要3条数据,使用该语句才会报错的原因。
updatexml
MySQL5.1.5版本中添加了对XML文档进行查询的修改的函数,分别是updatexml()和extracvalue()
|
|
执行报错的payload:1234567mysql> select 1,2,3 and updatexml(1,concat(null,(select @@version),null),1);+---+---+-----------------------------------------------------------+| 1 | 2 | 3 and updatexml(1,concat(null,(select @@version),null),1) |+---+---+-----------------------------------------------------------+| 1 | 2 | NULL |+---+---+-----------------------------------------------------------+1 row in set (0.00 sec)
报错原因:
- updatexml第二个参数需要的是Xpath格式的字符串,我们输入的格式显然不符合,故故障由此报错
- uodatexml的最大长度是32位的,所以有局限(PS:但是应对大多的已经足够。)如果密码长度超过了32位就不会被显示出来。