原文鏈接:UXSS on Microsoft Edge – Adventures in a Domainless World (無域世界大冒險)

原作者:Manuel Caballero

譯:Holic (知道創宇404安全實驗室)

注:相關文件可在此下載

今天,我們來討論設計上的問題,配合這些問題,我們最終在 Microsoft Edge 瀏覽器上實現了通用跨站腳本攻擊(UXSS)。如果你不是安全研究員,但還是想了解此漏洞,你可以這樣理解:訪問惡意網頁,攻擊者就能讀取你的 Cookie,更改客戶端的網頁內容,獲取個人信息等。此外,由于 Microsoft Edge 使用 受保護的內部資源執行特殊操作,攻擊者可能會訪問這些資源,并可能設置 Edge 的配置選項,打開 IE 等。

我們有段視頻展示了針對 bing cookie 的攻擊,另一段視頻顯示 nature.com 的內容。但請記住,這些網站本身沒有任何問題:而該漏洞來自 Microsoft Edge 瀏覽器。下面我們來看看這是怎么做到的。

Domainless World

about:blank 是個非常特殊的 URL,有時會使人感到困惑,不知道屬于哪里。思考一下:如果我們位于 www.magicmac.com/dom/index.html ,document.domain 顯然是 www.magicmac.com,但是 about:blank 的域屬于什么呢?這就視情況而定了。理論上,它應該匹配 referrer 的域,即設置其網址的網頁。例如,如果我們在 www.magicmac.com 點擊一個 about:blank 鏈接,那么該 about:blank 就將 www.magicmac.com 作為它的域。

另一個例子是 iframe,其來源指向 about:blank,或者根本沒有源(瀏覽器默認為 about:blank)。

所以,從 goodfellas.com 加載 about:blank 看起來和從 evil.com 加載差不多,因為兩個 URL 是相同的,但他們有不同的 document.domain ,所以它們之間不能互相訪問

那么問題來了:我們手動輸入到地址欄中的 about:blank 的域是什么?要的就是這個!答案如此重要,所以我把 Devtools 放大了看。

是空的,如我們所見,它有巨大的力量,但是為了確保我們是在同一頁面,我們調用一個沒有域的“無域名”(domainless)和“有域”的(domained)的 URL,鏈接至有 document.domain 的網站。

Bug hunter,本篇文章以下便是重要的東西了。

“A domainless about:blank is capable of accessing any domained about:blank”

(無域的 about:blank 能夠訪問任何有域的 about:blank)

換句話說,一個無域的 about:blank 可以無限制訪問有域的 about:blank 。我們在此投機取巧,直接在調試控制臺操作,快速添加一個 bing.com 的 iframe 到這個頁面。

document.body.innerHTML = '<iframe src="http://www.bing.com/images/search?q=microsoft+edge"></iframe>'

很好!我們在頂層無域的 blank 中有一個 bing.com 的 frame,但是我們的目標是找到 bing 中的一個空白的 iframe,如我所述,一個無域的 blank (main windows)將能夠訪問任何有域的 blank(bing.com 中的 iframe)。

這種情況下很容易實現,因為我們使用的 bing.com 已經有 blank 的 iframe 了。但讓我們繼續嘗試一下吧!即使來自調試器,下面的這條指令通常拒絕訪問,但由于頁面的頂層是無域的,它可以運行。那么讓我們來一探究竟!

window[0][0].location.href = "javascript:alert(parent.document.domain)";

Bang!我知道這不會深入你腦海,因為我們是從 DevTool 獲得了結果,對吧?但是對我來說,這是我所做的最重要的事情,因為如果我們能夠掌握這一理念,接下來發現新的 UXSS 將在一定程度上變得輕松不少。從現在起,每找到一種訪問無域的 blank 的方法(一般是 about:blank ,但我們也可以用其他的),我們將得到一個 UXSS。現在是使用 DevTools 的情況,我想確認一下我們完全了解所正在做的,當然我們不需要 DevTools。

獨立 PoC, 無須 DevTools

現在來動真格的吧。我們需要找到一種方法,創建一個可以從普通網頁訪問的無域網站,更快的方法是使用 data: URI 而不是 about:blank 。同理,至少協議不同。而如果我們在 iframe 內部加載 data: URI ,則其域將與其引用的域相同(就像我們在開頭看到的 about:blank 一樣),而且如果嘗試在頂層加載 data:uri 的數據,Edge 會拒絕將我們送至錯誤頁面。

然而,我們有幾個小技巧,可以做到獲取無域數據的 data:uri ,現在我們來探索 Flash 版的 PoC,因為它及其簡單。事實上,我從 2005 年以來一直在使用這個 Flash,它只設置了一個來自查詢字符串的 URL,趕快利用它!

<iframe src="geturl.swf?target=_top&redir=data:,[html/script goes here]"></iframe>

看到了嗎?僅需將你想加載的 URL 添加到 redir 參數中即可。在這種情況下,我們使用了一個 data:uri ,并將其加載在無域的頂層。此外,為了欺騙 Edge 瀏覽器,我們需要在 iframe 內部加載 swf ,否則將無法達成效果(錯誤頁面)。你可以自己試一下。

順便說一下,別忘了我們可以找到實現同樣效果的替代品。我剛剛使用它是因為它是首先被發現的,Adobe 的人可能會將 data:uri 列入黑名單,以便幫助我的 @Edge 朋友擺脫此 bug。然而,有很多方法實現相同的事情而無需 flash 文件。提出你自己的想法,找到自己的方式!

OK,現在我們在無域的窗口中,我們可以注入一個指向 bing.com 的 iframe,但是 Edge 處于不能正確渲染頁面元素的狀態。如果我們嘗試使用 createElement/insertAdjacentHtml/etc 它將不能生效。我的意思是,Edge 會繪制一個“死”的 iframe,就像沒有引擎的汽車一樣:它根本無法正常運行。為了解決此難題,我們使用 document.write 寫入自身,強制瀏覽器再次進行渲染。而且因為我們在無域的 URL 中,document.write 將使我們完全位于同一地址/域之中。

document.write('<iframe src="http://www.bing.com/images"></iframe>');

完美!現在我們可以訪問 bing 的空白 iframe,但是記得我們這回屬于比較幸運,因為并不是所有的站點里面都會有 “free blank iframes”。

window[0][0].location.href = "javascript:alert(parent.document.cookie)";

MS Edge 的線上 PoC 在此

我很興奮,這次在沒有 DevTools 的情況下利用生效了。Oh,no,我知道你在想什么,多疑的 bug hunter:Bing 白白給我們提供了一對空的 iframe,這太簡單了!是的,但我只是稍微慶祝一下!從現在開始我會叫你 killjoy!不再是 “bug hunter”。?

我們繼續,killjoy。我知道網站不會喜歡給我們提供空 iframe 的主意,所以我們需要找到自己的方式。

Owning non-cooperative sites

拿下非合作站點

想想一下,我們在第二步頂層是無域的 data: ,而我們的 iframe 正確呈現,但指向 nature.com 而不是 bing.com (因為 nature 有一個非空的 iframe)。如果我們嘗試更改 iframe 的地址,Edge 會拒絕打開一個新窗口。換句話說,這種事情是無效的。

// We are inside a domainless data: so Edge will open a new
// window instead of changing nature-iframe's location
window[0][0].location.href = "about:blank";

這不會生效的。也行它可以繞過,但我已經進行了足夠的嘗試。這是在無域的情況下發生的問題,因此我們可以打開一個帶有真實 URL 的新窗口,然后從那里再進行處理。這正是我們將要做的:

  1. 打開一個內有 nature.com iframe 的新窗口。[現在我們在新窗口里面有了一個常規 URL]
  2. 將 nature 的內部 iframe 的地址更改為 about:blank ,這樣我們可以給它一個名稱。是的我們希望 iframe 有一個名稱。
  3. 將名稱設為 about:blank,那么我們的無域 opener 就能通過 window.open 訪問到它了。別忘了我們現在窗口內有一個常規的 URL,它是我們強大的 opener。我們將向這個 iframe 命名,就像這樣:window.name = "DAVID_COPPERFIELD" ,以紀念這位繼續帶著激情學習的魔術師。
  4. 現在我們應該將 about:blank (屬于我們的域)的地址設置為 nature 的地址。為此,我們將使用 meta-refresh 將地址更改為 about:blank 。輕而易舉。這個技巧確保 about:blank 恢復至其父域的域。
  5. 讓 opener 知道一切就緒,所以它可以訪問了,就像這樣:window.open(“javascript:alert(document.domain)”, “DAVID_COPPERFIELD”);

MS Edge 的線上 PoC 在此

再次享受,但這次在房子里歡呼雀躍。Yes!Opsss,我的妻子問我發現了什么。她明白這些尖叫意味著什么。?

killjoy 先生,我們又做到了。PoC 是交互式的,因此我們可以實時了解我們正在做什么,但請閱讀代碼的具體細節,我確定有改進的余地。如果你提出這些想法,那么你很可能會發現能夠實現類似事情的變通方法。研究,學習,學到了!很有趣。

在沒有 Flash 的情況下,你能找到自己的方法設置無域 URL 的方法嗎?是的,你可以的。此外,只要有我們在此一起探討代碼,我們可以創建多種多樣的 UXSS 場景,比如在 iframe 訪問其頂層。那可能嗎?假設我是由 Facebook 呈現的橫幅廣告。可不可以訪問我們的頂層,并獲取就像用戶好友列表這樣的東西?當然!訪問不喜歡在框架中呈現的 XFO 站點怎么辦?iframe 是唯一能夠呈現 HTML 元素的嗎?最后,完全沒有 iframe 的網站又怎么辦?我給你保證,我們甚至能夠接觸到編制這些代碼的人。坐下來探索一下吧!這里有你需要的文件

Have a nice day! Manuel.


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