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. 用python生成你想要的任意大小文件

    在测试的日常工作中,我们经常会需要测试上传文件的边界值.今天分享一段30行的简单代码,可以生成任意大小的文件,方便测试. file_size=input("请输入想要生成文件的大小:(单位M ...

  2. Java Study day3

    Day 2 遗留问题: cmd javac编译和 java执行 程序输出Hello World 遗留问题解答: 首先使用Txt记事本写一个后缀为.java的HelloWorld.java程序,直接复制 ...

  3. J20航模遥控器开源项目系列教程(四)PCB打印 | 嘉立创PCB下单教程,5元顺丰包邮解君愁!

    我们的开源宗旨:自由 协调 开放 合作 共享 拥抱开源,丰富国内开源生态,开展多人运动,欢迎加入我们哈~ 和一群志同道合的人,做自己所热爱的事! 项目开源地址:https://github.com/J ...

  4. CF1504X Codeforces Round #712

    CF1504D Flip the Cards(找规律+贪心) 题目大意:给你n张牌,正反面都有数字,保证所有牌上的数字在$[1,2n]$内且互不相同.你可以翻转任意张牌,接下来需要把牌按正面的数字从小 ...

  5. 为什么JVM要用到压缩指针?Java对象要求8字节的整数倍?

    前言 前两天在一个帖子中看到一道面试题: 堆内存超过32G时,为什么压缩指针失效? 之前没有了解过这方面的知识,于是开始google起来,但当我翻看了不下一页的帖子,我都仍然没有搞懂,因为好多答案给我 ...

  6. 简单面试前算法一览java

    1.排序 冒泡,快速排序 2.查找 二分查找 3.链表 翻转链表 合并链表 是否有环 b. 快慢指针 public class QuickSort {   public static void qui ...

  7. Kafka 是如何实现高吞吐率的?

    Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失.kafka主要使用了以下几 ...

  8. 转:为什么数据库选B-tree或B+tree而不是二叉树作为索引结构

    转载至:https://blog.csdn.net/sinat_27602945/article/details/80118362 B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了. ...

  9. 机器学习 machine learn

    机器学习 机器学习 概述 什么是机器学习 机器学习是一门能够让编程计算机从数据中学习的计算机科学.一个计算机程序在完成任务T之后,获得经验E,其表现效果为P,如果任务T的性能表现,也就是用以衡量的P, ...

  10. kali Linux 渗透测试 | ettercap图形界面(ARP 欺骗 + DNS欺骗)

    上次我们使用 arpspoof 工具在命令行中完成了 arp 欺骗实验,今天我们用另一种工具 ettercap 工具来实现.ettercap支持图形化操作,对新手非常友好,并且操作非常简单, ette ...