The Patch Was Not the Fix: VMware vCenter CVE-2026-59310 and the reverse_ssh Persistence Backdoor

A five-day exploitation window, a reverse SSH backdoor, and a patch that closes the front door while the channel stays open. The vCenter triage.

Share

Executive Summary

On July 29, 2026, Broadcom published VMSA-2026-0006.1 with fixes for a directory traversal in the VMware vCenter Syslog server, CVE-2026-59310. The flaw is unauthenticated, it scores 9.8 Critical, and Broadcom lists no workaround. Five days later, on August 3, the first exploitations started. The actor that followed the patch wrote cron jobs straight into /etc/cron.d, dropped a downloader, and installed a standing outbound channel on the compromised appliance: a build of reverse_ssh, an open-source Go reverse-shell tool, registered as a systemd service the attacker named network-manager.

QUIRSO, the German incident-response firm tracking the campaign, counts 361 unique victim IPs across 47 countries, with roughly 95 percent of them hit by August 5. The count is IP-based, not host-based. Some of those addresses sit behind NAT or belong to hosting and cloud providers, so read it as a measure of scale, not as a count of organizations. CISA added the CVE to its Known Exploited Vulnerabilities catalog on August 18, with an August 21 due date under BOD 26-04, and the ransomware marker on the catalog entry is Unknown. The documented endgame here is the standing channel, not the encryption.

The patch closes the syslog front door. It does not touch the reverse SSH channel, the cron job, the systemd unit, the webshell, or any of the accounts the actor created. If your vCenter syslog server was reachable before you patched, the operating assumption should be that the appliance is compromised, and the patch is the first action, not the response.

Five Days From Patch to Persistence

The fixed builds are cumulative: 9.1.0.0300 on the 9.1 line, 9.0.2.0100 on the 9.0 line, and 8.0 U2f or U3k on 8.0; the advisory was revised August 3. The same VMSA also covers CVE-2026-59309, an authentication bypass in VMware Directory Service with the same 9.8 score. It is a different flaw on a different component and is not the KEV entry; coverage that conflates the two is wrong.

The first exploitation on the appliance QUIRSO analyzed landed at 05:47:01 UTC on August 3; Shadowserver's victim telemetry shows first seen the same morning. By August 4 the campaign had hit 151 new victim IPs in a day, its peak, and about 95 percent of the final 361 appeared by August 5. That is a fast campaign, but the number that matters for your response is not 361. It is the five days between disclosure and the first hit. Heavily targeted vendors get weaponized inside a patching cycle, and the window for a fleet that patches weekly is closed by the time the patch lands.

The primary account is QUIRSO's, published August 10 with the victim count and the YARA rule, and followed on August 14 with the full attack-chain reconstruction from one analyzed appliance. Rob Wright's Dark Reading coverage of August 13 put it in broader context: a global campaign under heavy exploitation days after disclosure, "the short window between public disclosure and active exploitation for heavily targeted vendors like VMware." Dark Reading notes the attacks so far appear to be limited to the one suspected APT actor, no group named. QUIRSO describes the actor as a suspected APT, at moderate confidence, and stops there. I will too.

The Front Door and the Back Door

The vulnerability is in vCenter's syslog server, the component that receives remote syslog traffic. A directory traversal in it, CWE-22, lets a network-reachable attacker write files outside the intended directory; here the write lands where a shell already runs, in /etc/cron.d. The first artifact found on the analyzed appliance was a malformed cron file named zz-poc59310-syslog.log. The name references the CVE, the suffix mirroring vCenter's own remote-syslog naming. The traversal hands a non-interactive root shell; no local privilege escalation was needed.

That is the front door. The back door is what the cron file installs. A root cron entry, running every minute, downloads esxi.sh from 185.144.28[.]120:3232 and pipes it to sh. The script detects the architecture, fetches the matching binary (esxi_amd64 on x86_64), and installs it as a systemd service named network-manager, set to restart on failure. Without root, the same script falls back to SysV init, rc.local, cron, or a background launch, and checks for passwordless sudo to escalate.

The client on the appliance initiates the SSH connection to a server the attacker controls, and the connect-back address is baked into the binary at compile time, so the dropped file is self-contained. The session looks like ordinary egress, outbound TCP from a management appliance to an unfamiliar host, exactly the traffic nobody reads on a busy network. That is what makes the channel invisible to an inbound-focused firewall, and what makes it outlive the patch.

The Backdoor's Name: reverse_ssh

reverse_ssh is not malware and not a campaign build. It is an open-source, dual-use, Go-based SSH reverse-shell framework from the NHAS project, BSD-3 licensed, roughly 1.4k stars on GitHub. The project README describes exactly the capability the actor used: a client that bakes in a connect-back address, reconnects automatically, does mutual key authentication with the server's public-key fingerprint burned into the client, and carries file transfer, TUN/VPN, and fileless in-memory execution via memfd. By default the client daemonizes, the parent exits, and the daemon keeps running.

The transport is not fixed to port 22. The client can ride SSH, HTTP, HTTPS, WebSockets, or TLS, and in this campaign the observed channel was plain SSH, with SSH--linux_amd64 client version strings in the victim telemetry. That flexibility is why the detection below hunts egress in general, not one port. On disk the observable artifact is a single statically linked Go binary carrying github.com/NHAS/reverse_ssh/ package paths in its build metadata, and the running process is whatever the attacker named the file, in this campaign esxi_amd64, esxi, or systemlog. Process-name hunting is a dead end. The Go build metadata is the signature.

There is a second implant, and it is not reverse_ssh. Before the reverse SSH deployment, the campaign dropped a backdoor called linuxFile, a WebSocket client to ws://intel.se9ly9upbhay.shop:8080/ws with the C2 address XOR-obfuscated and decoded at runtime, app-layer crypto over an unencrypted ws:// connection, auto-reconnect, and persistence through a systemd unit, sys-9436d8.service, and cron. A copy persisted at /root/.local/share/cg4nQW9TOxeq/. QUIRSO ships a separate YARA rule for it. Two implants, two rules. Catching one does not find the other.

The staging picture completes the map: a central directory at /tmp/.x/, payloads also pulled from tmpfiles.org, from 192.255.141[.]13:8080, and from 5.34.176[.]100:5244, an AList file-listing web app repurposed as a payload repository. The anti-forensics layer is hidden dotfiles in /tmp (.vmware-perf-upd.sh, .ldappw, .sso_domain), cron names masquerading as VMware components, post-execution script deletion, and a Go daemon called tmpclean that deletes /tmp entries older than 24 hours, hourly. The tmpclean releases also bundled updated reverse_ssh binaries, which QUIRSO reverse-engineered to confirm were the attacker's builds.

What the Actor Leaves on Disk

The placement map from the analyzed appliance, the pattern to work from on yours:

Path / name Role
/etc/cron.d/zz-poc59310-syslog.log, zz-poc59310 Traversal-placed cron, initial access
/tmp/.x/, also /tmp/ Central staging directory
esxi.sh Downloader plus persistence installer for reverse_ssh
esxi_amd64, esxi, systemlog The reverse_ssh client binary, arch-specific, name varies
systemd unit network-manager Root persistence for the reverse_ssh daemon
systemd unit sys-9436d8 Persistence for the earlier linuxFile backdoor
/root/.local/share/cg4nQW9TOxeq/ Copy of the earlier linuxFile backdoor
/etc/cron.d/vmware-vpxd-stats-*, vmware-perf-collect-*, vmware-perf-sync-* Masqueraded cron: SSH key-in, webshell drop, account creation
/etc/sudoers.d/vmware-perf Passwordless root sudo for the perfcharts account
/usr/lib/vmware-perfcharts/tc-instance/webapps/statsreport/vmware-perf-update.jsp JSP webshell
/tmp/.vmware-perf-upd.sh, /tmp/.ldappw, /tmp/.sso_domain Hidden credential-access artifacts

Every persistent artifact is named after a legitimate VMware component, and that is the anti-forensic technique. network-manager sounds like a networking service; vmware-perf-collect-* sounds like a performance collector. The hunt runs on behavior and placement, not on any single string. One of the masqueraded cron jobs re-adds the attacker's SSH key to root's authorized_keys on a schedule and disables root password login, so the cron entry and the key are one persistence loop.

The Detection That Actually Caught It

On a management appliance, the strongest signal of compromise is a network connection the operator does not recognize. The channel is outbound and it is new, so the first sweep is the live connection table:

# On the vCenter appliance, as root. Repeat after every reboot during triage.
netstat -tnp | grep ESTABLISHED
ss -tnp

Filter out what you expect: time sync, DNS, patch-repository traffic during a maintenance window. You want an outbound session to a host the appliance has never talked to, on a port that is not 53 or 123. In this campaign the observed channel was plain SSH to non-standard ports, but the client can present over HTTP, WebSockets, or TLS, so the rule is any new egress from the management plane, and the port is not the detection. On the analyzed host the first exploitation was at 05:47:01 UTC on August 3, so an egress event inside roughly August 3 to 9 to an unmapped peer is the lead that drives the rest of the sweep. A clean egress hunt does not clear the host; tmpclean means the on-disk trail is already partially erased.

The artifact-specific detector is QUIRSO's YARA rule, Tool_NHAS_Reverse_SSH_Client, published in the QTRDetectionContent repository as 2026-08-10_reverse_ssh_generic.yar. The rule matches the Go build-info magic, two or more github.com/NHAS/reverse_ssh/ package paths embedded in the binary's build metadata, and two or more client configuration strings, with a 100 MB file-size gate. I compiled it with yara-python and ran functional tests against synthetic samples: one positive, four negatives, all correct. The 2-of plus 2-of condition is what keeps it specific; the negative tests confirmed it.

Two caveats, both from QUIRSO's own rule metadata. First, this is a dual-use signature: a match identifies reverse_ssh code, it does not establish that the code is malicious, because legitimate penetration testers run the same tool. On a vCenter host there is no legitimate reason for it to be there, so a match is a high-priority lead, and the egress, cron, and timeline correlation turns it into a verdict. Second, QUIRSO withheld campaign-specific hashes pending law-enforcement coordination, so there is no hash list to grep, and a heavily modified build can evade the string matches. That is why the behavioral layer is what actually caught this campaign.

Run the same rule across the ESXi estate, plus QUIRSO's separate rule for linuxFile. Then the filesystem sweep: fresh executables in /tmp and /var/tmp (mtime is the only signal left after tmpclean), hidden dotfiles, the staging directory. Then cron and systemd: crontab -l and /etc/cron.d/ for the zz-poc59310* files and anything piping a remote fetch into a shell, systemctl list-units for network-manager and sys-9436d8. Then the access layer: root's authorized_keys, the perfcharts JSP webshell, every file in /etc/sudoers.d/, and the vSphere SSO accounts created in the window: adminuser, vcadmin, vcenter_admin. No single artifact is the verdict: the egress in the window, plus any two of the persistence, file, and account changes, is a confirmed compromise. One of them, with no correlation, is an open question, not a close.

Downstream of the vCenter, on the ESXi hosts, the actor dropped a local adminuser on each host and deployed a Babuk-derived ransomware, a binary named backup with the SHA1 e876ceb47ba092420a97724a957152b3808568b0, encrypting VMDKs with a .babyk extension, the first 512 MB of each disk partially encrypted, the vmware-fdm VIB removed. QUIRSO treats the ransomware as a smokescreen, not the objective. The channel is the incident.

Containment: Rebuild, Don't Sanitize

Isolate the appliance from the network while it stays powered, because a live capture is worth more than a clean rebuild: take a memory capture, image the disk, and pull every log to off-box storage before anything is touched. The vCenter appliance is the single control point for the VM estate; assume the hosts it manages are reachable from the compromise.

Rebuild, do not sanitize. The configuration of a compromised vCenter is untrusted, because the actor had root and wrote into the configuration's own directories. Re-image from the fixed patch media, 9.1.0.0300 on the 9.1 line, 9.0.2.0100 on the 9.0 line, 8.0 U3k or U2f on 8.0. Restore configuration only after reviewing it for the artifacts above, and treat the SSO store as suspect. Rotate every credential the management plane touches: vCenter SSO administrators, ESXi root and local accounts, every SSH key in the estate. Rebuild the ESXi hosts that show the local adminuser or the ransomware artifacts. The patched version is the floor, not the action.

The Homelab Version of This Pattern

Most readers of this are not running vCenter, and I would rather say that plainly than pretend otherwise. The vCenter campaign is the enterprise instance of a pattern that maps directly to the home management surface: a single flaw that lets an unauthenticated actor execute code, plus an outbound channel the actor installs, gives you persistence that no patch removes. The triage above transfers to the boxes you actually run, with the same four hunts and the same correlation.

On a Proxmox VE node, the vCenter equivalent at home, the management plane is the entire lab: compromise the PVE node and you compromise every VM it runs, for the same reason the vCenter estate falls. Proxmox carries its own traversal history: the pveum component, the PVE Manager API, has had path-traversal CVEs, the same class of flaw as the vCenter syslog traversal. That is a pattern mapping, not a claim that this campaign touched Proxmox. The hunt is identical: egress from the node that is not the apt or PVE mirrors, DNS, or a relay; cron entries and systemd units with masqueraded names; hidden executables in /tmp; authorized_keys you did not place. At home the egress signal is cleaner, because a Proxmox node's expected outbound traffic is narrow: any outbound SSH or long-lived connection to an unfamiliar IP is a finding until proven otherwise.

On pfSense, the box is the boundary, which changes the detection. The firewall already logs every packet that crosses it, so if the box itself is compromised, the flow log is the detector: outbound flows from the firewall's own interface IP to hosts that are not your upstream, your DNS, or your package mirror. The host-side hunt is the same four steps: cron, authorized_keys, unknown services, fresh binaries. pfSense has shipped directory-traversal fixes in the 2.8.x line, the same vulnerability class, and the single highest-value change the pattern points to is keeping the WebGUI off the internet.

The shared lesson: the management surface is the key, and a compromise of one of these boxes is a compromise of the whole setup. The response is never the patch alone.

What the Operator Keeps

The patch closes the front door. The backdoor stays open until you find it. That is the whole thesis, and it is why the order is detection-first in the sense that detection is what confirms the fix, not the patch.

The standing posture is three things. Keep the management plane off the internet, or behind a VPN with an ACL that lists every client, because the syslog server, the PVE Manager, and the pfSense WebGUI are all the same kind of surface. A traversal in any of them is a traversal to root on the box that holds your keys. Put the logs off-device, because in every incident in this pattern the on-device log is the attacker's cleanup target, and a log the attacker can reach is a target, not a log. Rotate the management credentials at the moment of the CVE window, not after, because the window is when the keys are burned.

That is the craft of it. The patch is a number on a release page. The triage is the egress hunt, the cron sweep, the YARA pass, and the correlation across the exposure window, and it is the part that actually removes the backdoor.

Further Reading

For the bigger picture of this attack class, the remote-access appliance cluster I covered this quarter walks four product lines and seven CVEs with the same trust-boundary failure: Beyond the Appliance: What Q3's Remote-Access Cluster Teaches Us About Management-Surface Defense.

References

  1. Broadcom VMSA-2026-0006.1, VMware vCenter directory traversal and related advisories, published 2026-07-29, revised 2026-08-03. https://support.broadcom.com/web/ecx/support-content-notification/-/external/content/SecurityAdvisories/0/38017
  2. CISA Known Exploited Vulnerabilities Catalog, entry CVE-2026-59310, added 2026-08-18, due 2026-08-21, BOD 26-04, ransomware marker Unknown. https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  3. CISA alert, "CISA Adds Four Known Exploited Vulnerabilities to Catalog," 2026-08-18. https://www.cisa.gov/news-events/alerts/2026/08/18/cisa-adds-four-known-exploited-vulnerabilities-catalog
  4. NVD, CVE-2026-59310. https://nvd.nist.gov/vuln/detail/CVE-2026-59310
  5. QUIRSO, "Active exploitation of CVE-2026-59310: 361 victim IPs across 47 countries," Medium, 2026-08-10. https://medium.com/@quirso_de/active-exploitation-of-cve-2026-59310-361-victim-ips-across-47-countries-9783187cc6ff
  6. QUIRSO, "Global Exploitation of CVE-2026-59310," Medium, 2026-08-14, Orlikowski / Yürekli / Szadkowski. Full attack-chain reconstruction from the analyzed appliance. (URL not captured in the source record; cited by title and date.)
  7. QUIRSO Threat Research, YARA rule 2026-08-10_reverse_ssh_generic.yar, QTRDetectionContent repository. https://github.com/QUIRSO/QTRDetectionContent/blob/main/2026-08-10_reverse_ssh_generic.yar
  8. NHAS, reverse_ssh, open-source Go SSH reverse-shell framework, project README (connect-back, transports, memfd, daemonization). https://github.com/NHAS/reverse_ssh
  9. Shadowserver, VMware vCenter CVE-2026-59310 exploitation victim special report, 2026-08-13 (first-seen telemetry, victim IP list, cloud/hosting skew note). https://www.shadowserver.org/what-we-do/network-reporting/vmware-vcenter-cve-2026-59310-exploitation-victim-special-report
  10. Rob Wright, "Global Threat Campaign Hits Critical VMware vCenter Flaw," Dark Reading, 2026-08-13. https://www.darkreading.com/vulnerabilities-threats/global-threat-campaign-critical-vmware-vcenter-flaw
Topics: