作者:
gainover
·
2014/02/24 11:43
0x00 譯者的話
本文原文是由國外大牛Mario Heiderich在2013年所寫的一篇paper:mXSS attacks: attacking well-secured web-applications by using innerHTML mutations. 本人覺得此類mXSS攻擊較為隱蔽,常規的XSS過濾器並不能防止此類攻擊。在測試QQ空間日誌中的確存在此類問題後,認為mXSS在WEB應用中還是存在較大的潛在危害,因此,決定將此文做一個翻譯。但是,一來由於水平有限,僅能依靠自己淺薄的理解來大致的翻譯一下,文中圖片以及程式碼都是在自己的理解上加以重新闡述,也許這樣更加易於讀者掌握。如果英文較好的同學可自行閱讀英文原版。二來,我個人僅注重“攻”的一部分,本文中我認為實用性不高的部分,以及如何防禦此類攻擊的大幅段落,我並未進行翻譯,因而有需要的讀者也需要自行去了解這些部分。不論如何,希望本文能夠讓國內的研究者們對mXSS有一個基本的瞭解。
0x01 簡介
不論是伺服器端或客戶端的XSS過濾器,都認定過濾後的HTML原始碼應該與瀏覽器所渲染後的HTML程式碼保持一致,至少不會出現很大的出入(圖1)。然而,如果使用者所提供的富文字內容透過javascript程式碼進入innerHTML屬性後,一些意外的變化會使得這個認定不再成立:一串看似沒有任何危害的HTML程式碼,將逃過XSS過濾器的檢測,最終進入某個DOM節點的innerHTML中,瀏覽器的渲染引擎會將本來沒有任何危害的HTML程式碼渲染成具有潛在危險的XSS攻擊程式碼。隨後,該段攻擊程式碼,可能會被JS程式碼中的其它一些流程輸出到DOM中或是其它方式被再次渲染,從而導致XSS的執行。 這種由於HTML內容進入innerHTML後發生意外變化(mutation,突變,來自遺傳學的一個單詞,大家都知道的基因突變,gene mutation),而最終導致XSS的攻擊流程,被稱為突變XSS(mXSS, Mutation-based Cross-Site-Scripting),整個流程的示意圖見圖2。從流程中不難看出,突變發生在XSS過濾流程之後,因此不論是伺服器端還是客戶端的XSS過濾器對這類攻擊並不能進行有效的防禦。
圖1. XSS過濾所假設的前提
圖2. mXSS攻擊流程
將內容置於innerHTML這種操作,在現在的WEB應用程式碼中十分常見,根據原文作者的統計,1W個常見的WEB應用中,大約有1/3使用了innerHTML屬性,這將會導致潛在的mXSS攻擊。從瀏覽器角度來講,mXSS對三大主流瀏覽器(IE,CHROME,FIREFOX)均有影響。表1列出到目前為止已知的mXSS種類,接下來的部分將分別對這幾類進行討論與說明。建議讀者主要使用IE8來測試本文中的程式碼。具體測試程式碼如下:
#!html
<div id="testa">xx</div>
<div id="testb">xx</div>
<script>
//請自行將輸入的HTML程式碼中的雙引號以及 \進行轉義操作
//其中: " -> \" , \ -> \\
var m="此處輸入被測試的HTML程式碼";
//1. 將使用者輸入內容放入innerHTML
var x=document.getElementById("testa");
x.innerHTML=m;
//2. 發生突變後,取出突變後的內容,放入html變數
var html=x.innerHTML;
//3. 彈出突變後的程式碼
alert(html);
//4. 將突變後的程式碼輸出到DOM中
document.getElementById("testb").innerHTML = html;
</script>
表1. 本文中所涉及的mXSS種類
英文 |
中文 |
Backtick Characters breaking Attribute Delimiter Syntax |
反引號打破屬性邊界導致的 mXSS |
XML Namespaces in Unknown Elements causing Structural Mutation |
未知元素中的xmlns屬性所導致的mXSS |
Backslashes in CSS Escapes causing String-Boundary Violation |
CSS中反斜線轉義導致的mXSS |
Misfit Characters in Entity Representation breaking CSS Strings |
CSS中雙引號實體或轉義導致的mXSS |
CSS Escapes in Property Names violating entire HTML Structure |
CSS屬性名中的轉義所導致的mXSS |
Entity-Mutation in non-HTML Documents |
非HTML文件中的實體突變 |
Entity-Mutation in non-HTML context of HTML documents |
HTML文件中的非HTML上下文的實體突變 |
0x02 反引號打破屬性邊界導致的 mXSS
該型別是最早被發現並利用的一類mXSS,於2007年被提出,隨後被有效的修復,所以當前絕大多數使用者的瀏覽器不會被此mXSS所影響。當時的利用程式碼如下:
#!html
輸入形式:
<img src="test.jpg" alt ="``onload=xss()" />
突變形式:
<IMG alt =``onload=xss() src ="test.jpg">
可以看到,突變後的形式變成了有效的XSS攻擊程式碼。
0x03 未知元素中的xmlns屬性所導致的mXSS
一些瀏覽器不支援HTML5的標記,例如IE8,會將article,aside,menu等當作是未知的HTML標籤。對於開發者來說,雖然是未知標籤,但是我們還是可以透過設定這些標籤的xmlns 屬性,讓瀏覽器知道這些未知的標籤是的XML名稱空間是什麼。一般來說,在HTML中,指定這些未知標籤的xmlns屬性並沒有任何意義,也不會改變它們在瀏覽器中的外觀之流的東西。但是,這些被指定了xmlns屬性的標籤進入innerHTML後,被瀏覽器所渲染,就會發生一些變化,而這個變化被十分猥瑣的用於了XSS。首先我們來看正常情況下設定xmlns的情況。
#!html
輸入形式:
<pkav xmlns="urn:wooyun">123
突變形式:
<wooyun:pkav xmlns="urn:wooyun">123</wooyun:pkav>
接著猥瑣流很快就會想到下面的程式碼,可以看出,成功變成了含有onerror=alert(1) 的img標籤。
#!html
輸入形式:
<pkav xmlns="urn:img src=1 onerror=alert(1)//">123
突變形式:
<img src=1 onerror=alert(1)//:pkav xmlns="urn:img src=1 onerror=alert(1)//">123</img src=1 onerror=alert(1)//:pkav>
擴充套件:細心的同學也許會注意到,我們的程式碼中,並未閉合