看我如何發現Facebook的$5000美金漏洞
最近,我在參與一些漏洞眾測項目,本文中我就來分享一個我發現的Facebook某伺服器漏洞,該漏洞獲得Facebook官方$5000美金獎勵。
端倪
在我前期對Facebook網段199.201.65.0/24進行探測時發現,其中在IP 199.201.65.36 上部署有Sentry服務,其主機名為sentryagreements.thefacebook.com。Sentry是基於Python語言和Django架構的,一種Web形式的日誌收集應用。
發現
在對該Web應用進行分析過程中,頁面上經常有一些莫名其妙的堆棧跟蹤行為(stacktrace)跳出來。並且其用戶密碼重置功能貌似非常不穩定,老是會崩潰。如果在不關閉Django調試模式的情況下,當發生堆棧跟蹤行為時,頁面上就會列印顯示出整個運行環境,好在其中不包括密碼、密鑰或key等敏感信息。
但是,在認真查看堆棧跟蹤方法時,一些環境變數值看似很有意思,比如:
SESSION_COOKIE_NAME的名稱是sentrysid
SESSION_SERIALIZER對應的調用方法是django.contrib.sessions.serializers.PickleSerializer
SESSION_ENGINE對應的調用方法是django.contrib.sessions.backends.signed_cookies
SENTRY_OPTIONS值中包含了一個Sentry服務的配置信息列表
在Python中,Pickle模塊是對Python對象結構進行二進位序列化和反序列化的協議實現,就是把Python數據變成流的形式,就像其中的類和方法一樣。可以查看此文,了解Pickle的運行機制和安全實現。
假設一下,如果我們可以偽造包含任意Pickle內容的會話,那麼就能在系統中間接執行命令了。但是,Django框架中用來驗證會話cookie的SECRET_KEY,在堆棧跟蹤行為中是不存在的。咦,怎麼在SENTRY_OPTIONS中的Sentry配置信息列表中包含了一個名為system.secret-key的鍵值!這個鍵值是未被Django框架過濾掉的。
然後,我又把Sentry 應用的說明文檔翻了一遍,發現system.secret-key是」一個用於會話驗證的安全密鑰,如果該密鑰受到破壞或竊取,則需要對它重新生成,否則用戶會話存在被劫持的可能。哇,如果這樣,那是不是存在Django的SECRET-KEY重寫漏洞了呢?
漏洞測試
由於要偽造包含任意Pickle內容的會話,所以我寫了一個小腳本,用來向我的sentrysid cookie中添加了一個Payload執行載荷。
這就是一個簡單的PoC代碼,它首先會獲取當前的sentrysid cookie,然後在反序列化時,用任意對象內容以os.system(「sleep 30」) 掛起方法來把sentrysid cookie進行替換。
當系統使用了這個被替換的sentrysid cookie之後,頁面實際上會增加30秒的延遲響應。當然,如果會出現這種情況,也就證明漏洞的存在。
最終,Facebook承認了該漏洞的有效性,之後,把這個sentryagreements.thefacebook.com系統下線,並告知我漏洞補丁已經在著手開發。
漏洞上報進程
2018.7.30 00:00 漏洞初報
2018.7.30 15:25 Facebook進行漏洞分類並將Sentry服務系統下線
2018.8.9 18:10 補丁修復
2018.8.9 20:10 Facebook向我獎勵了$5000美金,並告知我這個Sentry伺服器位於一個單獨的VLAN中,其中未包含特定的用戶數據。
*參考來源:
scrt,clouds編譯,轉載請註明來自FreeBuf.COM
※FB精品公開課 | 實戰白帽傾囊相授,滲透測試入門指南
※伺服器入侵溯源小技巧整理
TAG:FreeBuf |