Spring Cloud Function SpEL表達式命令注入(CVE-2022-22963)漏洞復現及分析


漏洞概述

SpringCloud 是一套分布式系統的解決方案,常見的還有阿里巴巴的Dubbo,Fass(Function As A Service )的底層實現就是函數式編程,在視頻轉碼、音視頻轉換、數據倉庫ETL等與狀態相關度低的領域運用的比較多。開發者無需關注服務器環境運維等問題上,專注於自身業務邏輯實現即可。

SpringCloud Function 就是Spring提供的分布式函數式編程組件。

漏洞復現

使用了github上已有的環境https://github.com/cckuailong/spring-cloud-function-SpEL-RCE
clone到本地后需要修改版本到java17


修改后build項目,訪問8080端口
spring.cloud.function.routing-expression頭中包含的SpEL表達式將會被執行

漏洞分析

通過diff可以發現開發者使用了SimpleEvaluationContext進行SPEL解析,而在此前版本中使用StandardEvaluationContext。
https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f

SpEL表達式

http://itmyhome.com/spring/expressions.html
Spring表達式語言(簡稱SpEl)是一個支持查詢和操作運行時對象導航圖功能的強大的表達式語言. 它的語法類似於傳統EL,但提供額外的功能,最出色的就是函數調用和簡單字符串的模板函數。

SpEL可以字符串之間進行嵌套也可以單獨使用,嵌套時使用#{}(實現ParserContext接口)。

functionRouter

如果設置為functionRouter則默認路由綁定的具體函數交由用戶進行控制,在 Spring Cloud Function Web里面,可以通過設置http頭的方式來控制,使用spring.cloud.function.definitionspring.cloud.function.routing-expression 都可以,區別是后者允許使用Spring表達式語言(SpEL)。

比如我用spring.cloud.function.definition或者用路由去訪問響應具體函數效果是一樣的

流程分析

SpringCloud Function之所以能自動將函數建立http端點,是因為在包mvc.FunctionController中使用/** 監聽了get/post類型的所有端點。

當一個請求進入時,程序首先基於Springboot的自動配置,將配置文件注入到functionProperties,隨后將以“WebRequestConstants.handler”為key,function為值添加到request數組里面。

然后進入FunctionController,Controller首先會將請求使用wrapper進行包裝,wrapper就是將request轉成FunctionInvocationWrapper 格式。

其中functionDefiniton=”functionRouter”,經過判斷是否是RoutingFunction,然后執行function.apply

if (function.isRoutingFunction()) {
	function.setSkipOutputConversion(true);
}

然后在apply里會進入doapply,輸入為input包含header里的所有信息

在route方法里獲取spring.cloud.function.definitionspring.cloud.function.routing-expression的值判斷是否為空,然后進入else if分支,將值傳給functionFromExpression

然后這里會使用標准的StandardEvaluationContext對header的值進行SpEL表達式解析

補丁分析

commit:https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f
StandardEvaluationContext替換為了SimpleEvaluationContext

SpEL 提供的兩個 EvaluationContext ,區別如下:

  • SimpleEvaluationContext - 針對不需要 SpEL 語言語法的全部范圍並且應該受到有意限制的表達式類別,公開 SpEL 語言特性和配置選項的子集。
  • StandardEvaluationContext - 公開全套 SpEL 語言功能和配置選項。您可以使用它來指定默認的根對象並配置每個可用的評估相關策略。
    SimpleEvaluationContext 旨在僅支持 SpEL 語言語法的一個子集。它不包括 Java類型引用、構造函數 和 bean引用。所以說指定正確 EvaluationContext ,是防止SpEl表達式注入漏洞產生的首選。方法如下:
String expression = request.getParameter("message");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
StandardEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().withRootObject().build();
String message = exp.getValue(context, String.class);
exp.setValue(context, "Hello");

利用工具

https://github.com/chaosec2021/Spring-cloud-function-SpEL-RCE

看了下代碼用java.lang.Runtime).getRuntime().exec()執行bash反彈shell
也可以用processbuilder來執行命令,例如
new ProcessBuilder('/System/Applications/Calculator.app/Contents/MacOS/Calculator').start()

參考

https://www.jianshu.com/p/04bc9f482b43
https://mp.weixin.qq.com/s/AVvyKjRz_XooIB0s1S8njA
https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22963/README.zh-cn.md
https://www.cnblogs.com/9eek/archive/2022/04/07/16113603.html
https://blog.51cto.com/u_9652359/5187423


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM