SpringCloud Function 介绍

SpringCloud 是一套分布式系统的解决方案,常见的还有阿里巴巴的Dubbo,Fass(Function As A Service )的底层实现就是函数式编程,在视频转码、音视频转换、数据仓库ETL等与状态相关度低的领域运用的比较多。开发者无需关注服务器环境运维等问题上,专注于自身业务逻辑实现即可。

SpringCloud Function 就是Spring提供的分布式函数式编程组件。

漏洞环境搭建

通过idea新建一个Spring项目,pom中引入spring-boot-starter-webspring-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.definitionspring.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数组里面。

  1. 请求正式进入Controller节点,Controller首先会将请求使用wrapper进行包装,wrapper就是将request转成FunctionInvocationWrapper 格式。

  1. 随后进入processRequest 对request进行处理,执行function的apply方法,跳转到doApply()时会对function进行判断,判断是不是functionRouter方法,根据咱们的配置文件此时的function为RoutingFunction.FUNCTION_NAMEfunctionRouter所以会,一路跳转到RoutingFunction.route

  1. 随后进入else if 分支, http头spring.cloud.function.routing-expression 不为空,则传入其值到functionFromExpression方法。

  2. 使用标准的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以上版本仍然暴露在风险之中。

引用

公众号

欢迎大家关注我的公众号,这里有干货满满的硬核安全知识,和我一起学起来吧!

SpringCloud Function SpEL注入的更多相关文章

  1. CVE-2022-22947 SpringCloud GateWay SpEL RCE

    CVE-2022-22947 SpringCloud GateWay SpEL RCE 目录 CVE-2022-22947 SpringCloud GateWay SpEL RCE 写在前面 环境准备 ...

  2. spring04 spel注入

    1.创建需要的实体类对象 public class Student { //学生实体类 private String name; //姓名 private Integer age; //年龄 priv ...

  3. Spring的3.0提供了一种:SpEL注入方式(了解)

    1. SpEL:Spring Expression Language是Spring的表达式语言,有一些自己的语法 2. 语法 * #{SpEL} 3. 例如如下的代码 <!-- SpEL的方式 ...

  4. day38 13-Spring的Bean的属性的注入:SpEL注入

    Spring2.5提供了名称空间p注入属性的方式,Spring3.几提供了SpEL属性注入的方式. <?xml version="1.0" encoding="UT ...

  5. SpringBoot SpEL表达式注入漏洞-分析与复现

    目录 0x00前言 0x01触发原因 0x02调试分析 0x03补丁分析 0x04参考文章 影响版本: 1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升至1.3.1或以上版本 ...

  6. SpEL表达式注入

    一.内容简介 Spring Expression Language(简称SpEL)是一种强大的表达式语言,支持在运行时查询和操作对象图.语言语法类似于Unified EL,但提供了额外的功能,特别是方 ...

  7. SpEL表达式注入漏洞学习和回显poc研究

    目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...

  8. SpringCloud Gateway 漏洞分析 (CVE-2022-22947)

    背景 SpringCloud 是Spring提供的微服务实现框架,其中包含网关.配置中心和注册中心等内容,网关的第一代实现为zuul,第二代实现为Gateway,提供了更好的性能和特性. 网关可以提供 ...

  9. 关于IONIC 报错 XX is not a function

    刚开始 做一个项目,总是报错"XX is not  a function"   最后发现 原因 ,   原来是 服务的 注入位置 有问题. angular.module(" ...

随机推荐

  1. Linux的总线设备驱动模型

    裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...

  2. 【Java分享客栈】Java程序员为争一口气熬夜硬刚CSS实现掘金首页

    前言 如果我做不了最厉害的Java工程师,那我就做Java工程师中最厉害的前端工程师. 前段时间,我默默给自己又喂了这碗心灵鸡汤-- 我不是很厉害的Java工程师,哪怕我已经工作八年,我依然觉得自己和 ...

  3. ModelSim10.7安装破解教程

    我打算开始学习ZYNQ,所以先安装好工具ModelSim10.7,很无奈的是倒腾了一个上午也没生产license的txt文档和破解成功. 上面是破解失败的截图,下面是生成不了license,点了直接闪 ...

  4. 知识点简单总结——minmax容斥

    知识点简单总结--minmax容斥 minmax容斥 好像也有个叫法叫最值反演? 就是这样的一个柿子: \[max(S) = \sum\limits_{ T \subseteq S } min(T) ...

  5. url斜杠问题——重定向

    path('hello',hello), path('hello/',hello), 有什么区别? 没有斜杠:只能访问hello 有斜杠:可以访问hello和hello/ 分析有斜杠的: hello- ...

  6. BGP的四类属性详解

    BGP的四类属性 公认必遵(Well-known mandatory) 要求所有运行BGP协议的设备都必须能识别,且在更新消息中必须包含. Origin(起源) 属性 用来标识路由信息的来源. 如果路 ...

  7. [使用多仓库解决] idea maven 下载源码出现:Cannot download sources Sources not found for: xxx

    根本原因 依赖托管仓库的库存不足.有的仓库,就是没有团队上传这个依赖.所以多加几个镜像源,总有一个仓库能找到. 解决方案 修改 maven 默认配置文件 "C:\Users\<user ...

  8. 什么是bean的自动装配?

    Spring 容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作.

  9. maven常用命令含义

    今天在开发过程中,对一个mapper.xml文件的sql进行了改动,重启tomcat后发现没有生效,首先考虑是不是远程服务开启着,导致代码没有走本地,确认远程服务是关闭的,的确是本地修改没有生效,于是 ...

  10. SpringBoot 上传文件大小限制,SizeLimitExceededException: the request was rejected because its size (64042302) exceeds the configured maximum (10485760)

    对应的配置属性文件:org.springframework.boot.autoconfigure.web.servlet.MultipartProperties 由于我是yml文件,所以直接这样定义就 ...