Threat Overview
Microsoft Security Research published a detailed exploitation analysis on September 30, 2026 for CVE-2026-73570, an unauthenticated operating-system command injection in the Zimbra Collaboration Suite SNMP notification path. A specially crafted SMTP message can introduce shell metacharacters into notification processing; when zimbra-snmp is installed and SNMP notifications are enabled, swatchdog passes attacker-controlled data to snmptrap, executing commands as the zimbra service account. Zimbra fixed the flaw in 10.1.20 on July 20, and CISA added it to the Known Exploited Vulnerabilities catalog on August 21.
Microsoft confirmed compromises in multiple regions and industries. Observed operations included out-of-band DNS/HTTP/ICMP validation, JSP webshell deployment into Jetty and mailboxd paths, curl/wget execution, reverse shells, a Zimbra-specific privilege escalation using writable mailbox logs and PAM, zimlog.service persistence, theft of LDAP/MySQL/authentication material, trusted-cluster SSH movement, mailbox/archive collection, remote-access implants, memory-backed execution, and an attempted Azure Blob transfer. Microsoft stresses that the published chain is a composite and that no single host necessarily showed every stage.
References
- Microsoft Security Research, “Unauthenticated command injection on internet-facing mail servers: tracking CVE-2026-73570,” published September 30, 2026: https://www.microsoft.com/en-us/security/blog/2026/09/30/unauthenticated-command-injection-on-internet-facing-mail-servers-tracking-cve-2026-73570/
- Zimbra, “Patch Release Update: Zimbra 10.1.20,” published July 20, 2026: https://blog.zimbra.com/2026/07/patch-release-update-zimbra-10-1-20/
- Zimbra Security Advisories, CVE-2026-73570 entry, current as reviewed October 1, 2026: https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories
- NVD, CVE-2026-73570, published August 13, 2026; KEV addition recorded August 21, 2026: https://nvd.nist.gov/vuln/detail/CVE-2026-73570
- The Hacker News, “Attackers Exploit Zimbra Flaw to Deploy Web Shells and Harvest Authentication Secrets,” published September 30, 2026: https://thehackernews.com/2026/09/attackers-exploit-zimbra-flaw-to-deploy.html
Impacted Systems
- Vendor/product: Zimbra Collaboration Suite (ZCS) before 10.1.20; Linux, self-managed/on-premises mail servers and clustered mailbox/MTA roles.
- Required configuration: Optional
zimbra-snmppackage installed and SNMP notifications enabled. - Exposure/prerequisite: Attacker can deliver a crafted SMTP request to the Zimbra service; authentication and user interaction are not required.
- Execution context: Initial commands run as the
zimbraaccount. Confirmed follow-on activity achieved root through Zimbra sudo-authorized helpers and PAM manipulation in at least one environment. - Fixed version: ZCS 10.1.20, released July 20, 2026, or later. Zimbra currently lists 10.1.20 as the fix release.
- Unaffected condition: Hosts without
zimbra-snmpor with SNMP notifications disabled do not meet the documented exploit prerequisites, but still require authoritative inventory validation.
Why this matters
The disclosure adds high-fidelity behavior and confirmed post-exploitation evidence to a KEV-listed internet-facing mail-server vulnerability. Zimbra servers contain concentrated mailbox, LDAP, token-signing, pre-authentication, certificate, and service credentials. The observed chain also moved across trusted mailbox nodes, so a single compromised server may have cluster-wide impact.
Exploitation Status
Confirmed active exploitation. Microsoft observed probing between July 28 and August 7 and confirmed compromises after the July 20 fix became available. Early probes used collaborator domains, a ZB73570 HTTP User-Agent, DNS/ICMP callbacks, and curl, wget, ping, nslookup, or id. Confirmed follow-on techniques and payloads varied between environments. An observed AzCopy transfer attempt does not prove exfiltration completed.
What this hunt looks for
The confirmed swatchdog-to-snmptrap injection boundary, JSP webshell writes, Zimbra Java launching shells, PAM/sudo escalation, systemd or cron persistence, service-secret collection, trusted-cluster movement, archive staging, callback services, and Syslog fallbacks.
Required logs
Microsoft Defender for Endpoint on Linux with DeviceProcessEvents, DeviceFileEvents, and DeviceNetworkEvents; Linux Syslog or audit telemetry; Zimbra mail and service logs; and DNS, firewall, or proxy telemetry for callback and exfiltration activity.
Hunt 1 — Confirmed shell-mediated SNMP command injection
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| where FileName in~ ("sh", "bash", "dash")
| where InitiatingProcessFileName =~ "perl"
| where InitiatingProcessCommandLine contains ".swatchdog_script"
| extend Cmd = tolower(ProcessCommandLine)
| where Cmd contains "snmptrap" and Cmd matches regex @"::zmservicename\s+s\s+.*[;&|<>`$].*\s+\S+-mib::zmservicestatus"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, SHA256, ReportId
| order by Timestamp desc
Hunt 2 — Suspicious JSP writes in Zimbra application paths
let lookback = 30d;
DeviceFileEvents
| where Timestamp >= ago(lookback)
| where FileName endswith ".jsp" or FileName endswith "_jsp.java"
| where FolderPath has_any ("/jetty_base/webapps/", "/jetty/webapps/", "/mailboxd/webapps/", "/work/zimbra/jsp/")
| where InitiatingProcessFileName in~ ("sh", "bash", "dash", "curl", "wget", "tee", "base64", "rsync", "java", "jspawnhelper", "perl") or InitiatingProcessCommandLine has "snmptrap"
| project Timestamp, DeviceName, ActionType, FolderPath, FileName, SHA256, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
Hunt 3 — Zimbra Java or jspawnhelper launching a native shell
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| where FileName in~ ("sh", "bash", "dash", "zsh", "ksh")
| where InitiatingProcessFileName in~ ("java", "jspawnhelper")
| where InitiatingProcessFolderPath has "/opt/zimbra/" or InitiatingProcessCommandLine has_any ("mailboxd", "jetty", "zimbra")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine
| order by Timestamp desc
Hunt 4 — Confirmed PAM and sudoers privilege-escalation behaviors
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| extend Cmd = tolower(ProcessCommandLine)
| where AccountName =~ "zimbra" or InitiatingProcessAccountName =~ "zimbra"
| where Cmd has_any ("/etc/pam.d/sudo", "pam_exec", "zmmailboxdmgr", "zmstat-fd", "/etc/sudoers", "nopasswd: all")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
Hunt 5 — zimlog or multi-mechanism persistence
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| extend Cmd = tolower(ProcessCommandLine)
| where Cmd has_any ("zimlog.service", "systemctl enable", "daemon-reload", "/etc/cron.d/", "crontab", "@reboot", "authorized_keys", "rc-update", "rc-service")
| where AccountName =~ "zimbra" or InitiatingProcessAccountName =~ "zimbra" or Cmd has "zimlog.service"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
Hunt 6 — Zimbra credential and authentication-secret collection
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| extend Cmd = tolower(ProcessCommandLine)
| where Cmd has_any ("zmlocalconfig -s", "localconfig.xml", "zimbraauthtokenkey", "zimbrapreauthkey", "zimbratwofactorauthsecret", "ldapsearch")
| where AccountName =~ "zimbra" or InitiatingProcessAccountName =~ "zimbra" or FolderPath has "/opt/zimbra/"
| project Timestamp, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, InitiatingProcessFileName
| order by Timestamp desc
Hunt 7 — Cluster discovery and movement using Zimbra SSH trust
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| extend Cmd = tolower(ProcessCommandLine)
| where Cmd has_any ("zmprov", "/opt/zimbra/.ssh/zimbra_identity", "stricthostkeychecking=no", "rsync")
| where AccountName =~ "zimbra" or InitiatingProcessAccountName =~ "zimbra"
| summarize FirstSeen=min(Timestamp), LastSeen=max(Timestamp), Commands=make_set(ProcessCommandLine, 30) by DeviceName, AccountName
| order by LastSeen desc
Hunt 8 — Mailbox archive staging or cloud-transfer tooling
let lookback = 30d;
DeviceProcessEvents
| where Timestamp >= ago(lookback)
| extend Cmd = tolower(ProcessCommandLine)
| where Cmd has_any ("/opt/zimbra/final.tar.gz", "/tmp/zimbra_dump_", "azcopy", "downloadazcopy-v10-linux", ".blob.core.windows.net")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
Hunt 9 — Known probing and callback infrastructure
let lookback = 90d;
let probeDomains = dynamic(["oast.fun", "oast.online", "dnslog.pp.ua", "requestrepo.com", "bypass.eu.org"]);
DeviceNetworkEvents
| where Timestamp >= ago(lookback)
| extend Host = tolower(coalesce(RemoteUrl, RemoteIP))
| where Host has_any (probeDomains)
| project Timestamp, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemotePort, RemoteUrl
| order by Timestamp desc
Hunt 10 — Syslog fallback for command injection and post-exploitation
let lookback = 90d;
Syslog
| where TimeGenerated >= ago(lookback)
| where SyslogMessage has_any (".swatchdog_script", "snmptrap", "zimlog.service", "zmlocalconfig -s", "/opt/zimbra/.ssh/zimbra_identity", "/tmp/zimbra_dump_", "ZB73570")
| where SyslogMessage has_any ("curl", "wget", "base64", "gzip", "pam_exec", "NOPASSWD", "authorized_keys", "rsync", "azcopy", "memfd")
| project TimeGenerated, Computer, HostName, Facility, SeverityLevel, ProcessName, SyslogMessage
| order by TimeGenerated desc
Detection Notes
- Hunt 1 is the highest-signal exploitation-boundary query. Hunts 2 through 8 establish distinct downstream outcomes and should not be treated as automatically implied by a Hunt 1 match.
- Known collaborator domains can be used legitimately by security testers. Correlate Hunt 9 with Zimbra process lineage, service accounts, and timing.
zmprov,zmlocalconfig, LDAP queries, SSH, rsync, and service management are legitimate administrator operations. Zimbra account context, unusual parents, compressed staging, and cross-node timing materially raise confidence.- A single removed JSP is not proof of eradication: Microsoft observed redundant copies across application paths and peer mailbox nodes.
- Thirty-day Defender XDR raw-event retention may not cover July/August activity. Sentinel or archived Linux/network logs are required for older lookback.
- Without Linux EDR/audit telemetry, memory-backed execution, deleted fragments, PAM manipulation, and process lineage may be unobservable. SMTP gateway logs alone cannot prove server-side command execution.