瘋了!Spring 驚爆大漏洞。。。
繼 Log4j 2 之后,聽聞 Java 再次遭到漏洞攻擊,這一次,似乎情況也更為嚴重,因為受到影響的是 Java 平臺的開源全棧應用程序框架和控制反轉容器實現——Spring 家族,而且網傳漏洞還不止一個。
一直以來,Spring 是編程開發的必選技術之一,此前一位名為 Bogdan N. 的全棧開發者甚至評價道:“學習 Java、學習 Spring 框架,你永遠都不會失業。”
可想而知,如果 Spring 城門失火,Java 必定遭殃。不過,Spring RCE 漏洞在網絡上炒了兩天,雖然有不少安全圈人員紛紛發圈,但更多的還是表示了只是聽聞,這也不禁讓人質疑,是真有漏洞,還是虛驚一場?
接下來,本文將盤點一下近期 Spring 的“大”漏洞。
1、第一個:真的 Spring Cloud Function SPEL RCE
3 月 26 日,據網絡安全網站 Cyber Kendra 報道,Spring Cloud Function 官方測試用例曝光了 Spring Cloud Function SPEL(Spring Expression Language)表達式注入漏洞,黑客可利用該漏洞注入 SPEL 表達式來觸發遠程命令執行。

漏洞發現過程
起初,研究人員在分析 Spring Cloud 函數的 main 分支(https://github.com/spring-cloud/spring-cloud-function/commit/dc5128b80c6c04232a081458f637c81a64fa9b52)時,發現有開發者向其中添加了 SimpleEvaluationContext 類。還使用了 isViaHeadervariable 作為標志,在解析 spring.cloud.function.routing-expression 之前判斷的值取自 HTTP header。
spring.cloud.function.routing-expression 的參數存在于訪問 Spring Cloud Function 的 HTTP 請求頭中,其 SpEL 表達式可以通過 StandardEvaluationContext 注入并執行。這使得攻擊者可以利用這個漏洞進行遠程命令執行。
Spring Cloud Function 的應用
當前,Spring Cloud Function 被許多科技巨頭應用于產品中,包括 AWS Lambda、Azure、Google Cloud Functions、Apache OpenWhisk 以及許多 Serverless 服務提供商。
根據官方文檔,Spring Cloud Function 是基于 Spring Boot 的函數計算框架,它可以:
- 通過函數促進業務邏輯的實現。
- 將業務邏輯的開發生命周期與任何特定的運行時目標分離,以便使用相同的代碼可以作為 Web 端點、流處理器或任務運行。
- 支持跨 Serverless 提供商的統一編程模型,具備獨立運行(本地或在 PaaS 中)的能力。
- 在 Serverless 上提供程序上啟用 Spring Boot 功能(自動配置、依賴注入、指標)。
簡而言之,Spring Cloud Function 通過抽象傳輸細節和基礎設施,為開發者保留熟悉的開發工具和開發流程,讓開發者專注于實現業務邏輯,從而提高開發效率。
影響
目前,Spring Cloud Function SPEL 漏洞已被歸類為嚴重等級,CVSS(通用安全漏洞評分系統) 得分為 9.0(滿分 10)。
不過,開發者也無須太過擔心,因為只有 Spring Cloud Function 的某些版本特定配置(3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2)的動態路由受到影響,受影響的版本發布時間在 2019 年 11 月 22 日至 2022 年 2 月 17 日。
此外,官方也針對漏洞發布修復補丁:https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f
以及發布了最新的 3.1.7 和 3.2.3 版本:https://github.com/spring-cloud/spring-cloud-function/tags
2、第二個:網傳比 Spring Cloud Function RCE 更為嚴重的 Spring RCE
相比前者,3 月 29 日晚間,有不少網友爆料的 Spring RCE 漏洞,讓開發者圈中人心惶惶。
不過有些不同尋常的是,這個漏洞目前并沒有像 Log4j2 事件那樣引起的圈內諸多企業大廠的緊急行動,也不像 Spring Cloud Function SPEL 漏洞那樣有官方說明,甚至連國外披露漏洞的根源也是來自 QQ 和國內部分網絡安全網站。

這也讓不少網友猜測,該漏洞應該是國內某個安全機構、安全人員最先發現的。這不,有網友將該漏洞發布到了 GitHub 上(目前已刪除,但有網友將該頁面保存了下來):

來源:https://archive.ph/DIbrv
根據網傳的內容顯示:
Spring 框架出現的 RCE 0day 漏洞影響的范圍為 JDK 版本號在 9 及以上的、使用了 Spring 框架或衍生框架。

目前,隨著該網傳漏洞的暗流涌動,國外不少網絡安全研究人員和安全公司也發布 Twitter 表示這一漏洞的存在:

他們也將該漏洞稱之為 Spring4Shell,猜測是由傳遞參數的不安全反序列化引起的。
3、Spring 零日漏洞真的存在?
針對網傳的內容,全球領先的安全風險信息解決方案提供商 Rapid7 通過《Spring4Shell: Zero-Day Vulnerability in Spring Framework》一文也對外確認零日漏洞是真實存在的。

其在文章中表示,該漏洞似乎影響了使用 @RequestMapping 注解和 POJO(Plain Old Java Object)參數的函數。與此同時,Rapid7 還通過 Springframework MVC 進行了演示(https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/):

這里有一個控制器 ( HelloWorldController),當它被加載到 Tomcat 中時,它將為 http://name/appname/rapid7 中處理 HTTP 請求。處理請求的函數被稱之為 vulnerable,而且還有一個 POJO 參數 HelloWorld。在這里,HelloWorld 被簡化了,但如果需要,POJO 可能會變得非常復雜:

基于此,Rapid7 表示,“如果我們編譯該項目,并將其托管在 Tomcat 上,我們就可以用下面的 curl 命令來利用它。請注意,下面使用的有效載荷與研究人員創建的原始概念證明所使用的完全相同。”

這個有效載荷在 Tomcat ROOT 目錄下投放了一個受密碼保護的 webshell,名為 tomcatwar.jsp,它看起來像這樣:

然后,攻擊者可以調用命令。下面是一個執行 whoami 以獲得 albinolobster 的例子:

通過測試,Rapid7 發現在 OpenJDK 1.8.0_312 上的測試失敗了,但 OpenJDK 11.0.14.1 有作用。
4、臨時修復方案
目前由于 Spring 官方尚未發布最新說明,無法確定哪些應用程序使用了有漏洞的功能,這也導致但凡和 Spring 沾點關系的功能,開發者都要問上一句「是否涉及 Spring Core 的 RCE 0day 漏洞」。


不過,據外媒 BleepingComputer 報道,這個漏洞雖然會影響到 JDK 版本號在 9 及以上的、使用了 Spring 框架或衍生框架,但是也有特定的前提條件。
同時,也有不少網友調侃道:
別慌,雖然現在 Java 已經到了 Java 18 版本,但是很多企業仍然停留在 Java 8 版本及以下。

不同的安全漏洞,也讓 Java 工程師產生了嚴重的心理陰影:

對于開發者、企業而言,當前也不用自亂陣腳,不過,為了避免一定的風險,可以做的就是先排查一下自己的 JDK 版本以使用 Spring 框架或衍生框架 的情況,如果版本在 JDK 8 及以下,則不受漏洞的影響。
此外,根據 rapid 7、國內的北京大學計算中心等渠道給出的臨時修復方案,大家也可以嘗試一波:
- 在應用中全局搜索@InitBinder 注解,看看方法體內是否調用dataBinder.setDisallowedFields 方法,如果發現此代碼片段的引入,則在原來的黑名單中,添加 {"class.*", "Class. *", "*. class.*", "*.Class.*"}。
- 注:如果此代碼片段使用較多,需要每個地方都追加。
- 在應用系統的項目包下新建以下全局類,并保證這個類被Spring 加載(推薦在Controller 所在的包中添加)。完成類添加后需對項目進行重新編譯打包和功能驗證測試,并重新發布項目。
import org.springframework.core.annotation.Order;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.InitBinder;@ControllerAdvice@Order(10000)public class GlobalControllerAdvice{@InitBinderpublic void setAllowedFields(webdataBinder dataBinder){String[]abd=new string[]{"class.*","Class.*","*.class.*","*.Class.*"};dataBinder.setDisallowedFields(abd);}}
最后,靜待官方消息。
參考資料:
https://www.cyberkendra.com/2022/03/rce-0-day-exploit-found-in-spring-cloud.html
https://its.pku.edu.cn/announce/tz20220330110501.jsp
https://github.com/spring-projects/spring-framework/commit/7f7fb58dd0dae86d22268a4b59ac7c72a6c22529
https://www.bleepingcomputer.com/news/security/new-spring-java-framework-zero-day-allows-remote-code-execution/
https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framewor