在Facebook伺服器上執行遠程代碼
我經常會在一些允許測試並且有漏洞獎勵計劃的大型伺服器上尋找漏洞。這是我的第一篇文章,主要介紹我在Facebook的一個伺服器上發現的一個漏洞。
在掃描一個屬於Facebook(199.201.65.0/24)的IP段時,我發現一個Sentry服務託管在199.201.65.36,主機名是sentryagreements.thefacebook.com。Sentry是一個日誌收集web應用程序,使用Python和Django框架開發。
當我查看應用程序時,一些stacktrace經常莫名其妙的出現在頁面。該應用程序在用戶密碼重置功能上似乎並不穩定,偶爾崩潰。由於Django調試模式沒有關閉,因此在發生stacktrace時會列印整個系統環境。然而,由於Django切斷了stacktrace中的關鍵信息(密碼、秘密、密鑰…),從而避免了大量信息泄漏。
然而,通過仔細觀察stacktrace,我發現一些環境變數鍵值很有意思:
The SESSION_COOKIE_NAME is sentrysid
The SESSION_SERIALIZER is django.contrib.sessions.serializers.PickleSerializer
The SESSION_ENGINE is django.contrib.sessions.backends.signed_cookies
SENTRY_OPTIONS鍵將一些Sentry配置保存在一個列表中。
Pickle是用於(反)序列化Python對象結構(如其中的類和方法)的二進位協議。這裡有一篇比較全面的文章,它解釋了Pickle是什麼及其安全影響,文章地址:https://www.balda.ch/posts/2013/jun/23/pyth-webframeworks-pickle/
如果我們能夠偽造包含任意序列化(pickle)內容的會話,我們就可以在系統上執行命令。可是,在stacktrace中,Django用來簽名會話cookie的SECRET_KEY不可用。不過,SENTRY_OPTIONS列表中一個名為system.secret-key的鍵並沒有被切斷。引用Sentry文檔的內容,system.secret-key是"一個用於會話簽名的秘鑰。如果被盜用,重新生成它是很重要的,否則很容易導致用戶會話劫持。";哇,它看起來像是DjangoSECRET-KEY的重載!
由於我安裝了用任意序列化內容來偽造自己cookie的所有工具,所以我寫了一個小腳本,在我自己的sentrysidcookie中添加了一個payload。代碼如下:
這段代碼簡單證明了一個想法: 它獲取已經存在的sentrysidcookie的內容,並將其替換為一個任意對象,該對象在系統讀取信息的時執行os.system(「sleep 30」)命令 。
當使用這個cookie時,頁面實際上需要額外花費30秒來載入,這就確認了缺陷的存在。
Facebook宣布了這個漏洞,並關閉了系統,直到漏洞得到修復,然後通知我已經安裝了補丁。
這是披露時間表,這也表明Facebook的安全人員響應很及時:
30.07.2018 00:00 CEST : 初步披露每一個細節。
30.07.2018 15:25 CEST : 篩選並停機。
09.08.2018 18:10 CEST : 安裝補丁。
09.08.2018 20:10 CEST :5000美元獎金髮放 –伺服器位於單獨的VLAN中,沒有用戶的具體數據。
感謝你的閱讀!
Blaklis
英文原文:https://blog.scrt.ch/2018/08/24/remote-code-execution-on-a-facebook-server/
譯者:一瞬
※程序員能熬過中年危機?我勸你儘早轉行!
※Web緩存投毒實戰(三)
TAG:Python部落 |