Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

admin 2022年4月6日03:17:31评论252 views字数 6829阅读22分45秒阅读模式

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

Spring Cloud Function 是来自 Pivotal 的 Spring 团队的新项目,它致力于促进函数作为主要的开发单元。该项目提供了一个通用的模型,用于在各种平台上部署基于函数的软件,包括像 Amazon AWS Lambda 这样的 FaaS(函数即服务,function as a service)平台。


研究发现,Spring Cloud Function 的 RoutingFunction 类中 apply() 方法将请求头中 spring.cloud.function.routing-expression 字段定义的 SpEL 表达式使用 StandardEvaluationContext 进行解析 ,从而造成远程代码执行漏洞。


项目地址:https://github.com/spring-cloud/spring-cloud-function



影响版本

3.0.0.M3 <= Spring Cloud Function <= 3.2.2



漏洞简析

前几天 Spring4Shell 爆发时这个漏洞还作为一个 0day 没有分配 CVE,看到 tw 上有些人说 Spring Core RCE 就是这个洞,然而并不是:)。


闲话少说跟着过一遍流程吧。


以 spring-cloud-function-samples/function-sample-pojo 为例分析

git clone --branch v3.2.0 https://github.com/spring-cloud/spring-cloud-function

配置spring-cloud-function-samples/function-sample-pojo/src/main/resources/application.properties(非必选项,未配置的情况下借助 /functionRouter 接口一样可以触发)

spring.cloud.function.definition:functionRouter

Run

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

至此环境就位。




老规矩先看补丁,定位到 commit: dc5128b80c6c04232a081458f637c81a64fa9b52,重点关注如下修改

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

看到从请求头中获取的 spring.cloud.function.routing-expression 原本由 StandardEvaluationContext 解析,commit 更新后新增了 isViaHeader 变量做了一个判断,如果是从请求头中获取的 spring.cloud.function.routing-expression 值,使用 SimpleEvaluationContext 解析,以达到防御 SpEL 表达式注入的目的。


依据 RoutingFunctionTests

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

构造一个无害 payload

POST /functionRouter/rand HTTP/1.1Host: 192.168.110.1:8080spring.cloud.function.routing-expression: SpEL-ExpressionContent-Type: application/x-www-form-urlencoded

定位到org.springframework.cloud.function.context.config.RoutingFunction#functionFromExpression,看到 SpEL 表达式解析的位置,使用 StandardEvaluationContext 对象解析 SpEL 表达式的值,造成 SpEL 表达式注入问题,sink 点打断点,开启 debug 并发送我们上面构造的 payload

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

向上追溯看看其中几个关键点

定位到org.springframework.cloud.function.context.config.RoutingFunction#route,从请求头的 spring.cloud.function.routing-expression 字段取值

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

继续向上,省略参数传递过程

-> org.springframework.cloud.function.context.config.RoutingFunction#apply-> org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper#doApply-> org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper#apply-> org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper#processRequest

直到 source:org.springframework.cloud.function.web.mvc.FunctionController#form,可以看到 FunctionController#form 规定了触发的请求头为 POST 方法,MIME 类型为 "application/x-www-form-urlencoded" 或 "multipart/form-data"。(这里针对本例漏洞环境 spring-cloud-function-samples/function-sample-pojo,顺便去看了一下  spring-cloud-function Release 版本中 source 不唯一)。

Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析


最后放一下调用栈

getValue:349, SpelExpression (org.springframework.expression.spel.standard)functionFromExpression:201, RoutingFunction (org.springframework.cloud.function.context.config)route:127, RoutingFunction (org.springframework.cloud.function.context.config)apply:86, RoutingFunction (org.springframework.cloud.function.context.config)doApply:699, SimpleFunctionRegistry$FunctionInvocationWrapper (org.springframework.cloud.function.context.catalog)apply:551, SimpleFunctionRegistry$FunctionInvocationWrapper (org.springframework.cloud.function.context.catalog)processRequest:100, FunctionWebRequestProcessingHelper (org.springframework.cloud.function.web.util)form:84, FunctionController (org.springframework.cloud.function.web.mvc)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)invoke:-1, NativeMethodAccessorImpl (sun.reflect)invoke:-1, DelegatingMethodAccessorImpl (sun.reflect)invoke:-1, Method (java.lang.reflect)doInvoke:205, InvocableHandlerMethod (org.springframework.web.method.support)invokeForRequest:150, InvocableHandlerMethod (org.springframework.web.method.support)invokeAndHandle:117, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)invokeHandlerMethod:895, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)handleInternal:808, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)doDispatch:1067, DispatcherServlet (org.springframework.web.servlet)doService:963, DispatcherServlet (org.springframework.web.servlet)processRequest:1006, FrameworkServlet (org.springframework.web.servlet)doPost:909, FrameworkServlet (org.springframework.web.servlet)service:681, HttpServlet (javax.servlet.http)service:883, FrameworkServlet (org.springframework.web.servlet)service:764, HttpServlet (javax.servlet.http)internalDoFilter:227, ApplicationFilterChain (org.apache.catalina.core)doFilter:162, ApplicationFilterChain (org.apache.catalina.core)doFilter:53, WsFilter (org.apache.tomcat.websocket.server)internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)doFilter:162, ApplicationFilterChain (org.apache.catalina.core)doFilterInternal:100, RequestContextFilter (org.springframework.web.filter)doFilter:117, OncePerRequestFilter (org.springframework.web.filter)internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)doFilter:162, ApplicationFilterChain (org.apache.catalina.core)doFilterInternal:93, FormContentFilter (org.springframework.web.filter)doFilter:117, OncePerRequestFilter (org.springframework.web.filter)internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)doFilter:162, ApplicationFilterChain (org.apache.catalina.core)doFilterInternal:201, CharacterEncodingFilter (org.springframework.web.filter)doFilter:117, OncePerRequestFilter (org.springframework.web.filter)internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)doFilter:162, ApplicationFilterChain (org.apache.catalina.core)invoke:197, StandardWrapperValve (org.apache.catalina.core)invoke:97, StandardContextValve (org.apache.catalina.core)invoke:541, AuthenticatorBase (org.apache.catalina.authenticator)invoke:135, StandardHostValve (org.apache.catalina.core)invoke:92, ErrorReportValve (org.apache.catalina.valves)invoke:78, StandardEngineValve (org.apache.catalina.core)service:360, CoyoteAdapter (org.apache.catalina.connector)service:399, Http11Processor (org.apache.coyote.http11)process:65, AbstractProcessorLight (org.apache.coyote)process:889, AbstractProtocol$ConnectionHandler (org.apache.coyote)doRun:1743, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)run:49, SocketProcessorBase (org.apache.tomcat.util.net)runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)run:-1, Thread (java.lang)



漏洞修复

自查 Spring Cloud Function 使用版本,升级到安全版本即可。

全局搜索 jar 文件版本,若是 Maven 引入则查 pom,很简单不说了。


当然官方使用 SimpleEvaluationContext 解析 SpEL 可以修复 SpEL 表达式注入引起的代码执行系统接管问题,但是仍存在 SpEL 表达式中初始化超大数组导致的内存耗尽 DOS 问题,有兴趣的小伙伴可以研究一下文末许少的文章,后续官方应该还会发布相应的安全修补措施。



Referer

https://www.cyberkendra.com/2022/03/rce-0-day-exploit-found-in-spring-cloud.html

https://mp.weixin.qq.com/s/U7YJ3FttuWSOgCodVSqemg

https://github.com/spring-cloud/spring-cloud-function/commit/dc5128b80c6c04232a081458f637c81a64fa9b52

https://xz.aliyun.com/t/11114




声明:本文档仅用于技术研究,由于传播、使用此文档提供的信息而造成任何后果,均由使用者本人负责,Craft Security Group 团队及文章作者不为此承担任何法律责任。



原文始发于微信公众号(Craft Security Group):Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月6日03:17:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Spring Cloud Function SpEL 表达式注入漏洞(CVE-2022-22963)分析http://cn-sec.com/archives/867056.html

发表评论

匿名网友 填写信息