---
name: azure-entra-cloud-pentesting
description: Azure and Entra ID offensive testing — tenant discovery via OpenID metadata, users, service principals, managed identities, application registrations, Microsoft Graph scopes and consent grants, RBAC across subscriptions, storage, Key Vault, App Service, Automation, and Run Command
intent: offensive
assessment_mode:
  - blackbox
  - credentialed
provider:
  - azure
---

# Azure / Entra Cloud Pentesting

## Purpose
Full Azure + Entra ID offensive methodology: from a domain to a tenant model (black-box), or from a validated token/service principal (credentialed) to mapped identity, RBAC, resources, and escalation paths. Microsoft Graph and Azure CLI/API first — Sentinel/Defender are irrelevant to offensive workflow.

## Entry Conditions
- Black-box: a target domain, `azurewebsites.net`/`blob.core.windows.net` endpoints, or app client IDs from `cloud-attack-surface-discovery`
- Credentialed: ARM/Graph token, service-principal secret, or managed-identity token from `cloud-credential-abuse` (audience already decoded)

## Discovery Signals
- Tenant ID: `https://login.microsoftonline.com/<domain>/v2.0/.well-known/openid-configuration` (returns tenant ID for the domain)
- App/client IDs in JavaScript (MSAL configs, `clientId:`), redirect URIs revealing app registrations
- Azure-hosted hostnames (App Service, Functions, APIM, Front Door)
- Subscription/resource-group names in error messages, ARM URLs

## Attack Model

```text
tenant discovered → identity model mapped (users/SPs/apps/MI)
→ Graph permissions + RBAC roles enumerated
→ resource access (Key Vault, Storage, VMs, Automation)
→ escalation candidates → verified impact
```

## Methodology

### Step 1: Tenant Discovery (black-box)
```bash
curl -sk "https://login.microsoftonline.com/<target-domain>/v2.0/.well-known/openid-configuration" | jq ".token_endpoint, .issuer"
# issuer reveals the tenant ID; .well-known endpoints enumerate federation metadata
# Brute/verify common subdomains: <name>.azurewebsites.net, <name>.blob.core.windows.net
# MSAL JS configs in bundles: tenant + clientId + scopes → the app's consent surface
```

### Step 2: Identity Model (Graph)
```bash
# With a Graph-audience token:
az rest --url "https://graph.microsoft.com/v1.0/me"
az rest --url "https://graph.microsoft.com/v1.0/users?$count=true" -H "ConsistencyLevel: eventual"   # if Directory.Read*
az rest --url "https://graph.microsoft.com/v1.0/servicePrincipals"          # enterprise apps
az rest --url "https://graph.microsoft.com/v1.0/applications"               # app registrations
az rest --url "https://graph.microsoft.com/v1.0/oauth2PermissionGrants"     # consent grants (delegated)
az rest --url "https://graph.microsoft.com/v1.0/policies/authorizationPolicy" # default user roles
# Decode your own token: roles claim (app roles) vs scp (delegated scopes) — these are DIFFERENT privilege models
```

### Step 3: ARM / RBAC
```bash
# With an ARM-audience token:
az login --service-principal -u <appId> -p <secret> --tenant <tid>   # or use the token
az account list
az role assignment list --all --output table                          # where does this principal have roles?
# Owner/Contributor/User Access Administrator on a scope = the RBAC escalation primitives
```

### Step 4: Resource Access
```bash
# Key Vault (its OWN audience — ARM role ≠ data plane, but `Access Policies`/RBAC model decides):
az keyvault list && az keyvault secret list --vault-name <v>
# Storage: az storage container list --account-name <acct> (keys or SAS)
# App Service: az webapp config appsettings list (connection strings galore)
# VMs + Run Command (the classic exec primitive):
az vm run-command invoke -g <rg> -n <vm> --command-id RunShellScript --scripts "id"
# Automation accounts: runbooks + credentials
# Managed identities: az identity list; each maps to an ARM principal
```

### Step 5: Chains
- Keys/SAS in Key Vault or app settings → `cloud-secrets-data-access` and resource access
- VM Run Command / Automation → workload execution → `cloud-metadata-workload-identity` logic inverted (you ARE the workload) → `azure-privilege-escalation`
- Cross-tenant apps/consent → `cloud-cross-account-tenant-trust`

## Token/Audience Rule
Before declaring a credential weak or powerful: determine `aud` (Graph / ARM / Key Vault / Storage), tenant, principal (user vs service principal vs managed identity), scopes (`scp`, delegated) vs roles (`roles`, application). A Graph token does not grant ARM access; an ARM token does not grant Graph privileges; Key Vault and Storage have separate audiences. Mint the right audience from the same credential when the identity supports it.

## Evidence Contract

```text
candidate (identity/permission/resource)
→ token with the right audience proves live access
→ concrete data or action (secret listed/read, VM command output, role assignment enumerated)
→ report with tenant/principal context
```

**NOT evidence**: tenant ID known, app registration existing, decoded token claims without a live call, `az account list` failing due to audience confusion (try Graph next)

## Common Misses
- Audience confusion — Graph tokens tested against ARM and vice versa
- Consent grants (delegated) never enumerated — an app a user consented to is an implicit lateral path
- Managed identities under-used — their tokens mint per-resource audiences
- App settings/connection strings on App Service never listed
- Run Command forgotten as the exec primitive (no VM login required)
- Federated identity credentials on apps never inspected (token minting as the app)

## False Positives / Non-Findings
- Multi-tenant apps visible in your tenant with no consent/grants (informational)
- Tokens expired or restricted by CA policies
- Service principals with no role assignments anywhere (report as unused credential exposure only)

## Xalgorix Tool Strategy
- `terminal_execute` with az CLI + `az rest` (Graph) — the baseline; no proprietary tools required
- Python for JWT decoding and MSAL token minting per audience
- Ledger: tenant, principals, token audiences, role assignments, verified resource accesses

## Specialist Handoffs
- Escalation → `azure-privilege-escalation`
- Kubernetes (AKS) → Entra integration here, RBAC/internals → `container-security`
- Cross-tenant trust → `cloud-cross-account-tenant-trust`
- Secrets → `cloud-secrets-data-access`

## Stopping Rule
Stop when: the tenant's identity model (users/SPs/apps/MIs), your effective Graph scopes and ARM roles, and the target's high-value resources (Key Vault, Storage, VMs, Automation) are mapped, and the strongest escalation candidates are verified or constraint-blocked.