Di Mauricio Payne, Analista di Sicurezza di Bureau Veritas Cybersecurity
Compromissione del cloud Azure attraverso autorizzazioni API sensibili
Recentemente, i ricercatori di Cloudbrothers hanno trovato un nuovo interessante modo per passare da un ambiente on premise a un ambiente Azure e ottenere i diritti di amministratore globale. In questo blog, le forniremo una dimostrazione e una spiegazione di questo attacco. Inoltre, saranno inclusi alcuni passi di mitigazione per aiutarla a rilevare e proteggere da questo attacco.
Dimostrazione del percorso dell'attacco
I ricercatori di Cloudbrothers hanno scoperto che un aggressore in grado di compromettere l'account AAD Sync utilizzato dal server AD Connect può aumentare i propri privilegi fino a diventare amministratore globale, sfruttando applicazioni con autorizzazioni sensibili.
Ciò è possibile in quanto l'account AAD Sync dispone delle autorizzazioni 'microsoft.directory/applications/owners/update' e 'microsoft.directory/servicePrincipals/owners/update'. Il che le consente di aggiornare i proprietari delle applicazioni registrate.
Inoltre, utilizzando le autorizzazioni 'microsoft.directory/servicePrincipals/credentials/update', questo account può aggiungere direttamente le credenziali a queste applicazioni, senza doversi prima aggiungere come proprietario.
Queste applicazioni possono poi essere utilizzate per l'escalation dei privilegi, se dispongono delle autorizzazioni corrette.
In questo blog ci concentreremo su due di queste autorizzazioni sensibili ('RoleManagement.ReadWrite.Directory' e 'AppRoleAssignment.ReadWrite.All') e dimostreremo il percorso di attacco che un aggressore dovrebbe seguire per descrivere ogni fase.
Panoramica dell'attacco
Prima di iniziare
Prima di iniziare, è importante affrontare alcuni presupposti che sono stati fatti per realizzare questo attacco.
- La prima è che sia stata registrata un'applicazione su Azure che contiene una delle due autorizzazioni sensibili precedentemente menzionate.
- La seconda ipotesi è che lei sia riuscito a compromettere completamente il server che esegue AD Connect e sia riuscito a scaricare le credenziali dell'account AAD Sync. Il dump delle credenziali può essere effettuato con vari metodi, ad esempio utilizzando il modulo PowerShell AADInternals. L'utilizzo di Get-AADIntSyncCredentials sul server AD Connect restituisce le credenziali dell'utente AAD Sync:
Il server AD Connect restituisce le credenziali per l'utente AAD Sync
Una volta acquisite queste credenziali, possiamo passare all'attacco principale vero e proprio. Il primo passo consiste nell'autenticarsi al tenant come utente di AAD Sync:
Si autentichi al tenant come utente di AAD Sync.
Risposta contenente il JWT
Dotati di questo token JWT, possiamo ora effettuare chiamate all'API Microsoft Graph e ottenere un elenco di tutte le applicazioni registrate sul Tenant. Questo token JWT può essere salvato in una variabile PowerShell che può essere utilizzata come intestazione di autenticazione:
$AuthHeader = @{Authorization = "Bearer <JWT>"}
Così facendo, possiamo effettuare una richiesta all'endpoint beta/applicazioni utilizzando PowerShell:
Invoke-RestMethod -Headers $AuthHeader -Uri "https://graph.microsoft.com/beta/applications/"
L'immagine seguente mostra la risposta della richiesta effettuata all'endpoint beta/applications, che contiene tutte le applicazioni registrate.
Risposta per la richiesta fatta all'endpoint beta/applicazioni
Esaminando questa risposta, vediamo molte informazioni relative alle diverse applicazioni. Tuttavia, ciò che è importante per noi in questo attacco è il campo "appID". Questi ID devono essere salvati in un elenco, perché sono necessari per la fase successiva dell'attacco. In questa fase utilizzeremo l'appID per effettuare una richiesta all'API Graph e interrogare quali sono i mandanti del servizio che appartengono a quell'applicazione.
Qui di seguito possiamo vedere la risposta di tale richiesta che contiene l'ID del service principal appartenente all'applicazione con appID 8c3ffdc3-fe9d-47a2-9bbc-3bc49e486c43. Questa richiesta può essere effettuata tramite PowerShell con il seguente comando:
Invoke-RestMethod -Headers $AuthHeader -Uri "https://graph.microsoft.com/beta/servicePrincipals/?`$filter=(appid eq '<appID>')".
Risposta con l'ID del responsabile dell'assistenza.
Una volta ottenuto l'ID di questi presidi di servizio, possiamo cercare le autorizzazioni ad essi assegnate. In particolare, cerchiamo un'autorizzazione con un appRoleID di "9e3f62cf-ca93-4989-b6ce- bf83c28f9fe8", che corrisponde al ruolo RoleManagement.ReadWrite.Directory o all'appRoleID di "06b708a9-e830-4db3-a914-8e69da51d44f", che corrisponde al ruolo AppRoleAssignment.ReadWrite.All.
ROLEMANAGEMENT.READWRITE.DIRECTORY
Il ruolo RoleManagement.ReadWrite.Directory dà all'applicazione il permesso di concedere privilegi aggiuntivi a se stessa, ad altre applicazioni o a qualsiasi utente. Effettuando la seguente richiesta, possiamo ottenere quali permessi sono assegnati al mandante del servizio con id: "9e666f83-8520-4c65- a8e2-e929194839ea".
Invoke-RestMethod -Headers $AuthHeader -Uri "https://graph.microsoft.com/beta/servicePrincipals/<ServicePrincipalID>/appRoleAssignments"
Nell'immagine sottostante possiamo vedere la risposta alla richiesta fatta sopra. Osservando la risposta vediamo il già citato appRoleId, che rende questa applicazione vulnerabile a questo attacco.
Risposta contenente appRoleID
Una volta trovata un'applicazione con questo ruolo, possiamo aggiungere il nostro utente (in questo caso l'utente AAD Sync) come proprietario di questo servizio principale. In PowerShell, la richiesta si presenta come segue:
$Riferimento = @{ "@odata.id" = "https://graph.microsoft.com/beta/directoryObjects/" + <AAD Sync userID> } | Convertire in json
Invoke-RestMethod -Method Post -Headers $AuthHeader -Uri "https://graph.microsoft.com/beta/servicePrincipals/<ServicePrincipalToTakeover>/owners/`$ref" - Body $Reference -ContentType "application/json" | Out-Null
La risposta a questa richiesta sarà simile a:
Risposta quando si aggiunge un utente come proprietario
Il passo successivo consiste nell'aggiungere un nuovo segreto al servizio principale, che in seguito utilizzeremo per autenticarci al tenant come questa applicazione vulnerabile. Viene effettuata una richiesta POST all'API Graph che imposta automaticamente una password sicura e la restituisce nel parametro "secretText". Questo avviene con il seguente comando PowerShell:
Invoke-RestMethod -Method Post -Headers $AuthHeader -Uri "https://graph.microsoft.com/beta/servicePrincipals/<ServicePrincipalToTakeover>/addPassword" -Body $Reference -ContentType "application/json"
Come si può vedere qui sotto, l'API restituisce il testo segreto:
La risposta contiene il nuovo segreto aggiunto.
Utilizzando l'appID dell'applicazione vulnerabile come "Client_Id" e il nuovo segreto aggiunto come"Client_Secret", possiamo autenticarci al tenant come questo service principal e ricevere un nuovo token JWT.
Richiesta API che si autentica come mandante di un servizio.
APPROLEASSIGNMENT.READWRITE.ALL
Il ruolo AppRoleAssignment.ReadWrite.All consente all'applicazione di concedere privilegi aggiuntivi a se stessa. Ciò significa che potremmo concedere il ruolo RoleManagement.ReadWrite.Directory all'applicazione e ottenere privilegi di amministratore globale. Di seguito si può vedere un'immagine in cui identifichiamo un'applicazione vulnerabile con questo ruolo:
Una volta identificata questa applicazione, possiamo aggiungervi un segreto che possiamo utilizzare per autenticarci come applicazione al tenant Azure:
Come visto in precedenza, la password viene restituita come parametro "secretText", che utilizzeremo in combinazione con l'appID per autenticarci nel tenant:
Questo restituisce un token JWT che, decodificato come possiamo vedere, contiene solo il ruolo "AppRoleAssignment.ReadWrite.All":
Utilizzando questo token JWT come nuovo token di autorizzazione, possiamo aggiungere il ruolo richiesto all'applicazione. Per farlo, dobbiamo conoscere l'appRoleID del ruolo che vogliamo aggiungere, il principalId e il resourceId. La richiesta di aggiungere il ruolo RoleManagement.ReadWrite.Directory può essere effettuata con i seguenti comandi PowerShell:
$params = @{
principalId = <servicePrincipalId>
resourceId = <resourceId>
appRoleId = "9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8".
} | Convertire in json
Invoke-RestMethod -Method POST -Headers $AppAuthHeader -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/ <servicePrincipalId>/appRoleAssignments" - Body $params -ContentType "application/json"
Risposta all'aggiunta di questo ruolo
Ora possiamo autenticarci nuovamente come applicazione, utilizzando la stessa password che avevamo aggiunto in precedenza. Visualizzando il token JWT appena generato, possiamo vedere che il nostro nuovo ruolo è stato applicato con successo:
Questo può essere verificato anche sul portale Azure, visitando l'applicazione:
AGGIUNTA DI UN UTENTE COME AMMINISTRATORE GLOBALE
L'utilizzo di questo nuovo JWT ci consente di effettuare richieste come mandante del servizio. Poiché ha il ruolo RoleManagement.ReadWrite.Directory, ci consente di assegnare a un utente il ruolo di amministratore globale. In PowerShell questo avviene aggiornando la variabile AppAuthHeader con il nuovo token JWT ed eseguendo i seguenti comandi:
$Reference = @{ "@odata.id" = "https://graph.microsoft.com/beta/directoryObjects/" + <UserIDToMakeGlobalAdmin>} | Convertire in json
Invoke-RestMethod -Method Post -Headers $AppAuthHeader -Uri "https://graph.microsoft.com/beta/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190- 012177145e10/members/`$ref" -Body $Reference -ContentType "application/json"
Guardando il portale Azure, possiamo vedere che il nostro utente fa ora parte degli Amministratori globali:
MITIGAZIONI
Per quanto riguarda i modi per mitigare questo attacco, non esiste una risposta univoca. Tuttavia, ci sono alcune azioni che possono essere intraprese per ridurre il tasso di successo di questo attacco.
La prima e più ovvia è limitare l'uso di ruoli sensibili come RoleManagement.ReadWrite.Directory. In alcuni casi questi ruoli saranno necessari; in questi scenari è meglio monitorare attentamente queste applicazioni e avere pronte delle risposte automatiche in caso di comportamento anomalo.
Inoltre, l'uso dell'accesso condizionato ridurrebbe la probabilità di successo di questo attacco via Internet. Ciò potrebbe avvenire, ad esempio, consentendo solo l'accesso all'account AAD Sync dalla sede centrale. Qualsiasi irregolarità in questo caso potrebbe essere utilizzata per attivare un avviso e informare di un tentativo di accesso potenzialmente dannoso. Tuttavia, come si vede in questo esempio, un aggressore che ha compromesso il server AD Connect può aggirare queste politiche di accesso condizionato conducendo l'attacco dal server AD Connect.
Inoltre, è necessario adottare misure di sicurezza sul server AD Connect per monitorare e ridurre i tipi di azioni che possono essere eseguite sul server. Un esempio potrebbe essere quello di bloccare l'uso di strumenti come AADInternals.
Il risultato di queste mitigazioni è che non esiste un'unica soluzione a questo attacco. Al contrario, è necessario disporre di più livelli di difesa che fermino un aggressore, si spera, prima ancora di ottenere l'accesso al server AD Connect.
Per maggiori informazioni su questo attacco, consulti:
Informazioni sull'autore
Mauricio Payne
Mauricio Payne è analista di sicurezza presso Bureau Veritas Cybersecurity. Ha studiato ICT e Software e si è specializzato in Cyber-Security presso il Fontys Hogescholen di Eindhoven. Da quando si è laureato, lavora presso Bureau Veritas Cybersecurity dove è specializzato in valutazioni di applicazioni web e cloud.
Maggiori informazioni
Ha domande su questo articolo o desidera maggiori informazioni su come Bureau Veritas Cybersecurity può aiutarla ad aumentare la sua cyber resilience? Compili il modulo sottostante e la contatteremo entro un giorno lavorativo.
INFORMAZIONI SULLA SICUREZZA
Bureau Veritas Cybersecurity è uno dei principali esperti di cybersecurity. I nostri clienti spaziano dal settore governativo e sanitario a quello finanziario e industriale in tutto il mondo. Bureau Veritas Cybersecurity offre servizi tecnici, come valutazioni delle vulnerabilità, penetration testing e red teaming. Forniamo anche certificazioni per ambienti IoT e industriali, nonché audit, servizi forensi e formazione di awareness. Il nostro obiettivo è aumentare la sua cyber resilience.
Bureau Veritas Cybersecurity è un'azienda di Bureau Veritas. Bureau Veritas (BV) è un'azienda quotata in borsa specializzata in test, ispezioni e certificazioni. BV è stata fondata nel 1828, ha oltre 80.000 dipendenti ed è attiva in 140 Paesi. Bureau Veritas Cybersecurity è la pietra miliare della strategia di cybersecurity di Bureau Veritas.
Perché scegliere Bureau Veritas Cybersecurity?
Bureau Veritas Cybersecurity è il vostro partner esperto in materia di sicurezza informatica. Aiutiamo le organizzazioni a identificare i rischi, rafforzare le difese e conformarsi agli standard e alle normative in materia di sicurezza informatica. I nostri servizi riguardano persone, processi e tecnologie, dalla formazione sulla consapevolezza e l'ingegneria sociale alla consulenza sulla sicurezza, la conformità e i test di penetrazione.
Operiamo in ambienti IT, OT e IoT, supportando sia i sistemi digitali che i prodotti connessi. Con oltre 300 professionisti della sicurezza informatica in tutto il mondo, uniamo una profonda competenza tecnica a una presenza globale. Bureau Veritas Cybersecurity fa parte del Bureau Veritas Group, leader mondiale nel settore dei test, delle ispezioni e delle certificazioni.