在PayPal中查詢DOM Polyglot XSS的簡單方法

語言: CN / TW / HK

當 DOM XSS 隱藏在數千行程式碼中時,查詢 DOM XSS 可能會很棘手。我們最近開發了 DOM Invader 來幫助解決這個問題,使用組合的動態+手動方法來發現漏洞,並迅速發現了一個影響 PayPal 的有趣的 Polyglot DOM XSS。在這篇文章中,我們將展示如何使用意外指令碼gadget繞過基於允許列表的 CSP。大多數現代網站都使用多個JavaScript庫,並且有很多行復雜的壓縮程式碼,這使得對DOM XSS的測試變得非常令人頭痛,PortSwigger安全研究部門專門開發了DOM Invader,使對DOM XSS的測試更加容易。DOM Invader將為你提供一個方便的樹狀檢視,以此來顯示目標的源和匯(不理解彆著急,這是BurpSuite的一個定義),這極大地簡化了發現DOM XSS的過程。

首先,我們使用 Burp 的嵌入式瀏覽器來導航站點並注入canary以檢視每個頁面上使用了哪些源和接收器。當我們遇到一些有趣的接收器時,我們會使用canary一起傳送諸如 <>'" 之類的字元探測器,並檢查接收器以檢視它們是否被允許。我們沒花多少時間就找到了一個頁面,它以一種不安全的方式反映了我們的探測器。通常這很困難,因為反射是不可見的,但使用DOM Invader就很容易了。

正如你在上面的截圖中看到的,我們的canary被反映在一個 id 屬性中。如果我們傳送一個雙引號,則可以看到值如何到達接收器。但是當傳送雙引號時,螢幕變為空白。但是,如果我們轉義雙引號,則站點不會中斷,我們可以看到它到達接收器:

在 HTML 中,反斜槓對雙引號沒有影響——所以我們似乎有一個 XSS 漏洞。我們需要通過注入其他字元來確認這一點,這將導致 JavaScript 執行。在對這個漏洞進行多次探測後,我們注意到注入的值必須是一個有效的 CSS 選擇器。所以我們想出了以下向量:

由於CSP的原因,這一功能最初並沒有發揮作用,但當我們在Burp中禁用這一功能時,我們收到了警報。然後,我們在HackerOne上向PayPal報告了這一情況,以及禁用CSP的說明。讓我們驚訝的是,我們得到了 HackerOne 人員的迴應:經過審查,您所描述的行為似乎沒有任何安全風險或安全影響。

顯然我們不同意這個評估,於是開始尋找繞過 PayPal 政策的方法。

繞過PayPal上的CSP

首先,我們研究了CSP,並注意到一些薄弱的部分。在script-src指令中,他們允許某些域,例如 *.paypalobjects.com 和 *.paypal.com。它們還包括“unsafe-eval”指令,該指令將允許使用 eval、Function 建構函式和其他 JavaScript 執行接收器:

檢視策略,允許列表和“unsafe-eval”可能是繞過CSP的最佳目標。因此,我們在Burp Suite範圍中添加了這些域。你可以在作用域中使用正則表示式,這非常方便。我們的範圍是這樣的:

Burp允許你在範圍中選擇特定的協議,由於策略具有“block-all-mixed-content”指令,我們只選擇了 HTTPS 協議。

在學習了CSP之後,我們打開了Burp中的嵌入式瀏覽器,開始手動瀏覽網站,這是為了挑選那些擁有大量JavaScript資源的目標。當我們收集了大量的代理歷史記錄後,就可以使用 Burp 出色的搜尋功能來查詢較舊的 JavaScript 庫。Burp允許你只搜尋範圍項,所以我們選中了那個框,這允許我們找到繞過CSP的資產。

我們從搜尋AngularJS開始,因為用它很容易建立CSP繞過。有對 Angular 的引用,但沒有對 AngularJS 的引用但我們嘗試的JavaScript檔案似乎並沒有載入Angular,也沒有引發異常。所以我們轉向Bootstrap,在請求頭和響應體中進行搜尋。出現了幾個 Bootstrap 例項,我們發現了一箇舊版本 (3.4.1)。

接下來,我們研究了 Bootstrap gadget。 GitHub 上存在一些 XSS 問題,但這些影響了 3.4.0 版本。我們查看了Bootstrap程式碼一段時間,尋找jQuery的使用情況,但沒有找到合適的gadget。

我們沒有在資料庫中找gadget,而是想到了 PayPal gadget。如果 PayPal 有一些我們可以利用的不安全 JavaScript ,那豈不是更好。這一次,我們沒有搜尋特定的庫,而是搜尋託管庫的路徑的一部分(例如“/c979c6f780cc5b37d2dc068f15894/js/lib/”)。在搜尋結果中,我們注意到一個名為 youtube.js 的檔案,並立即在其中發現了一個明顯的 DOM XSS 漏洞:

這個檔案使用的是jQuery,所以我們所需要做的就是包含jQuery和youtube.js,利用這個漏洞,然後我們繞過了CSP。看看YouTube .js檔案,我們看到它使用了一個CSS選擇器來找到YouTube播放器元素:

因此,我們需要注入一個帶有“youtube-player”類的元素和一個包含jQuery XSS向量的data-id屬性。一旦我們有了通用PayPal CSP繞過的基礎,要做的就是把它與原始注入結合起來。首先,我們注入了一個帶有 srcdoc 屬性的 iframe。這是因為我們想注入一個外部指令碼,但因為這是一個基於 DOM 的漏洞,指令碼將無法執行。但是有了srcdoc,會發生以下情況:

請注意,我們需要通過轉義雙引號併為選擇器的值部分分配單引號來確保它是一個有效的選擇器。然後再注入指向 jQuery 和 YouTube gadget的指令碼:

請注意,我們必須對向量進行 HTML 編碼,因為我們不希望它以>字元關閉srcdoc屬性。出於同樣的原因,我們避免使用空格。然後我們使用 YouTube gadget注入指令碼,jQuery 會轉換並執行該指令碼。我們再次需要對向量進行 HTML 編碼,給它正確的類名,並使用 data-id 屬性來注入我們的向量。注意,我們使用了一個編碼的單引號來避免屬性中斷。我們必須對雙引號進行HTML編碼,因為srcdoc將解碼HTML,而data-id屬性將在iframe中呈現時進行解碼,因此雙編碼可確保引號在注入 YouTube gadget時存在。最後,我們使用單行註釋進行清理,以確保指令碼在注入後忽略任何內容,即用雙引號和單引號完成 CSS 選擇器。

可以在 此處 找到最終的概念證明。

概念證明

這是 PoC 的截圖:

可以看到對所有 PayPal 的完整 CSP 繞過,但它是必要的嗎?正如我們所見,jQuery是CSP的剋星。它使用“unsafe-eval”指令轉換指令碼,並且很樂意使用策略執行它們。看看原始的XSS漏洞,它似乎是一個jQuery選擇器。因此,我們可以注入一個指令碼,它將被jQuery轉換。所以不需要單獨的 CSP 繞過。因此,我們可以將注入簡化為以下內容:

完整的概念證明請 點此

總結

允許列表策略絕對是不安全的,尤其是當你有大量可能被濫用的指令碼/庫時。即使使用者輸入通常不需要,也要修復XSS,這有助於防止意外的指令碼gadget。

你永遠不應該僅僅依靠 CSP 來保護XSS。 雖然這是你防禦的一部分,但它不是唯一可用的障礙。