Events Join us at the AWS Summit in Dubai on 30th September
Read

Hackers Turned Zimbra’s Own Health Monitor Into a Backdoor

Zimbra CVE-2026-73570 let attackers drop web shells, grab signing keys and read mail without a login. 274 servers hit. Patch to 10.1.20 today.

TL;DR: A mail server that watches itself for trouble ended up running an attacker’s commands. Hundreds of Zimbra servers were breached that way, and no login prompt stood between the attacker and the server.

What Happened?

Synacor shipped Zimbra Collaboration Suite 10.1.20 on July 20, 2026. It included a quiet fix for CVE-2026-73570, an unauthenticated command injection flaw rated 8.9. The CVE itself stayed unpublished for 24 days.

Attackers did not wait. Microsoft Threat Intelligence tracked two scanning tools probing the injection point between July 28 and August 7, before any advisory existed. The probes carried a CVE-specific ZB73570 user agent and used DNS, ICMP, and HTTP callbacks to confirm the servers were executing commands.

The flaw sits in swatchdog, part of the optional zimbra-snmp package. A crafted SMTP request can carry shell characters into an snmptrap call. When a service state change triggers health monitoring, those characters run as the zimbra account. No password. No click.

Poland’s national CERT confirmed exploitation in the wild in mid-August. Shadowserver counted 155 compromised servers on August 20 and 274 two days later, a roughly 77% jump in 48 hours. CISA added the CVE to its Known Exploited Vulnerabilities catalog on August 21 and gave federal agencies until August 24. More than 8,200 unpatched instances were still reachable.

Indicators of compromise CVE-2026-73570 · Zimbra Collaboration Suite · CVSS 8.9

Zimbra SNMP command injection: published indicators

Compiled from published vendor and national CERT reporting on exploitation observed between July and September 2026. Infrastructure rotates, so treat the host artifacts and behaviour patterns as the durable part of this list and the network values as a point in time snapshot. Values are defanged as published.

Network infrastructure

IndicatorTypeRole
117.107.25[.]243:7071IPv4 C2Dropper C2 serving de.sh
192.255.193[.]111:9004IPv4 C2Miner C2 serving build_amd64, staged as .kworker_sys
45.32.30[.]235:8081IPv4 C2Reverse shell, earliest confirmed C2 in the campaign
45.32.30[.]235:8080IPv4 C2Same host, interactive session and mail store staging
193.42.40[.]135:443IPv4 C2Organisation wide reverse shell and recon wave
3.209.137[.]175:443IPv4 C2Secondary C2 after infrastructure rotation
transzimbra[.]linkpc[.]netDynamic DNSDropper C2 serving agent.sh, agent2.sh and zimdown2
psk1zim[.]abrdns[.]com/agentwsDynamic DNSzimclient2 WebSocket channel on port 80, raw TCP on 8080
tls[.]psk1zim[.]abrdns[.]comDomainzimclient2 TLS command channel on port 443
wslogzimbra[.]linkpc[.]net/wsstatWebSocket URLzimdown2 installer status reporting, separate from payload hosting
mexico-cashpay-test.s3.dualstack.mx-central-1.amazonaws[.]com/pakistan/2026/aliyun_update.tar.gzS3 URLTarball dropper, confirmed executed on one host and retried elsewhere
0x25bdA7Feb3553995AD68a9A8Ed8c731b73a71586ContractDead drop command channel polled over public JSON-RPC by the memfd stage

Scanning and validation signatures

IndicatorTypeRole
ZB73570User agentCVE specific string used in HTTP validation probes, July 28 to August 7
oast[.]fun, oast[.]online, dnslog[.]pp[.]ua, requestrepo[.]comCallbackOut of band collaborator services used for execution confirmation
bypass[.]eu[.]orgCallbackCampaign associated callback infrastructure

File hashes (SHA-256)

HashFile
dee5af1c0f76b45d28bafd6e60c07bb8e391d98addf81ef8f13d073acdb3c48ade.sh dropper script
6ab7de2509038edf580aef6229c1c3db17f4da8f2d7d940818faf617d1938244agent2.sh stage 1 downloader
bf28f38122bf20d5fac969cc414daa6a890cdea872d389ca93d2092b6b7773cfzimdown2 Go installer
b594a42b8f1c6f090327bb9a3361c2d3515537fb7ac8da6b9061b9a3f330e159zimclient2 remote access agent
aea991f694911e321b0ab97534f2ad0291c392c0a43dabff664c563618bd036dbuild_amd64 cryptominer
65a7576c389326b6cdf9c993d0be6e5d50fed9655d1cdf2a3a50f2c21c8ec435Privilege escalation toolkit, quarantined as Looptik
22ef852f6ebc39ee71235b90648b4b200b385c47d25c79545986493f8c70db69Loader staged as systemd-resolved, installs /usr/sbin/_chronyd
518fe65dd349180191d9b258ab24876aaed6613cd657d0b626d1fc24e03a22b6Decoded in memory stage 2 command agent

Host artifacts to hunt

ArtifactCategoryWhat it means
zimlog.service, chronyd-helper.service, syslog_init.servicePersistenceUnits installed outside Zimbra directories and timestomped to match rsync.service or sshd.service
/etc/sudoers.d/81_metricPrivilege escalationNOPASSWD entry created for the zimbra account through a pam_exec hook
/etc/pam.d/sudo modified, zmmailboxd.out replaced by a symlinkPrivilege escalationPAM config briefly owned by the zimbra account, original content restored afterwards
Unexpected .jsp or *_jsp.java in /opt/zimbra/jetty*/webapps/, /mailboxd/webapps/, /work/zimbra/jsp/Web shellRedundant shells copied to peer mailbox nodes. Removing one does not remove access
.kworker_sys, .lpe_core, /tmp/init, /dev/shm/systemd-resolved, _chronydMasqueradingPayloads named to resemble kernel or system components
/tmp/s named pipe with openssl s_clientC2Encrypted reverse shell built from standard Linux utilities
/tmp/zimbra_dump_YYYYMMDD_HHMMSS/CollectionStaging directory for credential and certificate dumps before zipping
/opt/zimbra/final.tar.gz, five.ico in the public web directoryCollectionMail store archives staged locally, one saved with an image extension
azcopy, aka[.]ms/downloadazcopy-v10-linux, wsweb03[.]blob[.]core[.]windows[.]net/log/windows.logExfiltrationCloud transfer tooling and the blob target used in the attempt
snmptrap invocation followed by shell metacharacters, wget or curl, and a trailing #InjectionThe highest confidence signature of exploitation itself
HISTFILE=/dev/null, zmslapcat, zmlocalconfig -s, memfd_create executionHands on keyboardOperator activity, credential discovery and memory backed execution

Scope note. Several of the worst outcomes in this campaign involved no named malware family at all, only a plain interactive shell. A clean antivirus result on a reachable Zimbra server is not evidence of a clean server. Compiled by Secure.com from published reporting. Verify against your own vendor advisories before loading into detections.

The Impact

A shell was only the opening. Attackers rebuilt encoded fragments into JSP web shells across Jetty and mailboxd directories, copied them to peer mailbox nodes, briefly opened write access on a public directory, then restored permissions so a routine check shows nothing odd.

Then they took the signing keys. zimbraAuthTokenKey signs session tokens for every account on the platform. zimbraPreAuthKey builds working login URLs for any user. zimbraTwoFactorAuthSecret covers the second factor. Resetting user passwords does nothing about any of them.

Root came through a symlink into the sudo PAM configuration that ended in a passwordless sudo rule for the zimbra account, plus a fake zimlog.service unit timestamped to match rsync and sshd. On one server, the operators archived the mail store as final.tar.gz, downloaded AzCopy, and aimed it at an Azure Blob container. The existing Zimbra SSH identity carried the same tooling to every other node in the cluster.

Attack chain · no login, no click

One email, and the mail server runs the sender’s commands

The weak point is the monitoring, not the mailbox. Shell characters carried in a crafted SMTP request reach the SNMP notification path, where the health watchdog hands them straight to a shell.

01
Crafted SMTP request arrives
Untrusted input carrying shell metacharacters enters SNMP notification processing. No authentication and no user interaction needed.
02
The watchdog executes it
A service state change triggers health monitoring. swatchdog folds the attacker value into an snmptrap shell call, which runs as the zimbra account.
03
Web shells land, permissions snap back
Encoded fragments are rebuilt into JSP web shells across Jetty and mailboxd paths. Write access on the public directory is opened, used, then restored so a routine check looks clean.
04
Root through the PAM file
A writable log path is swapped for a symlink to the sudo PAM config, a pam_exec hook fires as root, and a passwordless sudo entry for zimbra survives the cleanup.
05
Signing keys and service credentials pulled
LDAP, MySQL and Postfix credentials come out of local config, then authenticated queries retrieve zimbraAuthTokenKey, zimbraPreAuthKey and zimbraTwoFactorAuthSecret.
06
The cluster goes with it
The existing Zimbra SSH identity carries shells and tooling to peer mailbox nodes over rsync. One archive of the mail store was staged as final.tar.gz for an attempted cloud transfer.

Why this bites twice: patching closes the injection point. It does not invalidate a stolen token signing key, and that key mints valid sessions for every account on the platform.

How to Avoid This

  • Upgrade to 10.1.20 or later. If an upgrade has to wait, remove the zimbra-snmp package, turn SNMP notifications off, and restrict SNMP and SMTP to trusted hosts.
  • Treat any reachable server that ran a vulnerable build as compromised until evidence says otherwise.
  • Rotate zimbraPreAuthKey across every domain, then auth token keys, two-factor secrets, and the LDAP, MySQL, Postfix, and Amavis service credentials. A patch does not revoke a stolen key.
  • Hunt for unexpected .jsp and _jsp.java files in Jetty, mailboxd, and servlet work directories on every node, not only the one that alerted.
  • Review systemd units, /etc/sudoers.d, /etc/pam.d, and cron entries for anything dressed up as a logging component.