原文:brokenbrowser
原作者:Manuel Caballero
譯:Holic (知道創宇404安全實驗室)

去年我演示過一個簡單的方法在 Edge 上進行 referrer 欺騙,可以用來欺騙 referer,還有額外驚喜:比如 XSS 過濾器的繞過。

今天我發現它已經被修復了,于是我決定找到繞過補丁的方法。老實說,我認為這不是一種繞過而是一些改動。實際看來,它依然有效地繞過了補丁,但從技術的角度來說,繞過方法有所不同。無論哪種方法,搞起!

修復前的原始 PoC

在原博文中我們可以看到,僅通過打開一個帶著對應 referrer 的新窗口,然后跳轉至目標域即可實現 referrer 欺騙。兩行代碼值千言。查看下面的 PoC,whatismyreferrer.com 認為referrer 是 paypal.com,實際上應該是執行 location.href 的頁面的 URL(現在已經被修復)。

win = window.open("https://www.paypal.com");
win.location.href = "https://www.whatismyreferer.com";

這足以欺騙 Edge 上的 referrer ,但是現在它已修復,而我突然想起一個簡單的變通方法。這里沒有調試或分析,顯然只是大膽測試,迅速且奏效。

我試了幾種方法來更改最終 URL(除了 location.href,采用 location.replace,meta 刷新,window.open 等方法),看看 Edge 能否被欺騙,卻未能如愿。但是,如果從 iframe 內部更改 URL,會發生什么?referrer 會變成頁面頂部還是 iframe 的 URL?

Playing with the referrer

在回答問題之前,請記住一個概念,通常 referrer 的網址應該是發起請求的網址。假設我們的 facebook.com 有一個 iframe 指向 eval.com,如果iframe 將頂部的 URL 更改為 paypal.com,那么 paypal 接收到的 referrer 應該是 evil 而不是 Facebook。

上圖顯示了預料到的結果(正確的),即使是在 Edge 上也是如此。但是如果不使用常規的鏈接跳轉,而是通過使用 location.href 設置頂部的 location ,然后 Edge 會搞混,使用其頂部的地址作為 referrer。

以下便是一個簡單的測試頁面,其中顯示了常規鏈接跳轉和 location.href 之間的區別。二者都會把你帶到 whatismyreferer.com,但是你會看到常規鏈接正確跳轉了,而 top.location.href 沒有。

[ 漏洞演示頁面 ]

但是我們如何利用這個漏洞呢?顯然,Facebook 永遠不會提供惡意的 iframe 對吧?好吧,Facebook 其實會像雅虎這樣的大廠商提供 iframe 廣告服務。這些廣告會代表這些大型網站加載任何網頁。此外,使用 top.location.href 的話,這些廣告可以毫無障礙地繞過 XSS 過濾器。

就個人而言,我討厭理論上的漏洞,因為這根本無法讓我滿意。你懂的,“如果用戶點擊此處,接受警告,解壓文件,雙擊exe,他就被感染了”。我并不喜歡這樣。

為了達到有效利用的目標,通過將 iframe 注入到要欺騙referrer 的站點中,然后從中執行 top.location。這與在任何網站上放置 iframe 上是一個道理,但是我們不需要任何相關合作!此話怎講?我們希望 whatismyreferer.com(受害者)相信用戶是來自 paypal.com(假的 referrer)。 而計將安出?

注入 iframe

  1. 打開新窗口,將服務器重定向至 PayPal
  2. 重定向發生之前,注入 iframe
  3. 重定向發生時,在 iframe 中用 top.location 跳轉至 whatismyreferer.com

關于這個 iframe 注入,之前關于 IE 的文章 htmlFile/UXSS 有所提及,這里我們再回顧一下吧。

當我們通過服務器重定向(1)打開新窗口時,我們有一點兒時間(重定向發生之前)訪問它的DOM,這便是注入iframe(2)的時機。一旦重定向發生,Edge將盡力刪除頁面(包括我們的iframe)中的所有內容并渲染PayPal,但是我們將通過阻塞線程阻止這一步。然后,一旦重定向發生,解鎖該線程,并從iframe內部執行一個top.location.href(3)。

這種特殊情況下,我們使用了與這兩處(xss-ie-domainless-worlduxss-ie-htmlfile)相同的技術阻塞線程,可以看到一個簡陋的大大的 alert。當然有辦法在不需要用戶交互和 alert 的情況下阻塞線程,但我不想讓攻擊者太輕松地實現。如果 PoC 會彈出 alert,且必須進行用戶交互,這就顯得用處不大了。這里有完整的 PoC:

// Open a new window with a server redirect to paypal
var win = window.open("redir.php?URL=https://www.paypal.com");

// Create an iframe immediately, before it redirects
var ifr = win.document.createElement("iframe");
win.document.appendChild(ifr);

// Make sure the iframe has access to its top (otherwise it will lose it)
win[0].opener = win;

// Block the iframe and once the redirect happens, move to the victim website.
win[0].setTimeout("alert('Close me once the site starts loading behind');" +
                   "opener.location='https://www.whatismyreferer.com'");

[ Test the PoC Live on Edge ]

捉蟲獵手學無止境。關掉Facebook標簽,讀一些有趣的東西吧。生如夏花,死如秋葉,莫要徒勞無功。繼續學習,有所取舍,然后享受你的成果!

Have a nice day! ?


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