Phase 2: Authenticated Enumeration
The Lab Scenario (DefCorp)
Understanding your starting position is vital. In this guide, you are not usually starting as a random hacker on the internet trying to guess passwords (a "Black Box" scenario).
You are in an Assumed Breach scenario.
The Setup:
- The Target: DefCorp, a defense contractor with high security requirements.
- The Environment: A Hybrid setup. This means they have an On-Premise Active Directory that syncs users to the Azure Cloud. This creates a massive attack surface: if we compromise the cloud, we might pivot on-prem. If we compromise on-prem, we might dominate the cloud.
- Your Role: "External Contractor." You have been given legitimate, low-privilege credentials (email and password) to perform maintenance work.
The Strategic Implication:
Since you have credentials, you don't need to exploit a firewall to get in. You are already "inside" the directory (Entra ID). Your challenge is that your user sees nothing (no Azure Resources) and is restricted by Conditional Access Policies (Geoblocking, MFA) and Firewalls.
Your goal is not "getting in." Your goal is "breaking out" of your restricted silo to access the crown jewels (Blueprints) hidden deep in a secure Subscription.
This section is the bridge between Phase 1 (Outside) and Phase 2 (Inside). Before we can perform authenticated enumeration, we must solve a critical problem. We have the credentials for test@defcorphq.onmicrosoft.com but logging directly into the administrative portal blocks us because of Mandatory MFA Enforcement.
Authentication Bypass and Token Extraction
In an assumed breach scenario, possessing a username and password is no longer enough. Since late 2024, Microsoft has enforced Mandatory Multi-Factor Authentication (MFA) for all users attempting to sign into Azure Management portals. This means if you take valid credentials and try to log into portal.azure.com, you will be blocked by an MFA prompt.
However, this security control has a specific weakness we can exploit.
The "Mandatory MFA" policy targets specific administrative Cloud Applications like the "Azure Portal" or "Intune Admin Center." It often ignores standard user productivity portals.
We can bypass this restriction by logging into a User Portal where the policy is looser. Once we authenticate there, Microsoft gives our browser a valid Access Token. We can steal this token and present it to the secure Azure APIs. The APIs trust the token and do not realize we bypassed the "front door" security checks.
Here are the three primary ways to execute this evasion.
Manual Method: Portal Hopping (Browser Extraction)
This is the most reliable "Living off the Land" technique. It requires no specialized hacking tools, only a web browser. We target portals designed for end-users to manage their profile or view apps.
These sites are rarely protected by the strict "Admin-Only" MFA policies.
Target Portals
- My Account: https://myaccount.microsoft.com/
- My Apps: https://myapps.microsoft.com/
Execution
- Open a browser in Incognito mode. Press F12 to open the Developer Tools and navigate to the Network tab. Ensure the "Preserve Log" option is checked so traffic persists during redirects.
- Browse to https://myaccount.microsoft.com.
- Log in with the compromised username and password. If the account is vulnerable, you will get straight in without an MFA prompt.
- Once the dashboard loads, look at the Network filter box in Developer Tools. Search for API requests containing keywords like batch, organization, or me.
- Click on one of these requests. Look at the Request Headers section on the right.
- Find the header labeled Authorization. The value will start with Bearer eyJ.... This is your Access Token (JWT).
Copy this entire string. You can now paste this into tools like the Az PowerShell module or roadrecon to start your enumeration.
Why this works: The token issued by myaccount allows you to talk to the Microsoft Graph API, which is the same API used for enumerating users and groups.
Extracting ARM Tokens (Infrastructure Access)
The Difference Between Graph and ARM
It is critical to understand that Azure uses distinct tokens for distinct services. The token we stole from myaccount.microsoft.com is usually scoped for Microsoft Graph. It lets us ask questions like "Who are the users?" or "What groups exist?"
However, if you try to use that token to list Virtual Machines or Access Keys, Azure will reject it. To manipulate the infrastructure (Infrastructure-as-a-Service), we need an Azure Resource Manager (ARM) token. This token allows us to interact with management.azure.com.
The Technique: The Cosmos DB Portal
Just like we used "My Account" to get a Graph token, we need a portal that interacts with Azure resources but might be less strictly monitored or easier to access once a session is established.
A reliable target for this is the Azure Cosmos DB Explorer.
- Ensure you have an active session (if you already logged into My Account in the same browser session, you often have a Single Sign-On ticket cached).
- Browse to
https://cosmos.azure.com.
- Press F12 to open Developer Tools and select the Network tab. Ensure "Preserve Log" is checked.
- Refresh the page if necessary.
- In the Network Filter box, type
resourcesor search for traffic going tomanagement.azure.com.
- Click on one of the requests (often a
GETrequest listing databases or subscriptions).
- Look at the Request Headers.
- Copy the Authorization value (
Bearer eyJ...).
How to Use This Token
You typically need to provide both the Graph Token (to resolve Usernames) and the ARM Token (to list Resources) to fully empower your PowerShell tools.
We can now use these tokens with Az PowerShell, Mg module or direct API calls.
Connect-AzAccount -AccessToken $ARMToken -GraphAccessToken $GraphToken -AccountId test@defcorphq...
Abusing Device Authorization Flow
Standard logins are "interactive." You open a browser, the app redirects you to Microsoft, you sign in, and the app gets a token.
The Device Code Flow is designed for devices that have internet access but no browser or keyboard, like a Smart TV, a printer, or a command-line tool.
Since the "Smart TV" cannot show a login screen, Microsoft invented a decoupled process.
- The Device (Attacker's Script) says: "Hello Microsoft, I want to log in user
test."
- Microsoft says: "Okay. I am waiting. Here is a short code (e.g.,
B4X9J). Tell the user to go tomicrosoft.com/deviceloginon their computer and type this code."
- The User (Attacker's Browser) goes to that URL, types the code, and logs in.
- Microsoft tells the Device: "The user successfully logged in on their computer. Here are your tokens."
Why We Abuse It (The Bypass)
The vulnerability lies in Authentication Context. Conditional Access Policies (MFA rules) examine who is logging in and what app they are using.
In the Lab, we deliberately force the script to use the Client ID for the Microsoft Intune Company Portal application (9ba1a5c7-f17a-4de9...).
Most companies want employees to easily enroll their phones (BYOD) into corporate management. Therefore, they often create exceptions in their Conditional Access Policies for the Intune Company Portal app to avoid blocking new device setups.
By telling Azure, "I am the Intune Company Portal," we trick the system into applying those looser security policies to our PowerShell script. This frequently lets us log in with just a username and password, skipping MFA entirely.
Why is this better than Portal Hopping?
When you steal a token from the browser ("Portal Hopping"), you get an Access Token. This lasts for about 1 hour. Once it expires, you are locked out again.
The Device Code Flow returns a Refresh Token. A Refresh Token lasts for 90 days. It allows you to request new Access Tokens whenever you want. This is Persistence. You do not need to re-run the login process or re-phish the user. You essentially have a permanent key to the account until the password changes.
The Steps in the Manual (Simplified)
Step 1: The Request (PowerShell)
You can run the following script below using the Intune Client ID. It sends a POST request to Azure. Azure responds with a user_code and tells you to go to the login page.
$ClientID = "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223"
$Scope = ".default offline_access"
$body = @{
"client_id" = $ClientID
"scope" = $Scope
}
$authResponse = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode" -Body $body
$authResponseAt this point, your PowerShell script pauses and starts "polling" (asking) Azure: "Did they sign in yet? How about now?"
Step 2: The Authentication (Browser)
You open your browser (Incognito), go to microsoft.com/devicelogin, and type the code.
You sign in with test@defcorphq... and the password.
Crucially, because Azure sees the request coming from "Intune App," it skips the MFA challenge.
Step 3: The Capture (PowerShell)
The moment your browser says "You have signed in," your PowerShell script receives a massive block of text. This contains the Access Token (for Graph API) and the Refresh Token.
In the PowerShell console, that you used to request the device code, run the below code to request refresh token and access token for the Graph API
$GrantType = "urn:ietf:params:oauth:grant-type:device_code"
$body=@{
"client_id" = $ClientID
"grant_type" = $GrantType
"code" = $authResponse.device_code
}
$Tokens = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://login.microsoftonline.com/common/oauth2/v2.0/token" -Body $body -ErrorAction SilentlyContinue
$Tokens
$GraphToken = $Tokens.access_tokenThe script even shows how to reuse that Refresh Token to specifically ask for an ARM Token (management.azure.com), giving you control over infrastructure.
To request access token for the ARM API, use the following code. Remember to use the same PowerShell session as above as we are re-using values in some variables.
$scope = 'https://management.azure.com/.default'
$refresh_token = $tokens.refresh_token
$GrantType = 'refresh_token'
$body=@{
"client_id" = $ClientID
"scope" = $Scope
"refresh_token" = $refresh_token
"grant_type" = $GrantType
}
$Token_output = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://login.microsoftonline.com/common/oauth2/v2.0/token" -Body $body
$token = $Token_output.access_tokenWe can now use these tokens with Az PowerShell, Mg module or direct API calls.
Import-Module .\AADInternals.psd1
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache
Automated Optimization: MFASweep
The manual methods rely on us guessing which applications are insecure. In a complex enterprise, IT admins might block Intune but leave something else open, like the Microsoft Teams API or Exchange Web Services.
We use MFASweep to brute-force this discovery process.
The Logic
MFASweep takes your single credential (username and password) and systematically attempts to authenticate against a large list of known Microsoft Application IDs. It tries to log in as Outlook, then SharePoint, then Graph, then ARM, and so on.
Execution
Invoke-MFASweep -Username test@defcorphq... -Password 'Password123'
Output Analysis
The tool will print a table showing the status for each service:
- MFA Required: The login failed. We cannot use this App ID.
- Bypassed: The login succeeded with only a password.
Strategic Value
If MFASweep tells us that the "Microsoft Graph PowerShell" app ID bypasses MFA, we immediately configure our tools (like roadtx or our Device Code script) to use that specific Client ID. This eliminates trial and error and pinpoints exactly where the security policy has gaps.
Enumeration - Mg Module (Microsoft Graph PowerShell)
This module allows you to interact directly with the Microsoft Graph API, which is the "control plane" for Entra ID (Identity). As a pentester, you rely on this tool to map the organizational structure, identify high-value targets, and find the "Hybrid Identity" connections that allow pivoting between the cloud and on-premise networks.
Connection & Session (Pass-the-Token)
In a typical Red Team scenario, you often obtain an access token through phishing (Evilginx), device code flow, or by extracting it from a compromised machine's browser memory or token cache. You rarely use interactive login here. Instead, you inject this "Bearer Token" to establish a session, bypassing MFA requirements.
Let’s use the command below on PowerShell, that will simply open a Microsoft Login Pop up and once we login, the token will be imported into our current PowerShell session.
Connect-MgGraph
After authenticating, you must verify the context of your session. This command reveals which user identity you have assumed and, crucially, what Scopes (permissions) are attached to your token. It helps you verify if you have broad read access (Directory.Read.All) or restricted user access.
Get-MgContext
- ClientId: The unique ID of the application (tool) communicating with Azure.
- TenantId: The unique ID of the organization's Azure/Entra ID directory you are connected to.
- Scopes: The specific permissions (privileges) granted to your current session (e.g., ability to Read All Directories).
- AuthType: The permission model used.
Delegatedmeans you are performing actions on behalf of a specific logged-in user.
- TokenCredentialType: How the authentication was performed.
InteractiveBrowsermeans the user logged in via a pop-up window.
- Account: The specific user email or identity currently authenticated.
- AppName: The friendly name of the tool connecting (here, the standard Microsoft Graph Command Line Tools).
- ContextScope: Indicates if the session is specific to the
CurrentUseror the whole Process.
- PSHostVersion: The version of PowerShell running on the local machine.
- Environment: The specific Azure cloud instance (Global = Standard Commercial Azure, vs. US Government or China).
Flags like CertificateThumbprint, ManagedIdentityId, and ClientSecret are blank because those specific authentication methods were not used for this session.
To ensure you are targeting the correct client, you query the organization details. This confirms the Tenant ID and lists the verified domains. This prevents you from running active enumeration against a wrong or decoy tenant.
Get-MgOrganization | fl *
- AssignedPlans: The service plans (licenses) associated with this organization.
- Branding: Custom visual settings for the login page (logos/backgrounds).
- City/Country/Street/PostalCode: The physical location details of the organization (Singapore).
- CreatedDateTime: The timestamp when this specific Azure/Entra tenant was created.
- DisplayName: The friendly name of the company (Defense Corporation).
- Id: The Tenant ID (Directory ID), a globally unique GUID used to identify this organization.
- ProvisionedPlans: Specific services that are currently active and available for use in the tenant.
- TechnicalNotificationMails: The email address that receives technical alerts (often reveals a real Admin email).
- TenantType: The directory type (
AAD= Entra ID/Azure Active Directory).
- VerifiedDomains: The domains the organization has officially registered and verified for use (e.g., email domains).
- AdditionalProperties: Extra data returned by the API that doesn't fit standard fields, often containing sync status or directory quotas.
User Enumeration & Reconnaissance
The foundation of enumeration is dumping the directory to build target lists. This command retrieves every user object in the tenant. Red teams use this to build lists of valid email addresses for password spraying or to identify naming conventions.
Get-MgUser -All
When you identify a potentially high-value target, you need to inspect them closely. By targeting a specific User ID, you can view extended properties like their mobile number, department, or job title.
Get-MgUser -UserId test@defcorphq.onmicrosoft.com | fl *
Instead of dumping everything, you can use server-side filtering to find interesting accounts quickly. This command searches specifically for the string "admin" in DisplayName, which is the fastest way to identify administrative service accounts or privileged staff.
Get-MgUser -Search '"DisplayName:admin"' -ConsistencyLevel eventual
One of the most valuable enumeration steps is distinguishing "Hybrid" users from "Cloud-Only" users. If the OnPremisesSecurityIdentifier property is not null, the user is synced from an on-premise Active Directory. If you compromise this user, you have a potential path to move laterally from Azure back to the local Domain Controller.
Get-MgUser -All | ?{$_.OnPremisesSecurityIdentifier -ne $null}
Conversely, you can identify cloud-native users by filtering for those with a null On-Premises SID. Targeting these users limits your blast radius to the cloud environment but is often useful for establishing initial persistence.
Get-MgUser -All | ?{$_.OnPremisesSecurityIdentifier -eq $null}
Determining User Impact & Influence
To profile a target's history, you check what objects they created. This serves as an audit trail. If a user created a specific application years ago, they might still have hardcoded credentials for it in their old files, or it might be a shadow IT resource they manage.
Get-MgUserCreatedObject -UserId test@defcorphq.onmicrosoft.com | fl *
Ownership is a powerful privilege in Azure. If a user "Owns" an object (like a Group or Application), they can effectively manage it. For example, if your user owns a group, you can add yourself to that group. This command maps out everything the target user can currently control.
Get-MgUserOwnedObject -UserId test@defcorphq.onmicrosoft.com | fl *
To understand the privileges of your compromised user, you must know their group memberships. This helps you identify if the user is a "Shadow Admin" via nesting, for example, being a member of a group that is a member of the "Global Administrators" role.
Get-MgUserMemberOf -UserId test@defcorphq.onmicrosoft.com
Groups and Dynamic Memberships
Mapping groups reveals the organizational hierarchy. You look for high-value team names like "Finance," "DevOps," or "Secure Projects" which imply access to sensitive data repositories.
Get-MgGroup -All
Once you have a list, you can search for specific, interesting groups to get their Object IDs for further analysis.
Get-MgGroup -Filter "DisplayName eq 'VM Admins'" | fl *
Dynamic Groups are a tactical entry point. These groups automatically add members based on rules (e.g., user.department -eq "IT"). If you have the permissions to edit your own user attributes, you can change your department to "IT" and the system will automatically add you to this group, granting you its access. This command finds groups susceptible to this attack.
Get-MgGroup | ?{$_.GroupTypes -eq 'DynamicMembership'}
Once a high-value group is identified, you need to see who is in it. This gives you a hit-list of users to target for phishing or token theft. If you compromise any member of this group, you inherit the group's access.
Get-MgGroupMember -GroupId [GroupId]
Administrative Roles & Units
Entra ID roles (like Global Administrator) work differently than groups. Roles are "Activated." This command lists the directory roles that are currently enabled in the tenant, showing you which privileges are actively being used.
Get-MgDirectoryRole | fl *
Role Templates show you the definition of roles available in the tenant. This is useful for understanding what roles exist, even if they aren't currently active, helping you map out potential privilege escalation paths.
Get-MgDirectoryRoleTemplate | fl *
Custom Roles are a major source of misconfigurations. Administrators often create custom roles with minimal intent but accidental high privilege. This command filters for roles that are not built-in, which should be inspected carefully for dangerous permissions like resetting passwords.
Get-MgRoleManagementDirectoryRoleDefinition | ?{$_.IsBuiltIn -eq $False}
Some permissions are scoped restrictively using Administrative Units (AUs). A user might be a User Administrator, but only for the "Contractors" unit. Finding these units is critical to understanding why a high-privilege account might be failing to execute actions against other users.
Get-MgDirectoryAdministrativeUnit | fl *
The most critical check is finding the "Keys to the Kingdom." By targeting the Role ID for "Global Administrator," you can list every user who holds ultimate power over the tenant.
$RoleId = (Get-MgDirectoryRole -Filter "DisplayName eq 'Global Administrator'").Id
(Get-MgDirectoryRoleMember -DirectoryRoleId $RoleId).AdditionalProperties
Applications & Service Principals
This enumerates the "App Registrations" or abstract definitions of applications. Pentesters look here to understand what Line-of-Business apps the company has developed and what permissions they request.
Get-MgApplication -All
Apps configured with Passwords (Secrets) instead of Certificates are vulnerable targets. If you can find the cleartext secret (in a code repo or config file), you can impersonate the application. This command filters the list for these softer targets.
Get-MgApplication -All | ?{$_.PasswordCredentials -ne $null}
This lists the "Service Principals," which are the actual running instances of applications in the tenant. This includes third-party Enterprise Applications like Salesforce or Service Now.
Get-MgServicePrincipal -All
To inspect the privileges of a specific Service Principal, you filter for it by name.
Get-MgServicePrincipal -Filter "DisplayName eq 'Finance Management System'"
Just like users, Service Principals can be owners of other objects. This checks for "Robot Privilege Escalation". If a Service Principal owns a Group, and you compromise the App, you can manipulate that group.
Get-MgServicePrincipalOwnedObject -ServicePrincipalId [ObjectId]
Device Enumeration
This lists all devices registered in the directory. You use this to plan lateral movement (like Pass-the-PRT) by identifying machines associated with high-value users.
Get-MgDevice -All
Old device records are common in Azure. This filter cleans up the data by showing only devices that have signed in recently, ensuring you are targeting active infrastructure.
Get-MgDevice -All | ?{$_.ApproximateLastSignInDateTime -ne $null}
2. Enumeration - Az PowerShell (Azure Resource Manager)
This is the standard administrative tool for managing infrastructure. While Mg Module focused on Identity, this module focuses on Resources (VMs, Storage, Key Vaults). You use this to find sensitive data and execution paths.
Connection (Identity & Resource Hybrid)
In advanced attacks, you often possess separate tokens for Graph (Identity) and ARM (Infrastructure). The Connect-AzAccount command allows you to explicitly pass both. This is essential because standard login prompts might trigger MFA or Conditional Access.
Connect-AzAccount
Infrastructure Mapping
This is your primary reconnaissance command. It returns an inventory of everything you have access to. You look through this output for interesting names like "Confidential," "Backup," "Prod," or "Sensitive."
Get-AzResource
- Name: The specific label of the asset (
defcorpcommon). Discovery: The name "common" suggests this is likely a shared repository.
- ResourceGroupName: The logical container or "department folder" this asset belongs to (
Finance). Discovery: We now know the Finance department has segregated infrastructure.
- ResourceType: The technical service type (
Microsoft.Storage/storageAccounts). Discovery: We confirmed this is a Storage Account (cloud file share), making it a high-value target for finding sensitive financial documents.
- Location: The physical data center where the data lives (
germanywestcentral).
- ResourceId: The unique, full API path to access this object
/subscriptions/.../storageAccounts/defcorpcommon.
- Tags: Optional metadata labels (currently empty).
The "Crown Jewels" (High-Value Targets)
ResearchKeyVault: We found a Key Vault. This is the highest priority target because it likely contains encryption keys, secrets, or passwords that could unlock the rest of the environment.
defcorpcommon: We found a Finance Storage Account. The name "common" suggests it is a shared file repository, likely containing sensitive financial documents or backups.
The Attack Vectors (Entry Points)
processfile&vaultfrontend: We identified two Web Applications. These are our "front doors." As a red teamer, we would scan these next for web vulnerabilities (like insecure file uploads) to get code execution.
bkpadconnect: We found a Virtual Machine in the Engineering group. This is a potential foothold for lateral movement if we can access its management ports.
The Defensive Posture (OpSec Warning)
MicrosoftMonitoringAgent: We detected that the Engineering VM has a monitoring extension installed. This warns us that logging is active, so any attacks against that specific server need to be stealthy to avoid tripping alerts.
The Logic of the Environment
- We confirmed the organization segregates its resources by Department (Resource Groups:
IT,Research,Engineering,Finance). This helps us understand the "Blast Radius", compromising an Engineering account might not automatically give us access to Finance data.
Azure resources are organized into "Folders" called Resource Groups. Mapping these groups helps you understand the logic of the environment (e.g., separated by Environment like Dev/Prod or by Department like HR/Finance).
Get-AzResourceGroup
Credential Mining (Deployment History)
This is a critical enumeration step. When administrators deploy resources, they often use automated JSON templates. If the deployment fails or even if it succeeds, the parameters (often including Admin Passwords) are saved in the logs. This command checks the history of a Resource Group.
Get-AzResourceGroupDeployment -ResourceGroupName [Name]
Once you identify an interesting deployment from the history, you download the actual template file to your machine. You can then open this text file and search for "Password" or "Secret" to find cleartext administrative credentials.
Save-AzResourceGroupDeploymentTemplate -ResourceGroupName [Group] -DeploymentName [DeployName]
Privilege Discovery (Resource RBAC)
This command answers the question: "What am I allowed to do to in this infrastructure?" It lists your specific RBAC assignments. If you see "Contributor" or "Owner" over a Subscription or VM, you have full control.
Get-AzRoleAssignment -SignInName test@defcorphq.onmicrosoft.com
When you encounter a Custom Role with an unfamiliar name (like "VM Operator"), you must inspect its definition. This command reveals the specific Actions (permissions) granted, often uncovering hidden dangerous capabilities like runCommand.
Get-AzRoleDefinition -Name "Virtual Machine Command Executor"
Compute & Execution Paths
This lists the Virtual Machines in the subscription, in this case, we can list all VMs where our current user has minimum Read role. We examine the OS type (Windows/Linux) and size to identify potential jump hosts or servers critical to operations.
Get-AzVM | fl *
We must also list all App Services. We filter on the bases of 'Kind' proper otherwise both appservices and functionapps are listed.
Azure groups "Websites" and "Functions" (serverless scripts) together under the same category. This command filters the list to remove the Functions. It gives you a clean list of just the web portals, the "front doors" that users interact with.
Get-AzWebApp | ?{$_.Kind -notmatch "functionapp"}
Extensions are scripts or agents installed on a VM. Finding "CustomScriptExtension" is gold for a red teamer, as the script files themselves often contain hardcoded credentials or API keys that the administrator used for setup.
Get-AzVMExtension -ResourceGroupName [Group] -VMName [Name]
This verifies network exposure. It identifies which IPs are publicly facing, giving you potential entry points for external scanning or exploitation.
Get-AzPublicIpAddress
Network Interfaces confirm internal IP addressing. You use this to plan pivoting or socks proxying into private subnets.
Get-AzNetworkInterface
Serverless Functions (Function Apps) run code snippets. You target these because they utilize Managed Identities to access other resources. If you can compromise the Function App (via code injection or weak configuration), you can steal its identity.
Get-AzFunctionApp
Storage & Sensitive Data
Key Vaults are the "crown jewels." They store the passwords, API keys, and certificates for the entire environment. Gaining access to a Vault is a primary objective.
Get-AzKeyVault
If you have permission, this command dumps the actual metadata of the secrets stored inside the vault.
Get-AzKeyVaultSecret -VaultName [Name]
This It pulls the plaintext value of a secret (like a database password) to your screen, effectively compromising whatever system that password protects.
Get-AzKeyVaultSecret -VaultName [Name] -Name [SecretName] -AsPlainText
Storage accounts are massive buckets of data. You enumerate these to look for containers with names like "logs" or "backups" which often contain sensitive info and may be misconfigured to allow public anonymous access.
Get-AzStorageAccount | fl
Enumeration - Azure CLI (az cli)
Priority: Rapid Assessment
Role: Cross-platform Querying & JSON Filtering
Context: Developers use this tool extensively. If you land on a developer workstation, you likely have this tool pre-authenticated. Its "JMESPath" query language allows you to filter huge datasets much faster than PowerShell loops.
Authentication
This initiates an interactive login in the browser. In an attack, you might use az account get-access-token if you are already on a logged-in machine to steal the current token.
az login
This confirms the identity of the current session. It acts as the whoami for the Azure cloud environment.
az ad signed-in-user show
Identity Querying
This dumps a simple, visual table of all users in the directory. It is the fastest way for a human operator to verify the names of accounts.
az ad user list -o table
This uses a query filter to list ONLY the users synced from on-premise AD. This creates an immediate targeting list for lateral movement from Cloud -> On-Prem.
az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName"
You can also list all users and grab specific fields like their "Job Title" to identify potential admins, using a different table output format.
az ad user list --query "[].[displayName,jobTitle]" -o table
[Screenshot Placeholder: Table of Users and Job Titles]
To quickly check the membership of a specific high-value group like "VM Admins," use this command. It avoids dumping all groups and focuses on the specific target.
az ad group member list -g "VM Admins"
Resource & App Enumeration
This provides a quick target list of Virtual Machines by Name only. This list can be fed into other scanning tools.
az vm list
az vm list --query "[].[name]" -o table
Service Principals represent applications. This command searches the entire directory for any application with the string "app" in its name. This helps find custom apps while filtering out the default Microsoft background services.
az ad sp list --all --query "[?contains(displayName,'app')].displayName"
This is a specific vulnerability hunter. It lists all Applications that have a Password credential (rather than a Certificate). Password-based apps are prioritized targets because their secrets are static strings that developers often accidentally leak in code.
az ad app list --query "[?passwordCredentials != null].displayName"













































