Unauthenticated Reconnaissance
Theory
Unauthenticated reconnaissance is the first step in assessing an Azure AD environment. This phase involves gathering information about the target organization's Azure presence without requiring any authentication credentials. The goal is to identify valid domains, user accounts, and potential entry points that can be leveraged in subsequent phases of an engagement.
Practice
Check if Company is Using Azure AD
Before starting any Azure AD enumeration, it's important to verify if the target company is actually using Azure AD. This can be done through various methods.
If the NameSpaceType indicates "Managed", then the company is using Azure AD.
if the NameSpaceType indicates "Federated", then the company is using Active Directory Federation Services (AD FS) .
# Replace <DOMAIN> with the actual target FQDN
curl -s "https://login.microsoftonline.com/getuserrealm.srf?login=username@<DOMAIN>&json=1" | jqTenant Enumeration
Tenant enumeration involves gathering information about the Azure AD tenant configuration, including domain names, authentication methods, and tenant-specific details. This information can be obtained through various public APIs and tools.
TenantID
We can retreive the Tenant ID by quering the OpenID Configuration API endpoint
curl -s https://login.microsoftonline.com/ocd-testing.com/.well-known/openid-configuration | jq .token_endpointDomains
We can enumerate additional domains associated with the tenant using the Autodiscover service:
domain="example.com";curl -s https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc -H "Content-Type: text/xml" -d @- << EOF |xq
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:exm="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:ext="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<a:Action soap:mustUnderstand="1">http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation</a:Action>
<a:To soap:mustUnderstand="1">https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc</a:To>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</soap:Header>
<soap:Body>
<GetFederationInformationRequestMessage xmlns="http://schemas.microsoft.com/exchange/2010/Autodiscover">
<Request>
<Domain>$domain</Domain>
</Request>
</GetFederationInformationRequestMessage>
</soap:Body>
</soap:Envelope>
EOFServices Enumeration
Organizations often use various Azure services that can be discovered through DNS enumeration or by checking common Azure subdomains.
Enumerate Azure SubDomains
It's possible to try to find Azure services exposed in common azure subdomains like the ones documented in this post.
MicroBurst (Powershell) can be used to achieve that goal, and enumerate Azure Subdomains.
# This script takes a base word and a list of permutations and enumerates several Azure services for potential targets.
# Base: The base word to use
# Permutations: A path to a permutation wordlist
Invoke-EnumerateAzureSubDomains -Base company -Permutations ".\permutations.txt" -Verbose The same can be acheive using cloud_enum (python)
python cloud_enum.py -k target.com --disable-aws --disable-gcpEnumerate Azure Storage Accounts & Blobs
Open Storage
Azure Storage Account are Microsoft's cloud storage solution, similar to Amazon S3. It includes several services like the Blob storage, for unstructured data (images, videos, and documents..).
.png)
Anonymous read access may be enabled by a public access policies for blobs. Furthermore, storage resources follow predictable URL patterns at core.windows.net:
- storage-account-name.blob.core.windows.net
- storage-account-name.file.core.windows.net
- storage-account-name.table.core.windows.net
- storage-account-name.queue.core.windows.net
MicroBurst (Powershell) can then be used to brute-force storage account names, containers, and files (blobs):
# This script takes a base word and prefixes/suffixes it with a list of words to identify any storage blobs associated with a target.
# It will also attempt to enumerate any containers in the blob.
## Base: The base word to use
## OutputFile: Where to save the results
## Permutations: A path to a permutation wordlist (default is Microburst/Misc/permutations.txt)
Invoke-EnumerateAzureBlobs -Base company -Permutations ".\permutations.txt" -OutputFile azureblobs.txtSAS URLs
A shared access signature (SAS) URL is an URL that provides access to certain part of a Storage account (could be a full container, a file...) with some specific permissions (read, write...) over the resources. If you find one leaked you could be able to access sensitive information, they look like this (this is to access a container, if it was just granting access to a file the path of the URL will also contain that file):
https://<storage_account_name>.blob.core.windows.net/newcontainer?sp=r&st=2021-09-26T18:15:21Z&se=2021-10-27T02:14:21Z&spr=https&sv=2021-07-08&sr=c&sig=7S%2BZySOgy4aA3Dk0V1cJyTSIf1cW%2Fu3WFkhHV32%2B4PE%3D
Use Storage Explorer to access the data
Enumerate Azure Container Registry (ACR)
By default, access to pull or push images from an Azure Container Registry is only available to authenticated users. But it's possible to allow anonymous pull access.
Authorizing anonymous pulls can be done as follows (need permissions)
az acr update --name <registry-name> --anonymous-pull-enabled trueIf we know such registry name and images, we can pull it as follows
docker pull myregistry.azurecr.io/myimage:latestUser Enumeration
The goal is to compile a list of possible valid email addresses for the targeted company, aiming to identify valid accounts using tools and techniques below.
The GetCredentialType API can be used for username enumeration.
Ensure that the domain is managed (refer to this section) to guarantee accurate results when using this technique. If it doesn't, unmanaged domains can return 0, leading to false positives
# Return values:
#0 The account exists, and uses that domain for authentication
#1 The account doesn’t exist
#2 The response is being throttled
#4 Some server error
#5 The account exists, but is set up to authenticate with a different identity provider. This could indicate the account is only used as a personal account
#6 The account exists, and is set up to use both the domain and a different identity provider
curl -s -X POST https:///login.microsoftonline.com/common/GetCredentialType --data '{"Username":"user1@example.com"}' | jq '.IfExistsResult'