前言
漏洞描述
利用范围
漏洞分析
使用idea新建Spring Cloud Function项目。
pom.xml中引入spring-boot-starter-web、spring-cloud-function-web
在application.properties中添加spring.cloud.function.definition=functionRouter
这里设置端口为8090,默认为8080
在环境搭建时,我们在application.properties中添加spring.cloud.function.definition=functionRouter
这里的属性spring.cloud.function.definition 表示声明式函数组合,简单理解就是一个默认路由。具体可参考如下说明。
我们设置spring.cloud.function.definition=functionRouter就是使默认路由绑定具体函数交由用户进行控制。
在spring-cloud-function-web中可以通过设置Message Headers来传达路由指令,也可以路通过spring.cloud.function.definition 或spring.cloud.function.routing-expression作为应用程序属性进行通信,允许使用 Spring 表达式语言 (SpEL)。
这就是产生SpEL注入的关键所在。
在理解了前置知识中相关原理,其实也就能大概知晓漏洞原理。
看到从请求头中获取的 spring.cloud.function.routing-expression 之前是由StandardEvaluationContext 解析,修复新增了 isViaHeader 变量做了一个判断,如果是从请求头中获取的 spring.cloud.function.routing-expression 值,使用 SimpleEvaluationContext 解析。
在spring.cloud.function.context.catalog.simpleFunctionRegistry#doApply中。
在执行function apply方法之后,会跳转到doApply中,对funtion进行判断,判断是不是functionRouter方法。
后续跟进,进入spring.cloud.function.context.config.Routingfunction#route
进入else if 分支, http头spring.cloud.function.routing-expression 不为空,则传入其值到functionFromExpression方法。
随后对传入的header进行解析处理。
后续跟进发现对Spel表达式进行解析的方法就是StandardEvaluationContext
后续跟进,在解析传入的Spel之后,成功触发恶意代码。
漏洞复现
修复建议
参考材料
1.https://docs.spring.io/spring-cloud-function/docs/3.2.2/reference/html/spring-cloud-function.html#_declarative_function_composition
2.https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f
3.https://spring.io.zh.xy2401.com/projects/spring-cloud-function/#overview
关于Portal Lab
星阑科技 Portal Lab 致力于前沿安全技术研究及能力工具化。主要研究方向为API 安全、应用安全、攻防对抗等领域。实验室成员研究成果曾发表于BlackHat、HITB、BlueHat、KCon、XCon等国内外知名安全会议,并多次发布开源安全工具。未来,Portal Lab将继续以开放创新的态度积极投入各类安全技术研究,持续为安全社区及企业级客户提供高质量技术输出。