# IR Playbook — Zimbra compromised via CVE-2026-73570 > Xpectra Security Research · 2026-08-24 > Audience: incident responders on a ZCS < 10.1.20 host with an indication of > the swatch/dosnmp command injection (or any unexplained zimbra-user shell). > Lab-validated commands; adjust paths for your ZCS layout. ## Phase 0 — Triage (0-30 min, read-only) Goal: confirm the chain **SMTP → zimbra.log → swatchdog → sh -c** and find the scope. ```bash # 1) Is the sink firing? swatchdog's stdout records every notification grep -n "SNMP notification:" /opt/zimbra/log/zmswatch.out | tail -20 # -> look for shell syntax in the line: $( , base64, /dev/tcp, |sh, |bash # 2) The injection attempt at the log level (works even if patched) grep -nE 'to=<"??\$\(' /var/log/zimbra.log /var/log/mail.log | tail -20 # -> note the source IPs and the crafted local-parts (attacker TTPs) # 3) Live process tree of the zimbra user (catch it red-handed if active) ps -ef | grep -v grep | grep -E 'sh -c|/dev/tcp|base64' pstree -au 2>/dev/null | grep -A3 -B3 swatchdog # 4) Defacement check (our PoC TTP; real attackers deface too) md5sum /opt/zimbra/mailboxd/webapps/zimbra/skins/_base/logos/LoginBanner.png \ /opt/zimbra/mailboxd/webapps/zimbraAdmin/skins/_base/logos/LoginBanner.png # -> compare with your clean baseline (see ioc/CVE-2026-73570.ioc.md §3) # 5) zimbra-owned files created recently (staging / canaries / webshells) find /tmp /var/tmp /opt/zimbra -user zimbra -newermt "14 days ago" -type f 2>/dev/null | head -40 find /opt/zimbra/mailboxd/webapps -user zimbra -newermt "14 days ago" -type f 2>/dev/null | head -40 # 6) Persistence hunting (the zimbra user and anything root-level it could reach) crontab -l -u zimbra 2>/dev/null; ls -la /var/spool/cron/ 2>/dev/null grep -rn "zimbra" /etc/crontab /etc/cron.d/ 2>/dev/null ls -la /root/.ssh/ /home/*/.ssh/ 2>/dev/null # authorized_keys additions # 7) Egress history (reverse shells / exfil) — netflow or conntrack if available # Look for zimbra-host -> external high-port sessions, especially recurring. ``` **Decision gate:** if (1) or (2) shows attacker payloads, or (4) shows a hash change → treat as confirmed compromise, go to Phase 1. If nothing found → expand to 30-day window, re-run, and consider the detection rule set as the ongoing control. ## Phase 1 — Containment (30-60 min) Order matters: cut the attacker's **current** capability first, preserve evidence. 1. **Kill the active chain** (only processes you identified in Phase 0 — take `ps` output first as evidence): ```bash kill -9 ``` 2. **Disable the sink** so the chain cannot re-fire while you work: ```bash su - zimbra -s /bin/bash /opt/zimbra/bin/zmlocalconfig -e snmp_notify=0 /opt/zimbra/bin/zmcontrol stop zimbra-snmp ``` 3. **Network containment**: - Block egress from the Zimbra host to the attacker IPs/ASNs seen in Phase 0 (reverse-shell beacon + any exfil destinations). - If the box is internet-facing and mail flow allows, temporarily restrict inbound SMTP to known senders/relay partners (coordinate with mail ops — this degrades service; time-box it). 4. **Credential hygiene**: the `zimbra` user can read all mail. Rotate any local/service credentials stored on the host; consider forced re-auth for admin console sessions from that host. 5. **Preserve evidence before eradication** (forensic discipline): ```bash tar czf /evidence/zimbra-ir-$(date +%F).tgz \ /opt/zimbra/log/zmswatch.out /var/log/zimbra.log /var/log/mail.log \ /opt/zimbra/conf/swatchrc sha256sum /evidence/zimbra-ir-*.tgz # record the digest # + full memory/disk image per your IR SOP ``` ## Phase 2 — Eradication (60-240 min) 1. **Restore the web assets** (defacement): - Reinstall stock `LoginBanner.png` for webmail and admin from a clean package/baseline (or the backup in `/root/deface-backup/` in our lab — in production: from a known-good build). Re-hash and compare. 2. **Remove attacker artifacts**: every file from Phase 0 step 5 that is not explained by normal operation; webshells in webapps; crontab entries; SSH keys. 3. **Purge the poisoned mail queue entries** (the crafted messages): ```bash postqueue -p | grep -n "" # identify postsuper -d # remove ``` 4. **Rebuild trust**: if the host shows root-level tampering you cannot fully explain, rebuild from a clean image and restore data from a pre-compromise backup. The cost is lower than living with unknown residue. ## Phase 3 — Recovery & verification 1. **Upgrade to 10.1.20 first** (or apply interim mitigation 1 if the upgrade is delayed — see `remediation.md`). 2. Bring mail services back in maintenance mode → test → production. 3. **Verify the sink is dead**: ```bash python3 detection/detect_snmp_sink.py --audit # version + sink python3 detection/detect_snmp_sink.py --active --local-canary # expect: NOT VULNERABLE / SINK DID NOT FIRE ``` 4. Deploy the permanent detection set (`rules/`) before re-exposing the box. 5. 30-day enhanced monitoring: alert on any zimbra-user shell, any `to=<$( ` log line, and banner hash drift. Re-run the canary at day 30. ## Phase 4 — Lessons learned (retro checklist) - [ ] Why did the host run with SNMP notifications enabled? (default-on? legacy?) - [ ] Was the box in mynetworks/relay scope wider than needed? - [ ] Did mail-gateway logs see the `$(` RCPT earlier than the host (earlier detection point)? - [ ] Detection coverage: which of our 5 Sigma rules would have fired first, and how fast? - [ ] Patch SLA: KEV listed 2026-08-21; our host was still < 10.1.20 on . Close the gap. - [ ] Add the Zimbra host to the quarterly canary self-test calendar. ## Communication (template) > Incident : Confirmed exploitation of CVE-2026-73570 (unauthenticated RCE > as zimbra) on . Timeline: first malicious RCPT observed ; shell > activity ; containment . Impact: mailbox data exposure (zimbra user), > webmail defacement, . Attacker egress to . Recovery: host > , sink disabled, detections deployed. Status: .