當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。 雖然這是你防禦的一部分,但它不是唯一可用的障礙。
Recommended Comments