在這篇文章中,我們詳細(xì)講述一個在Facebook 上發(fā)現(xiàn)的服務(wù)器安全漏洞,這個漏洞可能會影響數(shù)百萬CORS(跨域資源共享)中Origin頭允許“NULL”值的網(wǎng)站,該漏洞會威脅用戶的隱私,惡意實體可以不受限的訪問網(wǎng)站。被稱為“Originull”的攻擊方法,允許黑客訪問和瀏覽到所有經(jīng)過Facebook Messenger發(fā)送的私人聊天記錄、照片、和其他附加信息。這個安全問題是由Ysrael Gurt研究團隊發(fā)現(xiàn)的,目前已經(jīng)通知了Facebook。
“非技術(shù)性”的解釋
這個漏洞是一個跨域權(quán)限繞過攻擊漏洞,允許黑客利用外部網(wǎng)站訪問和讀取到用戶的Facebook 私人消息。通常,瀏覽器會保護Messenger用戶,只會讓Facebook 頁面訪問到這些信息,但是,F(xiàn)acebook 為了使它的子網(wǎng)站能訪問到Messenger的信息,它打開了一座能讓子網(wǎng)站訪問到信息的“橋”。如果惡意程序能成功利用Facebook 管理的子網(wǎng)站的身份,就有可能訪問到Messenger的私人聊天記錄。
例如,如果一個用戶打開了一個黑客的惡意鏈接,這個黑客就有可能看到所有Messenger用戶來往的聊天記錄、照片、和其他信息。
Image 1: The chat appears on the BugSec website. The user ID is shown to the lef
“技術(shù)性”的解釋
這是對以上問題更深層次的研究。Facebook Messenger聊天記錄的管理是在一個子域名下,地址是:{number}-edge-chat.facebook.com,而聊天本身是運行在www.facebook.com域名上。
客戶端javaScript和服務(wù)器的通信通過XML HTTP Request(XHR)。
javaScript為了訪問到來自5-edge-chat.facebook.com的數(shù)據(jù),F(xiàn)acebook 必須在調(diào)用者的HTTP頭增加“Access-Control-Allow-Origin”值,且“Access-Control-Allow-Credentials” 的值為“true”,只有這樣,數(shù)據(jù)才能被訪問(需要cookies)。
Image 2:The original request
到目前為止,這看起來好像是一個正常的跨域資源共享進(jìn)程。同時為了阻止其他非法的網(wǎng)站訪問這些數(shù)據(jù),F(xiàn)acebook對訪問的請求頭會做檢查。如果請求來自一個沒有認(rèn)證的源,服務(wù)器會返回帶有“x-fb-chat-failure-reason”頭的請求錯誤(HTTP 400)信息。
Image 3: Request from a different origin
但是!但是!但是!:Facebook也允許正常GET請求訪問聊天域名。但正常GET請求不帶有XHR的控制標(biāo)識頭。XHR控制標(biāo)識頭比較特殊,只有使用XHR請求的瀏覽器對會發(fā)送。
當(dāng)服務(wù)器收到GET請求時,它沒有包括CORS的“origin”頭。在很多開發(fā)語言中,不存在的頭標(biāo)識會被解釋成“NULL”值,如果Facebook會接受“origin”頭為“NULL”值的話,它就不會阻止來自這個源的請求。
最有可能的是,過濾機制和響應(yīng)機制是分開的,響應(yīng)者假設(shè)“origin”頭的值是允許的,因為如果沒有允許,過濾器肯定已經(jīng)阻止了這個請求。這種開發(fā)設(shè)計允許Facebook添加一個新的授權(quán)訪問源,只需要在一個位置修改一下代碼。
總之,“origin”值為”NULL”的GET請求繞過了過濾檢查。響應(yīng)者接受了請求頭中的”NULL”值,并且在響應(yīng)頭中的“Access-Control-Allow-Origin”值中呈現(xiàn)了出來。
Image 4: Request without origin.
到此,已經(jīng)清楚了,我們發(fā)了一個origin為“NULL”的請求,返回頭中帶有“Access-Control-Allow-Origin”標(biāo)識,且為”NULL”值。
首先,我們用“burp”來檢驗這個結(jié)果,當(dāng)我們發(fā)送了“NULL”的請求時,在Facebook的返回信息得到了驗證。
Image 5: Request with “null” origin
在這次測試中,我們也發(fā)現(xiàn)了在發(fā)送origin為“NULL”的請求時,“data URI scheme”可以被使用,(data URI scheme 允許我們使用內(nèi)聯(lián)的方式在網(wǎng)頁中包含數(shù)據(jù),目的是將一些小的數(shù)據(jù),直接嵌入到網(wǎng)頁中,從而不用再從外部文件載入)。當(dāng)使用這功能時,瀏覽器為安全目的,會將origin值默認(rèn)設(shè)置為“NULL”。
Image 6: The example code.
Image 7: The final HTML
Image 8: The HTML in Firefox.
Image 9: The HTML in Chrome
因此,基于實際測試,我們知道了Facebook的處理方法,我們對Messenger聊天用戶,可以進(jìn)行有效攻擊了。
Facebook聊天API
Facebood會向服務(wù)器發(fā)送連續(xù)的XHR請求,用來獲取新的消息。當(dāng)收到一個消息或超時,服務(wù)器會發(fā)出響應(yīng)。這種方式意味著總會總有一個XHR請求,在等待服務(wù)器的返回。當(dāng)一個服務(wù)器返回一個請求時,JavaScripy代碼給服務(wù)器又會發(fā)送一個新的請求。
Image 10: Server response at timeout.
Image 11: Server response for a new message.
為了確保消息以正確的順序到達(dá),每個請求都有一個序列號(返回的“序列”和請求是對應(yīng)的)。也就是說每一個請求所用到的參數(shù)可以從返回值中得到。
基于以上研究,我們編寫了下面的代碼,這個代碼會和Facebook API進(jìn)行通信,并竊取到用戶的消息、顯示在頁面上,并發(fā)送到BugSec服務(wù)器上。如下:
并將這個代碼轉(zhuǎn)換成Base64字符串,用data URI scheme的方式插入到元素標(biāo)簽中。
當(dāng)受害人點擊了惡意網(wǎng)頁(為什么需要用戶點擊,因為需要COOKIES),代碼開始監(jiān)聽他的Facebook Messenger聊天,并將聊天記錄發(fā)送到bugsec服務(wù)器。
通過Facebook的漏洞獎勵計劃,這個漏洞已經(jīng)報告給了Facebook,他們反應(yīng)很快,幾天前已經(jīng)對這個漏洞進(jìn)行了修補。
來源:安全客