【安全漏洞】Emissary 的SSRF漏洞(CVE-2021-32639)发现过程
導語:通過在Emissary項目上運行標準的CodeQL查詢集,我發現了之前報告的任意文件泄露(CVE-2021-32093)。
通過在Emissary項目上運行標準的CodeQL查詢集,我發現了之前報告的任意文件泄露(CVE-2021-32093),但也發現了新的漏洞:
不安全的反序列化漏洞 (CVE-2021-32634);
服務器端請求偽造漏洞(CVE-2021-32639);
原始代碼注入CVE (CVE-2021-32096)是由社區貢獻的CodeQL查詢標記的;
到目前為止,還可以通過默認的CodeQL查詢發現反映的跨站點腳本漏洞(CVE-2021-32092)。
代碼注入 (CVE-2021-32096)
起初我嘗試在Emissary 5.9.0代碼庫上使用CodeQL腳本注入查詢時,卻沒有得到任何結果。
在閱讀源代碼獲取漏洞細節后,我確信我的查詢正確地建模了javax.script.ScriptEngine.eval()接收,并且該源代碼已經由默認的CodeQL JAX-RS庫建模。然而,我意識到從不受信任的數據到腳本注入接收器的流不是“直接的”流。你可以通過查看代碼流的方式來理解其原因。
用戶數據進入應用程序的 JAX-RS 終端是:
getOrCreateConsole(request) 將調用 RubyConsole.getConsole() ,它會轉到:
此代碼啟動一個運行 RubyConsole.run() 方法的新線程(因為它實現了 Java Runnable 接口):
但是,由于此時 stringToEval 為 null,因此該方法幾乎會立即使用 wait() 方法暫停線程。
稍后,在 rubyConsolePost 中,我們可以找到以下代碼:
這里是不受信任數據(request.getParameter(CONSOLE_COMMAND_STRING))進入應用程序并流入RubyConsole.evalAndWait()方法的地方。但是,evalAndWait()方法是:
沒有對RubyConsole.eval()方法的實際調用,Ruby腳本在該方法中被計算,因此如果跟蹤受感染的請求參數,你將在該方法中結束并到達受感染的跟蹤的末尾。用戶控制的命令只被分配給stringToEval字段,這似乎就到此為止了。然而,如果你仔細觀察,你還會看到這個方法正在調用notifyAll()方法,這意味著這個方法將有效地激活被暫停的線程,該線程將依次運行以下表達式:
當rubyConsolePost方法被調用時,RubyConsole.run()會以一個null stringToEval執行,然后進入wait狀態。
當調用 evalAndWait(commandString) 時,stringToEval 獲取用戶控制的腳本,然后恢復 RubyConsole.run() 方法,該方法將評估現在分配的 stringToEval。
因此,沒有靜態代碼分析工具可以有效跟蹤的直接數據流。不過,通過使用CodeQL感染步驟對Javawait/notify模式建模,我應該能夠發現這個漏洞。
在此代碼模式中,你可以看到兩種不同類型的塊:調用notify的同步塊和調用wait的同步塊。當同步發生在同一個對象上時,我想將notify塊中的寫入與wait塊上相同字段的讀取連接起來。這意味著我需要一個額外的污點步驟來連接這些原本斷開連接的節點,以便 CodeQL 的污點跟蹤可以橋接這種邏輯斷開連接:
啟用這個額外的感染步驟后,我成功地報告了這個漏洞:
令人驚嘆的是,這個查詢不是由GitHub CodeQL工程師開發的,而是由幾個CodeQL社區成員貢獻和改進的:
https://github.com/github/codeql/pull/2850;
https://github.com/github/codeql/pull/5349;
https://github.com/github/codeql/pull/5802;
這個社區貢獻的查詢正在進入標準查詢集,并將很快提供給所有運行 GitHub 代碼掃描的開源項目。
我還向 CodeQL 存儲庫貢獻了我的notify/wait模式感染步驟,這可能很快就會為所有 CodeQL 用戶啟用同步字段之間的類似數據流分析!
任意文件泄露 (CVE-2021-32093)
CodeQL 發現了默認配置下的任意文件泄露,因此我不會評論此漏洞的詳細信息,因為它已經在 SonarSource文章中進行了描述。
不安全的反序列化 (CVE-2021-32634)
CodeQL 默認查詢還報告了三個不安全的反序列化操作。
第一個位于 WorkSpaceClientEnqueueAction REST 終端:
可以通過對 /WorkSpaceClientEnqueue.action 的經過身份驗證的 POST 請求訪問此終端。正如你在源代碼中所讀到的,表單參數 WorkSpaceAdapterWORK_BUNDLE_OBJ (tpObj) 在第 52 行被解碼和反序列化。
幸運的是,這是一個身份驗證后的漏洞,由于SonarSource報告修復了跨站請求偽造(CSRF)漏洞,因此無法通過CSRF代表已登錄用戶利用該漏洞。
CodeQL 還報告了另外兩個當前未在代碼中執行的不安全反序列化操作。然而,它們可能會在未來的版本中啟用。
第一個起源于MoveToAction類,它沒有被Jersey服務器公開。
MoveToAction:
MoveToAdapter:
PayloadUtil:
第二個方法來源于WorkSpaceAdapter類的inboundEnque方法。該漏洞需要調用inboundEnque(),但目前尚未執行該調用。
WorkspaceAdapter:
WorkspaceAdapter:
WorkspaceAdapter:
服務器端請求偽造 (CVE-2021-32639)
在CodeQL中發現這個漏洞得益于另一個社區的貢獻。報告此漏洞的查詢最初是由@lucha-bc和@porcupineyhair貢獻的,并且已經被提升為任何CodeQL掃描使用的默認規則集。
該查詢報告了兩個服務器端請求偽造 (SSRF) 漏洞。第一個影響 RegisterPeerAction REST 終端。例如,以下請求將導致多個請求發送到位于 http://attacker:9999 的攻擊者控制的服務器。
需要注意的重要一點是,一些偽造的請求是發送到 /emissary/Heartbeat.action 終端的未經身份驗證的請求:
但是,也有經過身份驗證的請求發送到攻擊者控制的服務器上的 /emissary/RegisterPeer.action 終端:
SSRF 漏洞通常用于訪問內部服務器或掃描內部網絡,但在這種情況下,我想到了不同的漏洞利用場景。由于 SSRF 漏洞導致 Emissary 使用的 Apache HTTP 客戶端發送一個帶有摘要身份驗證標頭的經過身份驗證的請求,因此從理論上講,我可以誘使客戶端切換到基本身份驗證,從而泄漏服務器憑證。
要使用 Apache HTTP 客戶端發送經過身份驗證的請求,需要在憑據提供程序上設置憑據,然后配置 HTTP 客戶端以使用該憑據提供程序:
可以看到憑據是從 Jetty 用戶領域讀取的,用于連接到需要憑據的任何主機和任何端口。這些憑證在憑證提供程序 (CRED_PROV) 中設置,該提供程序后來被配置為主要 Emissary 客戶端 (CLIENT) 的默認憑證提供程序。
配置沒有指定應該使用什么身份驗證方案,這讓我相信身份驗證方案是根據服務器響應決定的。如果我禮貌地要求客戶端使用基本身份驗證,那么所有跡象都表明服務器憑據可能會以明文形式(base64 編碼)發送。
為此,我設置了一個請求基本身份驗證的 Web 服務器,然后使用 SSRF 漏洞使 Emissary 服務器連接到我的惡意服務器。 Emissary HTTP客戶端很高興地從摘要身份驗證切換到基本身份驗證,并將憑據發送給我。以下是我的服務器顯示服務器憑證的輸出:
同樣,AddChildDirectoryAction 終端也容易受到 SSRF 的攻擊。對 /AddChildDirectory.action 終端的 POST 請求將觸發對攻擊者控制的主機的額外請求:
除了修復 SSRF 漏洞之外,NSA還通過只允許摘要身份驗證方案來防止身份驗證方法的混淆。
反射的跨站點腳本 (CVE-2021-32092)
CodeQL在自動查找SonarSource研究人員報告的大多數漏洞和幾個新的關鍵漏洞方面做得很好,但是它沒有報告SonarSource研究人員最初報告的跨站腳本(XSS)漏洞。我檢查了查詢集,發現沒有針對這個特定XSS實例的查詢。
然后我開始與 CodeQL 團隊合作,對 JAX-RS 終端上的 XSS 漏洞進行相當全面的分析。這個 XSS 檢測現在也包含在主 CodeQL 存儲庫中!
在 REST 終端上準確檢測 XSS 并不是一項簡單的任務,因為它們中的大多數將默認為 application/json 響應內容類型,這對 XSS 是安全的。因此,我需要 CodeQL 來檢測用戶控制的數據(無論是反射的還是持久的)在沒有正確編碼的 HTTP 響應中使用,而且還需要檢測此類響應的內容類型已更改為任何 XSS 友好類型。這可以通過以下幾種方式實現:
通過使用 ResponseBuilder.type() 顯式設置響應內容類型;
通過使用 @Produces 注釋來注釋封閉方法;
通過使用 @Produces 注釋來注釋封閉類;
在與 CodeQL 團隊一起進行這些查詢改進時,我意識到我們對 Spring REST 終端的 XSS 查詢也沒有考慮響應內容類型,這可能導致許多誤報,例如,帶有應用程序/json內容類型的響應被標記為可利用的。因此,我們還實現了所需的改進,以使Spring XSS查詢達到JAX-RS現在擁有精確度。
【安全學習資料】
總結
以上是生活随笔為你收集整理的【安全漏洞】Emissary 的SSRF漏洞(CVE-2021-32639)发现过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学了网络安全以后能做哪些岗位呢?来来来,
- 下一篇: 渗透操作系统——【靶场实战训练营】快来看