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

影响范围:

3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2

项目简介:

Spring Cloud Function 是一个具有以下高级目标的项目:

  • 通过函数促进业务逻辑的实现,可以将函数设置为HTTP端点
  • 将业务逻辑的开发生命周期与任何特定的运行时目标分离,以便相同的代码可以作为 Web 端点、流处理器或任务运行。
  • 支持跨无服务器提供商的统一编程模型,以及独立运行(本地或在 PaaS 中)的能力。
  • 在无服务器提供程序上启用 Spring Boot 功能(自动配置、依赖注入、指标)

漏洞分析:

首先在项目中找到关键点,把项目从github导入IDEA,发现没有搭建成功,换成JDK17也不行,网上关于这个项目的资料寥寥无几,索性直接看源码找了,在下图中routingExpression直接会被解析执行,并且context也是StandardEvaluationContext,接下来就是找这个参数了
在这里插入图片描述
在这里插入图片描述
在同一个文件中该函数就会被调用,一个是(String) message.getHeaders().get("spring.cloud.function.routing-expression"),一个是functionProperties.getRoutingExpression(),两个都不确定是否可控
在这里插入图片描述
先看functionProperties,在构造函数中赋值
在这里插入图片描述
最终找到了functionRouter,该函数添加了@Bean注解,Spring Cloud Function 项目中核心是推动基于函数的编程模型,而不是熟悉的 POJO 模型,满足一定条件并被@Bean注解后就可以将函数作为HTTP端点进行访问,发现代码中没有出现functionRouter后,可能这里也作为了HTTP端点进行访问了,但是参数怎么在数据包中设置还得继续看文档。没有找到相关的内容,所以先跳过这个参数了,回到之前找另一个参数(String) message.getHeaders().get("spring.cloud.function.definition")
在这里插入图片描述
message的信息,在apply函数中会进行调用,apply函数经过查询文档之后发现应命名函数的结果,也就是在调用@Bean注解标记后的函数时会执行apply
在这里插入图片描述
在这里插入图片描述
查看官方文档,这里说明了RoutingFunction注册在FunctionCatalog中的名称下functionRouter,也就是说访问functionRouter时就会调用对应apply,而apply中正好调用了route,这也与代码中的一致,因此可以通过functionRouter成功执行到触发点,接下来还需要知道(String) message.getHeaders().get("spring.cloud.function.routing-expression"),这个值如何控制
在这里插入图片描述
在这里插入图片描述
(String) message.getHeaders().get("spring.cloud.function.routing-expression")仔细看这个方法,getHeaders,很容易能想到请求包中也有header,接下来就是到官方文档求证…
在这里插入图片描述
总结一下:

1、Spring Cloud Function 项目是基于函数的编程模型,而functionRouter注册成为了HTTP端点

2、在functionRouter函数中会调用RoutingFunction,同时执行apply方法

3、apply()中会调用route方法,在该方法中会判断请求内容是否为Message,如果有数据那么会将Hander中的spring.cloud.function.routing-expression进行SpEL表达式进行解析

漏洞复现:

可以自己搭建也直接使用github上师傅的环境使用IDEA进行搭建,JDK版本为17

https://github.com/cckuailong/spring-cloud-function-SpEL-RCE

POST /functionRouter HTTP/1.1
host:127.0.0.1:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Connection: close
spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("open -a /System/Applications/Calculator.app")
Content-Length: 16

xxx

在这里插入图片描述
在复现中还发现一点没有分析到,可以在配置文件中配置默认路由,当访问不存在的路由时就会访问指定的该路由,当配置了以下内容时访问不存在的路有也会执行访问functionRouter的内容

spring.cloud.function.definition:functionRouter

因此在配置之后访问不存在的路由就可以执行,堪称死亡配置…
在这里插入图片描述
补丁分析:

查看提交分支

https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f

设置SimpleEvaluationContext来进行防御
在这里插入图片描述
在这里插入图片描述
总结:

这个漏洞的分析没有Spring Cloud Gateway那么顺利,因为这个项目的官方文档比较难懂,而且网上关于这个项目的使用也很少,可能是国内很少采用基于函数的编程方式吧。只能依靠官方文档和一些简单的教程去理解分析,由于没有调试,可能中间会缺少一些细节部分,分析有误的地方请大佬们及时指正~

参考内容:

  • https://spring.io/projects/spring-cloud-function#overview
  • https://docs.spring.io/spring-cloud-function/docs/3.1.7/reference/html/spring-cloud-function.html
  • https://github.com/cckuailong/spring-cloud-function-SpEL-RCE

喜欢的大佬们可以添加我的公众号,我会在公众号里持续分享一些安全的内容,可以一起交流~

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值