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


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

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    启用Gateway Actuator

    //application.properties
    management.endpoint.gateway.enabled=true
    management.endpoints.web.exposure.include=gateway
    
    • 1
    • 2
    • 3

    环境配好后启动

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

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

    刷新路由,使该路由生效

    成功弹出计算器

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

    0x02 漏洞分析

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

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

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

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

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

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

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

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

    那关键点就是谁调用了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的调用情况

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

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

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

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

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mO4niu8e-1660536470192)(C:\Users\91136\AppData\Roaming\Typora\typora-user-images\image-20220815113057536.png)]
    在这里插入图片描述

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

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

    在这里插入图片描述

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

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

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

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

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

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

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

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

    predicate是传参进来的

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

    查一下lookup的调用链

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

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

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

    POC:

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

    刷新路由,成功rce

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

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

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

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

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

    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

  • 相关阅读:
    ElasticSearch中的文档和查询响应数据
    密码正确无法登陆Linux系统
    js+html实现打字游戏v1
    案例解读【淘宝API接口的运用:抓取用户数据从而驱动精准营销
    在 GNU/Linux 中使用 GNUInstallDirs 优化 cmake 安装路径
    java实验报告1:JDK的安装配置及基本输出练习
    《深入理解java虚拟机 第三版》学习笔记三
    67. SAP ABAP 监控用户事物码和程序执行的工具介绍
    PCB - 封装焊盘阻焊层的检查
    SQL限制用户只能看到指定的库或表(Navicat操作)
  • 原文地址:https://blog.csdn.net/weixin_43263451/article/details/126344394