Spring框架为现代基于java的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。
Spring Cloud 中的 serveless框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数作为 Spel 表达式进行处理,造成Spel表达式注入,攻击者可通过该漏洞执行任意代码。
3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2
在官方网页新建一个 Spring boot 项目(https://start.spring.io/)、使用idea启动。

修改 pom.xml配置文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.5
com.example
demo
0.0.1-SNAPSHOT
demo
Demo project for Spring Boot
17
2021.0.1
org.springframework.cloud
spring-cloud-function-context
org.springframework.cloud
spring-cloud-starter
org.springframework.cloud
spring-cloud-starter-task
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-function-webflux
org.springframework.cloud
spring-cloud-function-dependencies
3.2.2
pom
org.springframework.cloud
spring-cloud-function-web
3.2.2
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
最后访问 http://127.0.0.1:8080. 出现以下页面表示成功。
【一>所有资源获取<一】
1、很多已经买不到的绝版电子书
2、安全大厂内部的培训资料
3、全套工具包
4、100份src源码技术文档
5、网络安全基础入门、Linux、web安全、攻防方面的视频
6、应急响应笔记 7、 网络安全学习路线
8、ctf夺旗赛解析
9、WEB安全入门笔记

apply方法会将http头部中的Spel表达式进行解析,从而造成Spel表达式注入。
查看官方diff


进入springframework/cloud/function/context/config/RoutingFunction文件。进入调试模式、将断点添加到apply()方法。

进入到apply()方法后、会调用route() 在该方法中会去判读input是否为 message的实例,function 是否为空、然后进入else if 去获取头信息、获取key值 spring.cloud.function.routing-expression 、在中间会对有无空格做判断。然后继续向下走。

会进入到springframework/cloud/function/context/config/RoutingFunction/functionFromExpression()方法。

routingExpression 会做为参数传入到springframework/expression/common/TemplateAwareExpressionParser/parseExpression()方法中。

判读其context是否为none值 在进入
springframework/expression/spel/standard/SpelExpressionParser/doPareExpression() 会new 一个 InternalSpelExpressionParser 类调用 doPareExpression() 继续跟进。

在springframeworl/expression/spel/stand/InternalSpelExpressionParser/doParseExpression()方法中、会在tokenizer.process()中 对token进行 源码与字节码的判断操作、继续向下。

会new 一个SpelExpression() 跟进到
springframwork/expression/spel/standard/SpelExpression/SpelExpression()。

在SpelExpression()方法中会将将表达式赋值到this.expression继续跟进 return到 springframework/expression/spel/standard/SpelpressionParser/doParseExpression()、继续return到springframework/expression/common/TemplateAwareExpressionPareser/pareExpression()、return
springframework/cloud/function/context/config/RoutingFunction/functionFromExpression()

在functionFromExpression()方法中会进入MessageUtils.toCaseInsensitiveHeadersStructure()。

调用MessageStructureWithCaseInsensitiveHeaderKeys(),进入到putAll()方法 获取message中头信息。

最后会进入漏洞触发点。

Payload 的构造可以参考官方测试用例。

本次利用创建文件测试。使用payloadtouch/tmp/xxxxxx.test.test。

