SpringCloud Function SpEL注入漏洞分析及环境搭建
作者:9eek 时间:2022-07-03 05:18:21
SpringCloud Function 介绍
SpringCloud 是一套分布式系统的解决方案,常见的还有阿里巴巴的Dubbo,Fass(Function As A Service )的底层实现就是函数式编程,在视频转码、音视频转换、数据仓库ETL等与状态相关度低的领域运用的比较多。开发者无需关注服务器环境运维等问题上,专注于自身业务逻辑实现即可。
SpringCloud Function 就是Spring提供的分布式函数式编程组件。
漏洞环境搭建
通过idea新建一个Spring项目,pom中引入spring-boot-starter-web
、spring-cloud-function-web
,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringCloudDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringCloudDemo</name>
<description>SpringCloudDemo</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
其中spring-cloud-function-web
的依赖如上图,核心实现为spring-cloud-function-core
包。
先在main函数中新建两个方法(uppercase
将字符串变为大写,reverse
字符串反转):
当在pom中引入spring-cloud-function-web
后,函数会自动添加为HTTP端点。
然后漏洞关键是在application.properties
或者yaml配置文件中新增一行:
spring.cloud.function.definition=functionRouter
这里的属性spring.cloud.function.definition
表示声明式函数组合,这个功能允许在提供属性时使用|
(管道),
或;
(过滤)分隔符以声明的方式提供组合指令。例如
--spring.cloud.function.definition=uppercase|reverse
举例:
当配置该属性为uppercase时,访问根路径提交的参数会自动被uppercase函数接受转化为大写:
反之若配置为reverse则默认路径函数功能为反转字符串:
通俗来讲这个属性就是一个默认路由, 可以手动指定相关函数,也可以使用functionRouter
,指定的方式可以是配置文件、环境变量或者启动参数等。
functionRouter
如果设置为functionRouter则默认路由绑定的具体函数交由用户进行控制,在 Spring Cloud Function Web里面,可以通过设置http头的方式来控制,使用spring.cloud.function.definition
和spring.cloud.function.routing-expression
都可以,区别是后者允许使用Spring表达式语言(SpEL)。
举例:
因为spring.cloud.function.routing-expression
允许使用SpEL表达式,所以就可能存在SpEL注入。
SpEL注入
这里简单介绍下SpEL,Spring Expression Language 是Spring提供的具有方法调用和基本的字符串模版功能的套件。类似OGNL、MVEL、JBoss EL。
SpEL可以字符串之间进行嵌套也可以单独使用,嵌套时使用#{}
(实现ParserContext
接口)。
举例:
但因为Spel支持方法调用,所以如果使用的是StandardEvaluationContext 进行解析(默认),则可能会被滥用,如使用new ProcessBuilder('/System/Applications/Calculator.app/Contents/MacOS/Calculator').start()
可触发命令执行:
漏洞复现
既然SpringCloud Function 中的functionRouter支持SpEL那是不是存在SpEL注入呢,我们在HTTP头中插入上面调起计算器的SpEL表达式
Payload: spring.cloud.function.routing-expression: new ProcessBuilder('/System/Applications/Calculator.app/Contents/MacOS/Calculator').start()
非常简单粗暴,漏洞复现成功:
原理分析
在命令执行出下断点,看下程序执行流程。
SpringCloud Function之所以能自动将函数建立http端点,是因为在包mvc.FunctionController
中使用/**
监听了get/post类型的所有端点。
1.当一个请求进入时,程序首先基于Springboot的自动配置,将配置文件注入到functionProperties,随后将以“WebRequestConstants.handler”为key,function为值添加到request数组里面。
2.请求正式进入Controller节点,Controller首先会将请求使用wrapper进行包装,wrapper就是将request转成FunctionInvocationWrapper 格式。
3.随后进入processRequest 对request进行处理,执行function的apply方法,跳转到doApply()时会对function进行判断,判断是不是functionRouter方法,根据咱们的配置文件此时的function为RoutingFunction.FUNCTION_NAME
既 functionRouter
所以会,一路跳转到RoutingFunction.route
5.随后进入else if 分支,http头spring.cloud.function.routing-expression
不为空,则传入其值到functionFromExpression
方法。
6.使用标准的StandardEvaluationContext
对header的值进行SpEL表达式解析:
后续就不用再跟下去了,至此可以发现,只要通过环境变量、配置文件或者参数等方式配置为spring.cloud.function.definition=functionRouter
即可触发SpEL注入。
补丁分析
SpringCloud官方已经修复了此问题(https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f)
和其他SpEL注入修复方式一样,使用了SimpleEvaluationContext
替换StandardEvaluationContext
,那这个漏洞基本就算修复完成了。但因为这个commit还没有纳入版本,所以目前springcloud Function3.0以上版本仍然暴露在风险之中。
引用
https://spring.io/projects/spring-cloud-function#overview
https://cloud.spring.io/spring-cloud-function/reference/html/spring-cloud-function.html#_function_catalog_and_flexible_function_signatures
https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f
http://itmyhome.com/spring/expressions.html
来源:https://www.cnblogs.com/9eek/p/16113603.html
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java Callable接口实现细节详解
![](https://img.aspxhome.com/file/2023/5/58995_0s.png)
java中的数组初始化赋初值方式
java编程基础之模仿用户登录代码分享
Mybatis批量插入更新xml方式和注解方式的方法实例
SpringBoot定时任务设计之时间轮案例原理详解
![](https://img.aspxhome.com/file/2023/0/62450_0s.png)
Java8中的LocalDateTime你会使用了吗
java利用socket通信实现Modbus-RTU通信协议的示例代码
Java动态 代理和AOP应用示例
![](https://img.aspxhome.com/file/2023/0/60270_0s.png)
C#实现简单合并word文档的方法
Spring JDK动态 代理实现过程详解
![](https://img.aspxhome.com/file/2023/2/59392_0s.png)
Java中String的JdbcTemplate连接SQLServer数据库的方法
java睡眠排序算法示例实现
![](https://img.aspxhome.com/file/2023/2/69882_0s.png)
Spark JDBC操作MySQL方式详细讲解
javaweb页面附件、图片下载及打开(实现方法)
浅析Java中对象的创建与对象的数据类型转换
![](https://img.aspxhome.com/file/2023/7/60257_0s.png)
Java 你知道什么是耦合、如何解(降低)耦合
Spring Cloud 动态刷新配置信息教程详解
Java读取TXT文件内容的方法
Java中File类方法详解以及实践
![](https://img.aspxhome.com/file/2023/5/65605_0s.jpg)
JAVA内部类示例详解及练习
![](https://img.aspxhome.com/file/2023/7/62427_0s.png)