我們在上一篇文章中介紹了響應類型,如何通過postMessage 竊取令牌以及小工具1,本文接著講小工具2、小工具3,以及洩露URL 的其他途徑。
小工具2:示例1,從沙盒框架中竊取window.name我在5 月12 日報告了使用這個小工具在野外發現的第一條鏈:
巧合的是,兩天后的5 月14 日,Youssef Sammouda 發表了一篇很棒的博文,解釋了他接管使用Gmail 的Facebook 帳戶的方法。這篇博文描述了我發現的類似流程。但是,該錯誤並不是要破壞OAuth-dance,而是通過使用允許加載任意javascript 的iframe:d 沙盒域來洩露受害者最終訪問的URL。沙盒訪問URL 中的敏感數據的原因是它在加載iframe 時附加到沙盒URL。
不過,我發現的案例有點不同。
第一個是在OAuth-dance結束的頁面上加載iframe。 iframe是window.location-object的json字符串版本。這是一種舊的跨域傳輸數據的方法,因為iframe中的頁面可以得到由父節點設置的自己的window.name:
在iframe中加載的域也有一個簡單的XSS:
正如Youssef解釋的那樣,如果你在一個窗口的一個域上有一個XSS,那麼如果窗口之間存在父/子/開啟者關係,則該窗口可以到達同源的其他窗口。
在示例中,我做了以下操作:
1.創建了一個惡意頁面,該頁面嵌入了沙盒的iframe,XSS 加載了我自己的腳本:
2.在沙盒中加載腳本時,我將內容替換為受害者使用的鏈接:
我還啟動了一個腳本,以檢查鏈接是否已打開,並且我想訪問的iframe 是否存在以獲取iframe 上設置的window.name 與攻擊者頁面上的iframe 相同的來源:
3.然後,攻擊者頁面可以只偵聽我們剛剛發送的帶有window.name 的消息:
小工具2:示例2,帶有XSS + 父源檢查的iframe第二個示例是使用postMessage 將iframe 加載到具有XSS 的不太好用的路徑上,但僅允許來自加載它的父窗口的消息。當它在給父窗口的消息中請求initConfig 時,location.href 被發送到iframe。
主窗口像這樣加載iframe:
內容如下所示,這比實際情況要簡單得多,只是為了更好地解釋攻擊:
在這種情況下,我可以執行與第一個示例類似的方法:
1.創建一個嵌入沙盒iframe 的惡意頁面,附加onload 以在加載iframe 時觸發腳本。
2.由於惡意頁面是iframe 的父級,它可以向iframe 發送消息以使用postMessage 將我們的腳本加載到沙盒的來源:
3.在沙盒中加載腳本時,我將內容替換為受害者的鏈接:
我還啟動了一個腳本,以檢查鏈接是否已打開以及我想要訪問的iframe 是否存在,以便在其中運行javascript 從我的iframe 到主窗口。然後,我在惡意窗口中附加了一個postMessage 偵聽器,該偵聽器將消息傳遞回我的iframe:
4.加載了iframe 的攻擊者頁面然後可以在主窗口的iframe 中偵聽我從注入的postMessage-listener 代理髮送的消息:
小工具3:使用API 獲取越界URL
這個小工具原來是最有趣的。把受害者送到某個地方然後從另一個地方獲取敏感數據,這讓人很滿意。
小工具3:示例1,沒有來源檢查的存儲框架第一個示例使用外部服務來跟踪數據。該服務添加了一個存儲框架:
主窗口將使用postMessage 與此iframe 對話,以發送跟踪數據,這些跟踪數據將保存在storage.html 所在的源的localStorage 中:
主窗口也可以獲取以下內容:
當iframe 在初始化時加載時,使用location.href 為用戶的最後一個位置保存了一個項:
如果你能以某種方式與這個來源對話,並讓它向你發送內容,那麼location.href 可以從這個存儲中獲取。該服務的postMessage-listener 有一個阻止列表和一個來源的允許列表。分析服務似乎允許網站定義允許或拒絕的來源:
此外,如果你有一個基於allowList 的有效來源,你還可以請求同步,這將在此窗口中向你發送對localStorage 所做的任何更改。
在將這個存儲加載到OAuth-dance 的不太好用路徑上的網站上,沒有定義allowList-origins;如果源是窗口的父級,這允許任何源與postMessage-listener 對話。該方法類似於小工具2:
1.我創建了一個惡意頁面,該頁面嵌入了存儲容器的iframe,並附加了一個onload,以便在加載iframe時觸發腳本。
2.由於惡意頁面現在是iframe的父頁面,並且在allowList中沒有定義任何起源,因此惡意頁面可以向iframe發送消息,告訴存儲發送對存儲的任何更新的消息。我還可以向惡意頁面添加一個偵聽器,以偵聽存儲中的任何同步更新:
3.惡意頁面還包含一個供受害者點擊的常規鏈接:
受害者會點擊該鏈接,通過OAuth-dance,最終進入加載跟踪腳本和存儲iframe 的不太好用路徑。存儲iframe 獲取last-url 的更新。自從localStorage 更新以來,window.storage-event 將在惡意頁面的iframe 中觸發,並且每當存儲更改時,當前正在獲取更新的惡意頁面將獲得帶有受害者當前URL 的postMessage:
小工具3:示例2,CDN 中的客戶混淆——DIY 存儲——沒有來源檢查的SVG由於分析服務本身有一個漏洞賞金,我也有興趣看看我是否可以找到一種方法來洩露已經為storage-iframe 配置正確來源的網站的URL。
當我開始在線搜索沒有客戶部分的cdn.analytics.example.com 域時,我注意到這個CDN 還包含服務客戶上傳的圖像:
我還注意到這個CDN 上有SVG 文件作為Content-type: image/svg+xml 內聯提供:
我在該服務上註冊為試用用戶,並上傳了我自己的資產,該資產也出現在CDN 上:
有趣的是,如果你隨後將特定於客戶的子域用於CDN,則仍然會提供圖像。 URL如下:
這意味著ID #94342 的客戶可以在客戶#12345 的存儲中呈現SVG 文件。
我上傳了一個帶有簡單XSS 有效負載的SVG 文件:
效果不是很好。 CDN 為img/下的所有內容添加了Content-Security-Policy: default-src 'self'-header。你還可以看到提到S3 的服務器標頭,這表明內容已上傳到S3 存儲桶:
S3 的一個有趣的事情是目錄在S3 中並不是真正的目錄。項之前的路徑稱為“前綴”。這意味著S3 不關心/是否經過url 編碼,如果你對URL 中的每個斜杠進行url 編碼,它仍然會提供內容。如果我在URL 中將img/更改為img%2f ,仍然可以解析圖像。但是,在這種情況下,CSP-header 被刪除並觸發了XSS:
然後我可以上傳一個SVG,該SVG 將創建與常規storage.html 相同形式的存儲處理程序和postMessage-listener,但允許列表為空。即使在正確定義了可以與存儲通信的允許來源的網站上,這也使我能夠進行相同類型的攻擊。
我上傳了一個看起來像這樣的SVG:
然後我可以使用與示例#1 中相同的方法,但我可以使用url 編碼的斜杠iframe 而不是iframe 的storage.html:
由於沒有網站能夠自行修補此問題,因此我向負責CDN 的分析提供商發送了一份報告:
在第三方上查看錯誤配置產生漏洞的整個想法主要是確認有多種方法來實現令牌的洩漏,並且由於第三方有漏洞賞金,這只是同一種漏洞的不同接收者,不同之處在於影響是針對分析服務的所有客戶。在這種情況下,第三方的客戶實際上有能力正確配置該工具,使其不會將數據洩露給攻擊者。然而,由於敏感數據仍被發送給第三方,所以看看是否有某種方法可以完全繞過客戶對工具的正確配置是很有趣的。
小工具3:示例3,聊天小工具API最後一個例子是基於一個出現在網站所有頁面上的聊天小工具,甚至是錯誤頁面。有多個postMessage 偵聽器,其中一個沒有適當的來源檢查,只允許你啟動聊天彈出窗口。另一個偵聽器對聊天小工具進行了嚴格的來源檢查,以接收初始化調用和當前用戶使用的當前聊天API 令牌。
聊天iframe 加載時:
1.如果chat-api-token 存在於chat-widget 的localStorage 中,它將使用postMessage 將api-token 發送給其父級。如果沒有chat-api-token 存在,它不會發送任何東西。
2.當iframe 加載後,它會向其父級發送一個帶有{'type': 'chat-widget', 'key': 'init'} 的postMessage。
如果你點擊主窗口中的聊天圖標:
1.如果chat-api-令牌還沒有被發送,那麼chat-widget會創建一個令牌,並將其放在自己的源的localStorage中,並將其postMessage發送給父窗口。
2.然後父窗口將對聊天服務進行API 調用。 API 終端被CORS 限制為為服務配置的特定網站。你必須使用chat-api-token 為API 調用提供有效的Origin-header 以允許發送請求。
3.來自主窗口的API 調用將包含location.href 並使用chat-api-token 將其註冊為訪問者的“當前頁面”。然後,響應將包含一些令牌,以連接到一個websocket來啟動聊天會話:
在這個例子中,我意識到chat-api-token 的通知總是會通知給chat-widget iframe 的父級,如果我得到了chat-api-token,我可以使用令牌,然後將我自己的人工Origin-header 添加到API 調用中,因為CORS-header 僅對瀏覽器很重要。這導致了以下進程:
1.創建了一個嵌入聊天小工具iframe 的惡意頁面,添加了一個postMessage-listener 來偵聽chat-api-token。此外,如果在2 秒內沒有獲得api-token,則會觸發重新加載iframe 的事件。這是為了確保我也支持從未發起聊天的受害者,並且由於我可以觸發遠程打開聊天,我首先需要chat-api-token 開始輪詢聊天API 中的數據服務器端。
2.添加了指向惡意頁面的鏈接以打開登錄流程,該流程最終將出現在帶有URL 中帶有令牌的聊天小工具的頁面上:
Recommended Comments