~/en/research $ cat case-001.md
Zimbra: command injection in the zimbra-snmp SNMP notification
Retrospective dossier of the command injection in the SNMP notification path in Zimbra, preserved as the lab baseline. The dossier records what the agent actually did, what had to be adapted in the lab to reach the sink, and what was left explicitly not established.
What was published and why this case is a dossier
Zimbra fixed a command injection in the SNMP notification path in 10.1.20: NVD opened it as CVE-2026-73570 with CWE-78 and CVSS 3.1 8.9 (High), published on 13 August 2026, and the vendor commit studied is c4837c66 in zm-build. The public conditions are ZCS before 10.1.20 with the optional zimbra-snmp package installed and SNMP notifications enabled. CISA KEV has listed it since 2026-08-21 with due date 2026-08-24, and CERT Polska reported active exploitation.
This is the retrospective dossier of the lab: the reconstruction preserved as the baseline, with the lab, the evidence and the full record in the repo, but with no published video piece. The initial research lasted a little over two days and was produced with agents operating on Qwen3.8-27B-FP8 and DeepSeek-V4-Flash-0731, with human supervision of scope and publication.
The chain, step by step
The path is notification, not authentication: an incoming message can carry a recipient field all the way to the log monitor that fires the SNMP alert. The sink is the legacy route doSNMP(), which builds a shell-interpreted command from interpolated data using Perl backticks. Anything that reaches that interpolation runs with the privileges of the service.
The vendor fix replaces that with a system() call with separate arguments, which no longer goes through the shell interpreter. In the case comparison, the patched branch did not execute the identical canary while the unpatched branch executed it, with a live positive control the same day.
The honest and central detail: for the crafted recipient field to reach the sink, the lab added a controlled watch condition in swatchdog. That is declared in the case as part of the setup, and it is why the README itself writes that it is not established that the documented field reaches the sink on an unmodified installation.
What the agent did and what it measured
Canary first: execution validation was done with a reversible canary before any impact demonstration, and the bounded demonstration went through an explicit human gate. The execution landed as the zimbra service user, with restoration after the test, on an isolated runtime network with a fictitious domain.
The published evidence is process screenshots, rule-fire transcripts, fix verification records, frames, the recordings of the run and a SHA-256 manifest for the case. None of this touched a third-party system: the README declares that explicitly.
Where the agent stopped
The case carries a "not established" table instead of a narrative of successes. The most important point: it is not proven that the exact fire path exists on an unmodified installation, because the lab added a watch condition to reach the sink. Nor is the prevalence of that path in production established, nor did the lab observe real-world exploitation on its own (that is attributed to CERT Polska and to CISA), nor is universal detection coverage or production-ready tuning claimed.
And there is a record gap I would rather name than fill: unlike cases 002, 003 and 004, this dossier does not publish an attempt log with the rejected attempts. The repo documents the limits, but not the sequence of failed attempts, so on this page that detail does not exist and is not invented.
Detection and remediation
Remediation: upgrade to ZCS 10.1.20. If the product cannot be patched right away, what cuts the chain are the public preconditions: remove the optional zimbra-snmp package or disable SNMP notifications, because without the notification monitor there is no sink to reach.
The published detections are five Sigma rules (four with reviewed status and one experimental), Suricata and YARA. They cover the attempt through the Postfix recipient field, the injection in swatch/dosnmp, the reverse shell over /dev/tcp from the service user, generic persistence via a suspicious child process under the service and the tampered login banner as a defacement indicator. The YARA rules look for the mail queue remnant, the notification artifact and the PoC banner.
All the rules fired against the artifacts of the lab run, not against real traffic, so the case itself recommends tuning them against the telemetry and baselines of each environment before letting them page anyone.
Results
- The legacy sink
doSNMP()builds a shell-interpreted command using Perl backticks; verified in source and in execution, and cross-checked against the vendor commitc4837c66in zm-build. - The adapted lab chain executed a canary and a bounded-impact demonstration as the
zimbrauser, with restoration after the test. - The patched implementation, which moves to
system()with multiple arguments, did not execute the identical canary while the unpatched branch did, with a live positive control. - Sigma, YARA and Suricata matched the recorded artifacts of the lab run, with their transcripts published.
- CISA KEV lists CVE-2026-73570 with
dateAdded2026-08-21 anddueDate2026-08-24; the fix studied is ZCS 10.1.20, and CERT Polska reported active exploitation.
you@nullsector:~$ mail miguel
Collaborations, talks, press or research: write to me.
Need a pentest or a vulnerability assessment? Request it at Xpectra.ai ↗