Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )

    • 0x00 前言
    • 0x01 漏洞复现
    • 0x02 漏洞分析
    • 0x03 总结
    • 0x04 参考文章

0x00 前言

这个漏洞本质是一个SPEL注入漏洞,需要应用暴漏actuator接口用来动态添加路由

当Gateway Actuator端点是启用状态并且是允许访问的以及相关配置不安全时,使用Spring Cloud Gateway的应用程序容易受到代码注入攻击。远程攻击者可以利用Actuator动态添加恶意路由,若路由中包括SPEL表达式则在路由刷新时会对其进行解析从而达到SPEL表达式注入

0x01 漏洞复现

漏洞影响版本:

  • Spring Cloud Gateway < 3.1.1
  • Spring Cloud Gateway < 3.0.7

pox.xml

<?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.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>person.xu</groupId>
	<artifactId>vulEnv</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>cve_2022_22947</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>2021.0.1</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
			<version>3.0.6</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-gateway-server</artifactId>
			<version>3.0.6</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</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>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

启用Gateway Actuator

//application.properties
management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=gateway

环境配好后启动

攻击者利用Actuator动态添加路由,返回201表示添加成功

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第1张图片

刷新路由,使该路由生效

成功弹出计算器

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第2张图片

0x02 漏洞分析

https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e

根据commit可以看到修改了shortcutconfigurable#getvalue

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第3张图片

旧版使用的是StandardEvaluationContext类:支持更全面的SpEL功能

新版使用的是GatewayEvaluationContext类,该类是自定义的其内部封装了SimpleEvaluationContext类,而SimpleEvaluationContext类仅仅支持基本的SpEL功能,即 SpEL 语言语法的一个子集,例如排除对 Java 类型、构造函数和 bean 引用。

找到了修复的地方,那就一步步往回推

在getvalue中最终执行了SPEL表达式,首先判断entryValue是否以#{开头并且以}结尾,这里是检查语法格式,然后就会进行经典的SPEL表达式解析

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第4张图片

那关键点就是谁调用了getValue,然后关注传入的entryValue是否可控

全局搜索getValue

PS:这里不能直接用ctrl+shift+f然后换到scope进行全局搜索因为jar包中都为class文件,其都是二进制文件,所以无法查找到任何信息。所以需要先下载源码再ctrl+shift+f然后换到scope

参考:https://blog.csdn.net/fuleigang/article/details/124754169

一般先在本类中看是否存在调用,发现在本类中存在调用,可以看到在normalize中调用了getValue并且entryValue跟传入的args有关

PS:这里也可以选中getValue,然后按ctrl+clt+h查看getValue的调用情况

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第5张图片

然后看一下normalize是如何被调用的

选中normalize然后按ctrl+clt+h,可以看到调用链如下

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第6张图片

点击第二个,发现在normalizeProperties中调用了normalize并且发现entryValue跟this.properties有关

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第7张图片
Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第8张图片

继续往上跟,看看this.properties是怎么来的,是否可控

点击第三处,本类的bind方法调用了normalizeProperties,但是该方法中并没有初始化this.properties,那就继续往上跟

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第9张图片

可以看到有四处调用了此处的bind方法,这里我们跟RouteDefinitionRouteLocator.lookup

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第10张图片

可以看到在里面调用了properties方法

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第11张图片

跟进去看一下,发现该方法就是在给this.properties赋值,而this.properties值为predicate.getArgs()

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第12张图片

这里的properties方法和eventFunction方法返回值都为为AbstractBuilder对象,可以理解为在给AbstractBuilder对象进行配置,最终调用该对象的bind方法

所以现在关注点来到了predicate.getArgs(),看看这个可不可控,如果这个可控,那么就意味着最开始说的那个entryValue可控

predicate是传参进来的

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第13张图片

查一下lookup的调用链

发现在本类的combinePredicates中有被调用

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第14张图片

可以看到predicates跟routeDefinition有关,到这应该能猜到predicates即路由定义中的predicates字段。通过routeDefinition.getPredicates获取路由定义中predicates字段信息。当我们利用Actuator动态添加路由时,是可以控制predicates,控制了predicates也就能控制开头讲的entryValue,从而可以控制SPEL解析的内容,从而造成表达式注入

POC:

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第15张图片

刷新路由,成功rce

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第16张图片

我们在漏洞利用那使用的是路由定义中的filters字段,这个字段也支持SPEL解析,就在predicate字段解析完成后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1G10UPF-1660536470194)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220815115930198.png)]

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第17张图片

Spring Cloud GateWay SPEL RCE(CVE-2022-22947 )_第18张图片

0x03 总结

本质是一个SPEL表达式注入漏洞,本来是只有在修改路由配置文件的情况下才能导致RCE,但是由于Gateway提供了Actuator相关的API可以动态地注册路由,使得被害者在开启Actuator功能情况下,攻击者可以动态添加路由(其中包含了恶意的SPEL表达式)。在路由刷新时,Gateway解析路由中的SPEL表达式从而导致RCE

在实战中,利用性不高,目标未必会开启Actuator接口,开启了也未必能正常添加路由

0x04 参考文章

https://www.yuque.com/tianxiadamutou/zcfd4v/uqg4u0

https://www.cnblogs.com/9eek/p/16243402.html

https://nosec.org/home/detail/5008.html

https://bbs.huaweicloud.com/blogs/335870

https://blog.csdn.net/fuleigang/article/details/124754169

https://www.anquanke.com/post/id/269795

你可能感兴趣的:(Java安全,java,spring,cloud,web安全)