Netwrix 1Secure offre visibilità unificata su dati e identità - gratuito per 14 giorni con accesso completo.Inizia una prova gratuita

Centro risorseBlog

Scoprire percorsi di attacco indiretti ai controller di dominio virtualizzati in Azure

Scoprire percorsi di attacco indiretti ai controller di dominio virtualizzati in Azure

Sep 24, 2026

Nel team di Netwrix Security Research, stavamo aiutando un cliente con una valutazione di Entra ID e sapevamo che avevano già fatto il tiering di AD on-premise. Sapevamo anche che avevano controller di dominio virtualizzati in Azure, ma era difficile capire quale server Windows fosse effettivamente un DC. Abbiamo scoperto che Azure Run Command consente di eseguire comandi come SYSTEM, quindi l’abbiamo usato per fare ricognizione e identificare i DC.

Tutto ciò che viene mostrato in questo post (screenshot, nomi delle macchine, nomi utente) proviene da un ambiente di laboratorio che abbiamo ricostruito successivamente per dimostrare la tecnica. Nessuno è dato cliente.

Per contesto, la documentazione di Microsoft descrive Run Command come un modo per eseguire script PowerShell all'interno di una VM Windows tramite l'agente VM, principalmente per attività di gestione generale come risolvere problemi di accesso o di rete su una macchina. Tuttavia, non verifica che tipo di VM stia gestendo. Funziona tranquillamente su un controller di dominio come su qualsiasi altra VM.

Abbiamo deciso di creare un script PowerShell con Claude che ci permette di eseguire un comando su più macchine Windows contemporaneamente, invece di cliccare nella console Esegui comando una VM alla volta. Serve solo il permesso Microsoft.Compute/virtualMachines/runCommand/action, incluso in Virtual Machine Contributor o superiore.

Il trucco è eseguire ogni chiamata Invoke-AzVMRunCommand dentro un ThreadJob invece del solito Start-Job. Start-Job avvia un nuovo processo PowerShell per ogni VM e ricarica il modulo Az ogni volta, rallentando rapidamente oltre poche macchine. ThreadJob gira su un thread nello stesso processo, quindi avviarne molti insieme costa quasi nulla. Manteniamo una coda di tutte le VM trovate e la riempiamo fino a un numero fisso in esecuzione contemporanea (20 di default). Riempiamo uno slot appena uno termina, senza aspettare che finisca tutto un lotto prima di iniziare il successivo.

Ecco come appare l'esecuzione di whoami tramite il portale per una macchina alla volta:

Image
Figure 1. whoami run through Azure's Run Command, returning nt authority\system

Ecco lo stesso comando eseguito su tutte le VM nella sottoscrizione contemporaneamente, tramite lo script PowerShell:

Image
Figure 2. whoami running against all four VMs at once through the script, responding as nt authority\system

Con questo funzionante, il passo successivo è stato trovare i DC. Il controllo è semplice: eseguire Get-Service NTDS su ogni VM Windows attiva tramite Run Command. NTDS è il servizio che gestisce il database AD DS, quindi se è presente e in esecuzione, quella macchina è un controller di dominio.

Una VM era chiaramente attiva, ma Run Command ha restituito un errore invece di rispondere, mentre tutte le altre VM nella sottoscrizione hanno risposto correttamente. Il nome da solo era già un forte indizio. Il fallimento di Run Command è esattamente ciò che ci si aspetterebbe da un controller di dominio ben protetto, con strumenti di sicurezza più rigidi che ostacolano. Prendere quell’errore alla lettera e andare avanti avrebbe significato segnalare zero controller di dominio nella sottoscrizione.

Image
Figure 3. the script checking every VM for NTDS, then flagging GOBIAS-DC01 as unconfirmed and offering a domain-joined VM to run LDAP recon from

Invece di fidarci dell’errore, abbiamo interrogato direttamente AD. Qualsiasi VM unita al dominio raggiungibile da Run Command viene usata per interrogare AD tramite LDAP. Non serve il modulo Active Directory, solo [adsisearcher], un acceleratore di tipo PowerShell integrato che funziona già su qualsiasi macchina unita al dominio.

Il controllo è un bit userAccountControl chiamato SERVER_TRUST_ACCOUNT, valore 8192. AD lo imposta solo quando un computer è promosso a DC. Abbiamo aggiunto due controlli: gruppo primario 516 (il gruppo "Domain Controllers") e un oggetto NTDS Settings corrispondente nella partizione Configurazione.

Una cosa però: un hostname corrispondente da solo non prova che sia questa VM, né che sia in Azure. I nomi cambiano, vengono troncati e a volte riutilizzati. Quindi controlliamo prima l’IP, risolvendo il hostname del DC in un IP dall’interno del dominio e confrontandolo con l’IP privato che Azure stesso riporta per quella VM. Quell’IP esiste solo se la macchina è davvero in Azure, quindi una corrispondenza lì è il più solido possibile. Quando il DNS non risolve, ricorriamo al confronto dei nomi host, anche se lo consideriamo meno affidabile perché i nomi possono cambiare in modi che gli IP non fanno.

Image
Figure 4. LDAP recon confirming GOBIAS-DC01 as a Domain Controller and matching it to the Azure VM by private IP, even though Run Command couldn't reach it directly

Una volta confermato con certezza che la macchina che aveva dato errore prima era un controller di dominio, la vera domanda era chi potesse eseguire comandi arbitrari come SYSTEM su di essa, poiché questo tipo di accesso è Tier-0, punto. Non è chi ha Domain Admin; il cliente aveva già gestito questo con la loro classificazione. È chi ha permessi Azure su quella specifica VM, perché Run Command non considera nulla in AD. Conta solo Azure RBAC.

Ecco come appare. Alcuni utenti compaiono più di una volta (una riga per ruolo), insieme a un gruppo e due service principal, tutti con Owner o Contributor da qualche parte nella catena, per lo più ereditati dalla Subscription e non assegnati direttamente alla VM. Ognuno di loro può invocare Run Command contro un controller di dominio ed eseguire codice come SYSTEM. Nulla di ciò ha a che fare con chi è effettivamente nei Domain Admins on-prem.

Image
Figure 5. RBAC assignments on the domain controller, most inherited from the Subscription, every one of them capable of invoking Run Command as SYSTEM

A questo punto, lo script chiede anche se vuoi generare un grafico in stile BloodHound da questi dati per visualizzare quali principali di sicurezza hanno un percorso, diretto o indiretto, verso un controller di dominio virtualizzato in Azure. Nel nostro laboratorio, sono 12 i principali con un percorso verso il DC, la maggior parte ereditata dall'abbonamento e non assegnata direttamente alla VM. Clicca su un nodo qualsiasi e la barra laterale spiega esattamente cos'è e come ci è arrivato, inclusa l'appartenenza al gruppo, quindi un nodo Gruppo che mostra "3 membri" non è solo un conteggio. Puoi vedere chi c'è dentro.

Image
Figure 6. BloodHound-style attack path graph showing every security principal with a path to GOBIAS-DC01, generated directly from the script

Raccomandazione

Etichetta i tuoi Domain Controller in Azure con qualcosa come Tier-0-OnPrem-AD sulla risorsa VM. Sembra ovvio, ma la maggior parte degli ambienti che abbiamo esaminato non lo fa, motivo per cui identificarli ha richiesto un vero lavoro invece di filtrare semplicemente per etichetta. Una volta etichettati, puoi creare una policy: negare nuove assegnazioni di Proprietario o Collaboratore su qualsiasi cosa con quell’etichetta, o avvisare quando cambia.

L'etichettatura ti dice solo cosa succede d'ora in poi. Non risolve ciò che è già presente. Ogni ambiente che abbiamo esaminato ha accumulato permessi su queste VM nel tempo, per lo più ereditati dal gruppo di risorse o dalla sottoscrizione, non assegnati direttamente. Ecco perché è facile trascurarlo.Verifica chi ha accesso attualmente e chiedi, per ogni persona e principal di servizio, se hanno ancora bisogno di essere Owner o Contributor su una macchina che è un controller di dominio.

Image
Figure 7. Both Domain Controllers tagged Tier: Tier-0-OnPrem-AD, one clean tag per VM, no leftovers

Una volta impostato, filtrare significa solo aggiungere la colonna del livello o digitare Tier-0-OnPrem-AD nella barra di filtro, e appariranno tutti i DC. Nessuno script necessario. Ciò che ci è costato un’intera pipeline di enumerazione ora è un filtro a due clic per chiunque nel team.

Image

Riferimenti

  1. Microsoft Learn: Esegui script in una VM Windows in Azure usando l’azione Esegui comandi
    https://learn.microsoft.com/en-us/azure/virtual-machines/windows/run-command
  2. Microsoft Learn: Servizio metadati istanza Azure per macchine virtuali
    https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service

Condividi su

Scopri di più

Informazioni sull'autore

Asset Not Found

Huy Kha

Direttore della Ricerca sulla Sicurezza