一、引言
最近在鼓搗跨站腳本包含(XSSI)攻擊時,我突然意識到可以通過HTTP狀態碼來玩泄漏信息和跨域。如果你想到的是“XSSI登錄神諭”,那么說明你的已經上道了,但該攻擊還可以擴展到更多的情形中。這里說的登錄神諭通常是根據當前認證狀態來決定加載與否的一些JavaScript文件。然而,這種攻擊還可以針對HTML、JSON、XML或任意的內容類型。這實際上就是為XSSI攻擊開辟了一個新的戰場:從GET參數枚舉信息,一次一位。
對于這種類型的攻擊手法,我至今尚未見過公開的介紹,所以我將盡力使這篇文章盡可能全面。這意味著這篇文章會很長,所以我將其分為幾部分,具體如下所示:
1. 攻擊手法
2. 該攻擊的必要條件
3. 防御措施
4. 進一步探討
5. 小結
為了節約篇幅,本文不會解釋XSSI的基礎知識,這方面的內容,可以參考另一篇文章,地址為https://www.scip.ch/en/?labs.20160414。我認為這是有關這個主題的最佳參考文章。在本文中,我提出了一種注入非腳本內容的新型攻擊手法。針對非腳本內容的更強攻擊手法,上面提到的那篇文章也有相關的解釋,但是與下面將要演示的方法相比,要想實施那些攻擊,它們要求的條件會更加苛刻(編碼和注入技巧)。
二、新型攻擊手法
該攻擊手法的基本思想與XSSI登陸神諭非常類似。攻擊者會嘗試將腳本標簽加載到指向不同來源的頁面。通過onerror、onload和window.onerror函數,攻擊者可以弄清楚跨源服務器如何響應GET請求的信息的。讓我感到吃驚的是,在收到一個非2XX的響應時,會執行onerror函數,否則就會執行onload函數。除非強制實施了嚴格的內容類型限制,否則不管返回的內容類型如何(請參閱下文必要條件1),都是如此。
它的意義何在呢?我們能從200 vs 400響應中了解到什么? 嗯,這取決于端點,以及其他多種可能因素。畢竟,HTTP狀態碼旨在返回信息,并且經常用于返回API的信息。
1.幾個簡單的例子
現在讓我們假設,如果你通過了身份認證,那么/admin目錄就會返回一個200狀態碼和HTML頁面,否則,就會返回一個401狀態碼和HTML錯誤頁面。那么,這不僅可以作為一個登錄神諭,同時還允許進行權限的枚舉。如果每個用戶都有唯一的個人信息頁面(即:/profile/dennis),則惡意站點可以使用類似的攻擊來識別特定用戶,以便進行進一步攻擊,并且不會引起安全響應團隊的警覺。如果一個頁面具有基于GET請求的SQL注入漏洞,但攻擊者卻無法訪問該頁面的話,那么,攻擊者可以誘騙經過身份驗證的用戶訪問處于攻擊者控制之下的頁面,從而間接發動注入攻擊,然后將結果跨域泄漏給攻擊者的JavaScript代碼。
2.一個更有趣的例子
下面,我們將深入考察一個更有趣的例子。假設這里有一個票務系統,它提供了查找客戶信息的搜索字段。如果發送GET到“/search?c=d*”的話,其中“*”字符用作通配符,將返回以字母“d”開頭的所有客戶信息和200狀態碼。如果沒有客戶匹配“d *”模式,則返回500狀態碼。如果攻擊者想要獲得這些用戶信息,但他們無法登錄,那怎么辦?他可以設法讓已經登錄的用戶代為發送請求,并告訴onload函數“是的,我找到了某人”,或告訴onerror函數“搜索沒有返回任何結果”。
這類似于SQL盲注,不同之處在于這里需要借助第三方,同時,這里濫用的是同源策略而非語法。注意,在這里不需要關心票據系統在正文中返回的內容類型。搜索可以返回JSON、XML、HTML甚至一幅圖像,只要沒有返回nosniff頭部,對這個攻擊就沒有影響。同時,URL參數可以包含在腳本src屬性中,這樣攻擊者就可以創建如下所示的腳本了:
這將發送一個GET請求到票務系統上的API“/search?c=a*”。這里,攻擊者只是設置了onload和onerror事件來分別記錄成功和失敗情況:
然后將它附加到DOM對象上面:
如此一來,攻擊者網站的所有訪問者都會自動向票務系統跨域發送GET請求。如果有一個以“a”開頭的客戶,那么端點將返回200,并且onload函數將會被執行。攻擊者的onload處理程序會將另一個腳本加載到DOM中,查詢是否有以“aa”開頭的客戶。如果出現了onerror事件,那說明沒有以字母“a”開頭的客戶,所以攻擊者會將另一個腳本加載到DOM中,檢查是否有以字母“b”開頭的客戶。該腳本將一直使用樹搜索算法進行搜索,直到返回有效的客戶名稱為止。
一旦找到了一個客戶名稱,攻擊者就可以使用相同類型的攻擊來搜索需要客戶名稱的其他API端點,并返回其他的信息, 例如,搜索與客戶相關聯的電子郵件地址的端點。此外,攻擊者還可以搜索匹配“*”模式的客戶。如果此操作失敗,則表示訪問者沒有訪問票務系統的客戶搜索的相應權限,所以也就無需發送其他請求了。由于竊取信息的請求是由攻擊者站點的訪問者發出的,所以攻擊可以讓所有訪問者并行發送請求。如果將這些攻擊手法與社會工程電子郵件結合一起,甚至可以從內部引發票務系統信息泄漏事件。
所以,這種攻擊不是很牽強,也不需要特殊的條件。
三、攻擊的必要條件
簡單來說,需要具備以下條件:
1. 不返回'X-Content-Type-Options:nosniff'HTTP頭部,除非內容類型是JavaScript。
2. 端點必須響應GET請求。
3. 端點的狀態碼:200類型響應表示成功,非200類型響應表示失敗。
4. 該信息不可公開獲取。
最重要的是,這里除了第一個條件中的JavaScript之外,根本沒有提及內容類型。也就是說,這種攻擊適用于XML、JSON、圖像或任何其他內容。有關該攻擊的必要條件的更多詳細信息,請參閱防御措施部分。對于滲透測試人員來說,也應該閱讀這一節,因為它對某些技巧進行了更加深入的解釋。
四、防御措施
要想防御這種攻擊,你只需要設法讓上面的任意一個必要條件達不到要求就行了。下面,讓我們從防御角度來深入討論這些必要條件。
必要條件1
如果網站返回“X-Content-Type-Options:nosniff”HTTP頭部的話,那么該攻擊就會偃旗息鼓了。所以,最簡單的防御措施,就是讓它返回這個頭部。服務器可以通過nosniff頭部告訴瀏覽器,“當我說將給你時,就意味著這是真的!”。
為什么這個方法能奏效?這是因為,任意類型的文件都可以通過HTTP提供,但是,Web開發人員卻并不總是正確地聲明相應的文件類型。因此,當瀏覽器請求JavaScript文件時,內容類型頭部可能會說它實際上是HTML。因此,瀏覽器就會拋出錯誤消息,直到它嘗試將文件解析為JavaScript為止。此時,由于onload函數已經執行,所以任何解析錯誤都將調用window.onerror函數。如果內容類型未正確聲明,nosniff頭部的存在就意味著onerror將立即被調用。總是調用onerror就意味著沒有發現差異和沒有信息損失。如果內容類型是JavaScript,那么nosniff就沒有幫助,所以你照樣可以發起XSSI攻擊。
注意:這只適用于支持nosniff頭部的瀏覽器。IE和Chrome是第一批支持此頭部的瀏覽器。Firefox也聲明將要提供相應的支持,具體時間我還不清楚,但我發現Firefox 50已經支持nosniff頭部,但是Firefox 45.5仍然沒有提供相應的支持。我假設Edge跟IE一樣,但我沒有親自測試它們。
必要條件2
腳本標簽只能用于GET請求。因此,如果端點只接受POST請求,則此攻擊就無能為力了。這個要求看似簡單,但務必要小心。您可能已經設計了只接收POST請求的API,但您的內容管理系統也許仍然可以接收GET請求.。
必要條件3
如果端點始終返回200,那么也就無法從狀態碼中竊取信息了。但是,狀態碼的存在,是自有其存在的理由的! 不要僅僅為了阻止這種攻擊而簡單粗暴地廢棄了HTTP協議的核心部分。請改用nosniff頭部來阻止該攻擊。
雖然固定的HTTP狀態碼可以阻止這里描述的這種攻擊,但是卻無法防御其他攻擊。例如,頂層的JSON數組就可以解析為JavaScript,盡管頂層的JSON對象無法解析為JavaScript。因此,即使您的端點始終返回200狀態碼,照樣可以創建window.onerror函數,然后根據是否存在解析錯誤來收集信息。只要把Content-Type頭部設置為JSON,利用nosniff頭就能阻止這種攻擊。
必要條件4
如果攻擊者能夠在自己的瀏覽器中加載私密信息,那么他就不需要這種攻擊了。該攻擊主要是設法讓用戶訪問攻擊者的域,然后以用戶在其他域的權限來獲取更多信息,這通常要求用戶已經經過了相應的認證。除此之外,如果您的家庭路由器有此漏洞,那么惡意公共站點可以通過它請求腳本,從而導致信息泄漏。
五、進一步探討
3XX狀態碼
雖然本文沒太關注打開重定向和3XX響應,但是它們可能進一步擴展該攻擊。到目前為止,重定向到2XX的行為好像跟2XX類似,而重定向到非2XX的行為與非2XX的行為類似。這意味著如果發現打開的重定向,通過檢查referer頭保護自己的端點,如果啟用了重定向的話,就可能會被繞過。這也是一個很好的思路。
其他標簽
我相信,指向跨域的img標簽的行為跟script標簽的行為類似。也許在img和script標簽中加載資源可能會由于解析差異而導致更多的信息泄露。此外,CSS也值得進一步仔細研究。
其他屬性
我希望Subresource Integrity會導致進一步的信息泄漏,但它卻明智地要求應用CORS了。如果你可以繞過CORS,那么這種攻擊將會大放異彩。
我花了大量時間來測試通過onload,onerror和window.onerror獲取信息的方法,其實,我們還可以考察其他諸多的屬性,因為這可能會發現其他攻擊方法,或通過每個請求獲取更多的信息。
六、結束語
在加載跨域資源的時候,任何可檢測的差異都能提供寶貴的信息。這些信息可能與登錄神諭一樣微不足道,但也可能與證書一樣造成嚴重的信息泄露(雖然不太可能)。
防御方:內容類型的分歧是各種攻擊的常見手段。使用HTTP頭部nosniff嚴格限制內容類型能夠減輕這種攻擊和其他攻擊。這樣做的另外一個好處是, 對不當的響應將產生顯眼的錯誤提示,便于人們進行相應的修復工作。
攻擊方:人們對于同源策略的理解還不是非常深入,這使它成為bug的一個重要來源。一定要注意查找GET請求中返回的敏感信息,然后看看通過script標簽跨域請求信息時,是否可以檢測到任何行為的差異。
上一篇:Skype如何使用?
下一篇:網站域名被劫持的解決方法
掃一掃 加微信咨詢