Az - AzureAD (AAD)

Supporta HackTricks

Informazioni di base

Azure Active Directory (Azure AD) funge da servizio basato su cloud di Microsoft per la gestione dell'identità e degli accessi. È fondamentale per consentire ai dipendenti di accedere e ottenere risorse, sia all'interno che al di fuori dell'organizzazione, comprendendo Microsoft 365, il portale Azure e una moltitudine di altre applicazioni SaaS. Il design di Azure AD si concentra sulla fornitura di servizi di identità essenziali, includendo in modo prominente autenticazione, autorizzazione e gestione degli utenti.

Le caratteristiche chiave di Azure AD comprendono autenticazione a più fattori e accesso condizionale, insieme a un'integrazione fluida con altri servizi di sicurezza Microsoft. Queste funzionalità elevano significativamente la sicurezza delle identità degli utenti e consentono alle organizzazioni di implementare e far rispettare efficacemente le loro politiche di accesso. Come componente fondamentale dell'ecosistema dei servizi cloud di Microsoft, Azure AD è cruciale per la gestione basata su cloud delle identità degli utenti.

Entità

Enumerazione

Per questa enumerazione puoi utilizzare il tool az cli, il modulo PowerShell AzureAD (o AzureAD Preview) e il modulo Az PowerShell.

In linux dovrai installare PowerShell Core:

sudo apt-get update
sudo apt-get install -y wget apt-transport-https software-properties-common

# Ubuntu 20.04
wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb

# Update repos
sudo apt-get update
sudo add-apt-repository universe

# Install & start powershell
sudo apt-get install -y powershell
pwsh

# Az cli
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Differenze tra i moduli

  • AzureAD è un modulo PowerShell di Microsoft per gestire Azure AD. Non mostra tutte le proprietà degli oggetti Azure AD e non può essere utilizzato per accedere alle informazioni sulle risorse Azure.

  • Az PowerShell è un modulo per gestire le risorse Azure dalla riga di comando di PowerShell.

Connessione

az login #This will open the browser
az login -u <username> -p <password> #Specify user and password
az login --identity #Use the current machine managed identity (metadata)
az login --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID #Login with user managed identity
# Login as service principal
az login --service-principal -u http://azure-cli-2016-08-05-14-31-15 -p VerySecret --tenant contoso.onmicrosoft.com #With password
az login --service-principal -u http://azure-cli-2016-08-05-14-31-15 -p ~/mycertfile.pem --tenant contoso.onmicrosoft.com #With cert

# Request access token (ARM)
az account get-access-token
# Request access token for different resource. Supported tokens: aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
az account get-access-token --resource-type aad-graph

# If you want to configure some defaults
az configure

# Get user logged-in already
az ad signed-in-user show

# Help
az find "vm" # Find vm commands
az vm -h # Get subdomains
az ad user list --query-examples # Get examples

Quando accedi tramite CLI ad Azure con qualsiasi programma, stai utilizzando un Azure Application di un tenant che appartiene a Microsoft. Queste Applicazioni, come quelle che puoi creare nel tuo account, hanno un client id. Non sarai in grado di vederle tutte nelle liste delle applicazioni consentite che puoi vedere nella console, ma sono consentite per impostazione predefinita.

Ad esempio, uno script powershell che autentica utilizza un'app con client id 1950a258-227b-4e31-a9cf-717495945fc2. Anche se l'app non appare nella console, un sysadmin potrebbe bloccare quell'applicazione in modo che gli utenti non possano accedere utilizzando strumenti che si connettono tramite quell'App.

Tuttavia, ci sono altri client-id di applicazioni che ti permetteranno di connetterti ad Azure:

# The important part is the ClientId, which identifies the application to login inside Azure

$token = Invoke-Authorize -Credential $credential `
-ClientId '1dfb5f98-f363-4b0f-b63a-8d20ada1e62d' `
-Scope 'Files.Read.All openid profile Sites.Read.All User.Read email' `
-Redirect_Uri "https://graphtryit-staging.azurewebsites.net/" `
-Verbose -Debug `
-InformationAction Continue

$token = Invoke-Authorize -Credential $credential `
-ClientId '65611c08-af8c-46fc-ad20-1888eb1b70d9' `
-Scope 'openid profile Sites.Read.All User.Read email' `
-Redirect_Uri "chrome-extension://imjekgehfljppdblckcmjggcoboemlah" `
-Verbose -Debug `
-InformationAction Continue

$token = Invoke-Authorize -Credential $credential `
-ClientId 'd3ce4cf8-6810-442d-b42e-375e14710095' `
-Scope 'openid' `
-Redirect_Uri "https://graphexplorer.azurewebsites.net/" `
-Verbose -Debug `
-InformationAction Continue

Utenti

# Enumerate users
az ad user list --output table
az ad user list --query "[].userPrincipalName"
# Get info of 1 user
az ad user show --id "test@corp.onmicrosoft.com"
# Search "admin" users
az ad user list --query "[].displayName" | findstr /i "admin"
az ad user list --query "[?contains(displayName,'admin')].displayName"
# Search attributes containing the word "password"
az ad user list | findstr /i "password" | findstr /v "null,"
# All users from AzureAD
az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi==null]"
az ad user list --query "[?onPremisesSecurityIdentifier==null].displayName"
# All users synced from on-prem
az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi!=null]"
az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName"
# Get groups where the user is a member
az ad user get-member-groups --id <email>
# Get roles assigned to the user
az role assignment list --include-groups --include-classic-administrators true --assignee <email>

Cambiare la password dell'utente

$password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText –Force

(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password –Verbose

MFA e Politiche di Accesso Condizionale

È fortemente consigliato aggiungere MFA a ogni utente, tuttavia, alcune aziende potrebbero non impostarlo o potrebbero impostarlo con un Accesso Condizionale: L'utente sarà richiesto MFA se accede da una posizione specifica, browser o alcuna condizione. Queste politiche, se non configurate correttamente, potrebbero essere soggette a bypass. Controlla:

Az - Conditional Access Policies / MFA Bypass

Gruppi

# Enumerate groups
az ad group list
az ad group list --query "[].[displayName]" -o table
# Get info of 1 group
az ad group show --group <group>
# Get "admin" groups
az ad group list --query "[].displayName" | findstr /i "admin"
az ad group list --query "[?contains(displayName,'admin')].displayName"
# All groups from AzureAD
az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi==null]"
az ad group list --query "[?onPremisesSecurityIdentifier==null].displayName"
# All groups synced from on-prem
az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi!=null]"
az ad group list --query "[?onPremisesSecurityIdentifier!=null].displayName"
# Get members of group
az ad group member list --group <group> --query "[].userPrincipalName" -o table
# Check if member of group
az ad group member check --group "VM Admins" --member-id <id>
# Get which groups a group is member of
az ad group get-member-groups -g "VM Admins"
# Get Apps where a group has a role (role not shown)
Get-AzureADGroup -ObjectId <id> | Get-AzureADGroupAppRoleAssignment | fl *

Aggiungi utente al gruppo

I proprietari del gruppo possono aggiungere nuovi utenti al gruppo

Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose

I gruppi possono essere dinamici, il che significa fondamentalmente che se un utente soddisfa determinate condizioni, verrà aggiunto a un gruppo. Naturalmente, se le condizioni si basano su attributi che un utente può controllare, potrebbe abusare di questa funzionalità per entrare in altri gruppi. Controlla come abusare dei gruppi dinamici nella pagina seguente:

Az - Dynamic Groups Privesc

Principali di Servizio / Applicazioni Aziendali

Nota che Service Principal nella terminologia di PowerShell è chiamato Enterprise Applications nel portale Azure (web).

# Get Service Principals
az ad sp list --all
az ad sp list --all --query "[].[displayName]" -o table
# Get details of one SP
az ad sp show --id 00000000-0000-0000-0000-000000000000
# Search SP by string
az ad sp list --all --query "[?contains(displayName,'app')].displayName"
# Get owner of service principal
az ad sp owner list --id <id> --query "[].[displayName]" -o table
# Get service principals owned by the current user
az ad sp list --show-mine
# List apps that have password credentials
az ad sp list --all --query "[?passwordCredentials != null].displayName"
# List apps that have key credentials (use of certificate authentication)
az ad sp list -all --query "[?keyCredentials != null].displayName"

Il proprietario di un Service Principal può cambiare la sua password.

Elenca e prova ad aggiungere un client secret su ogni App Aziendale

```powershell # Just call Add-AzADAppSecret Function Add-AzADAppSecret { <# .SYNOPSIS Add client secret to the applications.

.PARAMETER GraphToken Pass the Graph API Token

.EXAMPLE PS C:> Add-AzADAppSecret -GraphToken 'eyJ0eX..'

.LINK https://docs.microsoft.com/en-us/graph/api/application-list?view=graph-rest-1.0&tabs=http https://docs.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http #>

[CmdletBinding()] param( [Parameter(Mandatory=$True)] [String] $GraphToken = $null )

$AppList = $null $AppPassword = $null

List All the Applications

$Params = @{ "URI" = "https://graph.microsoft.com/v1.0/applications" "Method" = "GET" "Headers" = @{ "Content-Type" = "application/json" "Authorization" = "Bearer $GraphToken" } }

try { $AppList = Invoke-RestMethod @Params -UseBasicParsing } catch { }

Add Password in the Application

if($AppList -ne $null) { [System.Collections.ArrayList]$Details = @()

foreach($App in $AppList.value) { $ID = $App.ID $psobj = New-Object PSObject

$Params = @{ "URI" = "https://graph.microsoft.com/v1.0/applications/$ID/addPassword" "Method" = "POST" "Headers" = @{ "Content-Type" = "application/json" "Authorization" = "Bearer $GraphToken" } }

$Body = @{ "passwordCredential"= @{ "displayName" = "Password" } }

try { $AppPassword = Invoke-RestMethod @Params -UseBasicParsing -Body ($Body | ConvertTo-Json) Add-Member -InputObject $psobj -NotePropertyName "Object ID" -NotePropertyValue $ID Add-Member -InputObject $psobj -NotePropertyName "App ID" -NotePropertyValue $App.appId Add-Member -InputObject $psobj -NotePropertyName "App Name" -NotePropertyValue $App.displayName Add-Member -InputObject $psobj -NotePropertyName "Key ID" -NotePropertyValue $AppPassword.keyId Add-Member -InputObject $psobj -NotePropertyName "Secret" -NotePropertyValue $AppPassword.secretText $Details.Add($psobj) | Out-Null } catch { Write-Output "Failed to add new client secret to '$($App.displayName)' Application." } } if($Details -ne $null) { Write-Output "" Write-Output "Client secret added to : " Write-Output $Details | fl * } } else { Write-Output "Failed to Enumerate the Applications." } }

</details>

### Ruoli

<div data-gb-custom-block data-tag="tabs">

<div data-gb-custom-block data-tag="tab" data-title='az cli'>

```bash
# Get roles
az role definition list
# Get assigned roles
az role assignment list --all --query "[].roleDefinitionName"
az role assignment list --all | jq '.[] | .roleDefinitionName,.scope'
# Get info of 1 role
az role definition list --name "AzureML Registry User"
# Get only custom roles
az role definition list --custom-role-only
# Get only roles assigned to the resource group indicated
az role definition list --resource-group <resource_group>
# Get only roles assigned to the indicated scope
az role definition list --scope <scope>
# Get all the principals a role is assigned to
az role assignment list --all --query "[].{principalName:principalName,principalType:principalType,resourceGroup:resourceGroup,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='<ROLE_NAME>']"
# Get all available role templates
Get-AzureADDirectoryroleTemplate
# Get enabled roles (Assigned roles)
Get-AzureADDirectoryRole
Get-AzureADDirectoryRole -ObjectId <roleID> #Get info about the role
# Get custom roles - use AzureAdPreview
Get-AzureADMSRoleDefinition | ?{$_.IsBuiltin -eq $False} | select DisplayName
# Users assigned a role (Global Administrator)
Get-AzureADDirectoryRole -Filter "DisplayName eq 'Global Administrator'" | Get-AzureADDirectoryRoleMember
Get-AzureADDirectoryRole -ObjectId <id> | fl
# Roles of the Administrative Unit (who has permissions over the administrative unit and its members)
Get-AzureADMSScopedRoleMembership -Id <id> | fl *
# Get role assignments on the subscription
Get-AzRoleDefinition
# Get Role definition
Get-AzRoleDefinition -Name "Virtual Machine Command Executor"
# Get roles of a user or resource
Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com
Get-AzRoleAssignment -Scope /subscriptions/<subscription-id>/resourceGroups/<res_group_name>/providers/Microsoft.Compute/virtualMachines/<vm_name>
# Get permissions over a resource using ARM directly
$Token = (Get-AzAccessToken).Token
$URI = 'https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Research/providers/Microsoft.Compute/virtualMachines/infradminsrv/providers/Microsoft.Authorization/permissions?api-version=2015-07-01'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value

Dispositivi

# If you know how to do this send a PR!# Enumerate DevicesGet-AzureADDevice -All $true | fl *# List all the active devices (and not the stale devices)Get-AzureADDevice -All $true | ?{$_.ApproximateLastLogonTimeStamp -ne $null}# Get owners of all devicesGet-AzureADDevice -All $true | Get-AzureADDeviceRegisteredOwnerGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredOwner -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}# Registred users of all the devicesGet-AzureADDevice -All $true | Get-AzureADDeviceRegisteredUserGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredUser -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}# Get dives managed using IntuneGet-AzureADDevice -All $true | ?{$_.IsCompliant -eq "True"}# Get devices owned by a userGet-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com# Get Administrative Units of a deviceGet-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -ObjectId $_.ObjectId | where {$_.ObjectId -eq $deviceObjId} }

Se un dispositivo (VM) è collegato ad AzureAD, gli utenti di AzureAD potranno accedere. Inoltre, se l'utente connesso è Proprietario del dispositivo, sarà amministratore locale.

Applicazioni

App sono Registrazioni App nel portale (non Applicazioni Aziendali). Ma ogni Registrazione App creerà un'Applicazione Aziendale (Service Principal) con lo stesso nome. Inoltre, se l'App è un'App multi-tenant, un'altra Applicazione Aziendale (Service Principal) sarà creata in quella tenant con lo stesso nome.

Quando un'App viene generata, vengono date 2 tipologie di permessi:

  • Permessi dati al Service Principal

  • Permessi che l'app può avere e utilizzare per conto dell'utente.

# List Appsaz ad app listaz ad app list --query "[].[displayName]" -o table# Get info of 1 Appaz ad app show --id 00000000-0000-0000-0000-000000000000# Search App by stringaz ad app list --query "[?contains(displayName,'app')].displayName"# Get the owner of an applicationaz ad app owner list --id <id> --query "[].[displayName]" -o table# List all the apps with an application passwordaz ad app list --query "[?passwordCredentials != null].displayName"# List apps that have key credentials (use of certificate authentication)az ad app list --query "[?keyCredentials != null].displayName"# List all registered applicationsGet-AzureADApplication -All $true# Get details of an applicationGet-AzureADApplication -ObjectId <id> | fl *# List all the apps with an application passwordGet-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}}# Get owner of an applicationGet-AzureADApplication -ObjectId <id> | Get-AzureADApplicationOwner |fl *# Get AppsGet-AzADApplication# Get details of one AppGet-AzADApplication -ObjectId <id># Get App searching by stringGet-AzADApplication | ?{$_.DisplayName -match "app"}# Get Apps with passwordGet-AzADAppCredential

Un'app con il permesso AppRoleAssignment.ReadWrite può escalare a Global Admin concedendosi il ruolo. Per ulteriori informazioni controlla questo.

Una stringa segreta che l'applicazione utilizza per dimostrare la propria identità quando richiede un token è la password dell'applicazione. Quindi, se trovi questa password puoi accedere come service principal all'interno del tenant. Nota che questa password è visibile solo quando viene generata (puoi cambiarla ma non puoi ottenerla di nuovo). Il proprietario dell'applicazione può aggiungere una password ad essa (così può impersonarla). Gli accessi come questi service principal non sono contrassegnati come rischiosi e non avranno MFA.

Differenza tra Applicazioni & (Applicazioni Aziendali o Service Principals)

Differenza tra un'applicazione e un Service Principal in Azure:

  • Registrazioni di Applicazioni/App: Sono applicazioni che esistono nel tuo Azure AD

  • (Get-AzureADApplication -filter "DisplayName eq 'testapp'")

  • Service Principal/Applicazioni Aziendali: Oggetti di sicurezza nel tuo Azure AD che possono avere privilegi nel Directory di Azure e sono collegati alla tua applicazione o a un'applicazione di terze parti

  • Get-AzureADServicePrincipal -filter "DisplayName eq 'testapp'")

  • Un amministratore potrebbe dover approvare i permessi concessi se sono molto sensibili.

Un'applicazione può essere in esecuzione in un tenant di terze parti e una volta che inizi a usarla e le concedi accesso, un'Applicazione Aziendale/Service Principal viene creata nel tuo tenant per darle accesso alle informazioni di cui ha bisogno:

Unità Amministrative

Viene utilizzata per una migliore gestione degli utenti.

Le unità amministrative limitano i permessi in un ruolo a qualsiasi parte della tua organizzazione che definisci. Potresti, ad esempio, utilizzare le unità amministrative per delegare il ruolo di Helpdesk Administrator a specialisti di supporto regionali, in modo che possano gestire gli utenti solo nella regione che supportano.

Pertanto, puoi assegnare ruoli all'unità amministrativa e i membri di essa avranno questi ruoli.

# Get Administrative UnitsGet-AzureADMSAdministrativeUnitGet-AzureADMSAdministrativeUnit -Id <id># Get ID of admin unit by string$adminUnitObj = Get-AzureADMSAdministrativeUnit -Filter "displayname eq 'Test administrative unit 2'"# List the users, groups, and devices affected by the administrative unitGet-AzureADMSAdministrativeUnitMember -Id <id># Get the roles users have over the members of the AUGet-AzureADMSScopedRoleMembership -Id <id> | fl #Get role ID and role members

Azure AD Identity Protection (AIP)

Azure AD Identity Protection (AIP) è un servizio di sicurezza che utilizza rilevamento e rimedio automatici per aiutare a proteggere le identità degli utenti in Azure Active Directory da compromissioni. AIP monitora e valuta continuamente il rischio degli accessi degli utenti e delle configurazioni delle identità, applicando automaticamente misure di sicurezza appropriate, come la richiesta di autenticazione a più fattori o il blocco di attività potenzialmente pericolose. Questo aiuta le organizzazioni a prevenire violazioni della sicurezza basate sull'identità.

Flusso:

  1. Azure AD Identity Protection monitora le attività degli utenti e raccoglie dati sugli accessi, eventi di autenticazione e altre attività rilevanti.

  2. Il servizio utilizza algoritmi di machine learning per analizzare questi dati e rilevare potenziali minacce alla sicurezza.

  3. Azure AD Identity Protection assegna un livello di rischio alla minaccia (ad es. accesso) e genera un avviso se necessario per eseguire un'azione automatica.

Azure AD Password Protection (APP)

Azure AD Password Protection (APP) è una funzionalità di sicurezza che aiuta a prevenire password deboli in Azure Active Directory imponendo politiche di password forti. APP blocca password deboli comunemente usate e le loro varianti, riducendo il rischio di violazioni legate alle password. Può essere applicato sia a livello cloud che su Active Directory on-premises, migliorando la sicurezza complessiva delle password nell'organizzazione.

References

Last updated