Mastering Azure Enumeration: Techniques for Unauthenticated and Authenticated Hacking
Terminology-
- Tenant — An instance of Azure AD and represents a single organization.
- Azure AD Directory — Each tenant has a dedicated Directory. This is used to perform identity and access management functions for resources.
- Subscriptions — It is used to pay for services. There can be multiple subscriptions in a Directory.
- Core Domain — The initial domain name
<tenant>.onmicrosoft.com
is the core domain. It is possible to define custom domain names too.
Managed Identity(Similar to roles in AWS)-
- Azure provides the ability to assign Managed Identities to resources like app services, function apps, virtual machines, etc.
- Managed Identity uses Azure AD tokens to access other resources (like key vaults, and storage accounts) that support Azure AD authentication.
- It is a service principal of a special type that can be used with Azure resources.
- Managed Identity can be system-assigned (tied to a resource and cannot be shared with other resources) or user-assigned (independent life cycle and can be shared across resources).
Unauthenticated-
Tenant Information
https://login.microsoftonline.com/getuserrealm.srf?login=pswalia2u.onmicrosoft.com
Set-ExecutionPolicy bypass
Import-Module .\AADInternals.psd1
Get-AADIntLoginInformation -UserName pswalia2u@pswalia2u.onmicrosoft.com
Another way using POST request to https://login.microsoftonline.com/common/GetCredentialType
$UserName = "pswalia2u@pdfmerge.work"
$URI = 'https://login.microsoftonline.com/common/GetCredentialType'
$RequestParams = @{
Method = 'POST'
Uri = $URI
Body = @{
'Username' = $UserName
} | ConvertTo-Json
}
$Result = Invoke-RestMethod @RequestParams
If($Result.IfExistsResult -eq 0){
Write-Output "$UserName is Valid"
}else{
Write-Output "$UserName is Invalid"
}
Oauth Endpoint-
https://login.microsoftonline.com/pswalia2u.onmicrosoft.com/.well-known/openid-configuration
Retrieved info-
token_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/oauth2/token
#TenantID ab0d55f7-6101-4073-8c76-3cb36cd1a3ee
token_endpoint_auth_methods_supported : {client_secret_post, private_key_jwt, client_secret_basic}
jwks_uri : https://login.microsoftonline.com/common/discovery/keys
response_modes_supported : {query, fragment, form_post}
subject_types_supported : {pairwise}
id_token_signing_alg_values_supported : {RS256}
response_types_supported : {code, id_token, code id_token, token id_token...}
scopes_supported : {openid}
issuer : https://sts.windows.net/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/
microsoft_multi_refresh_token : True
authorization_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/oauth2/authorize
device_authorization_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/oauth2/devicecode
http_logout_supported : True
frontchannel_logout_supported : True
end_session_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/oauth2/logout
claims_supported : {sub, iss, cloud_instance_name, cloud_instance_host_name...}
check_session_iframe : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/oauth2/checksession
userinfo_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/openid/userinfo
kerberos_endpoint : https://login.microsoftonline.com/ab0d55f7-6101-4073-8c76-3cb36cd1a3ee/kerberos
tenant_region_scope : EU
cloud_instance_name : microsoftonline.com
cloud_graph_host_name : graph.windows.net
msgraph_host : graph.microsoft.com
rbac_url : https://pas.windows.net
Get-AADIntTenantID -Domain <your-org>.onmicrosoft.com
Get-AADIntTenantDomains -Domain pswalia2u.onmicrosoft.com
Get-AADIntTenantDomains -Domain microsoft.com
curl.exe "https://outlook.office365.com/autodiscover/autodiscover.json?Email=mariewilliams@pharmacorphq.onmicrosoft.com&Protocol=Autodiscoverv1"
Enum Domains-
https://github.com/RoseSecurity/Enum_AzureSubdomains
redis.cache.windows.net Databases-Redis
documents.azure.com Databases-Cosmos DB
database.windows.net Databases-MSSQL
vault.azure.net Key Vaults
onmicrosoft.com Microsoft Hosted Domain
mail.protection.outlook.com Email
sharepoint.com SharePoint
azureedge.net CDN
search.windows.net Search Appliance
azure-api.net API Services
portal.cloudappsecurity.com Microsoft Defender for Cloud Apps
azurewebsites.net App Services
scm.azurewebsites.net App Services - Management
p.azurewebsites.net App Services
cloudapp.net App Services
file.core.windows.net Storage Accounts-Files
blob.core.windows.net Storage Accounts-Blobs
queue.core.windows.net Storage Accounts-Queues
table.core.windows.net Storage Accounts-Tables
Import-Module .\MicroBurst.psm1 -Verbose
Invoke-EnumerateAzureSubDomains -Base microsoft -Verbose
https://github.com/dafthack/MFASweep.git
Invoke-MFASweep -Username user-email -Password "test@123"
contact@defcorphq.onmicrosoft.com
admin@defcorphq.onmicrosoft.com
root@defcorphq.onmicrosoft.com
test@defcorphq.onmicrosoft.com
hello@defcorphq.onmicrosoft.com
Authenticated-
Using MG Module-
Install-Module -Name Az -AllowClobber -Force; Import-Module Az
#Creating Pscredential object
$passwd = ConvertTo-SecureString "secret_password" -AsPlainText -Force `
; $creds = New-Object System.Management.Automation.PSCredential ("email", $passwd) `
; Connect-AzAccount -Credential $creds
#Note If MFA is present run only "Connect-AzAccount" and perform interactive login
Install-Module Microsoft.Graph -AllowClobber -Force
$token=(Get-AzAccessToken -ResourceTypeName MSGraph).token
OR
$token = (az account get-access-token --resource https://graph.microsoft.com | ConvertFrom-Json).accessToken
OR
$token = (az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv)
Connect-MgGraph -AccessToken ($Token | ConvertTo-SecureString -AsPlainText -Force)
#Whoami
Get-MgContext
Get-MgOrganization | fl *
Get-Mguser -All | Measure
#Enumerate a specific user
Get-MgUser -UserId pswalia2u@pswalia2u.onmicrosoft.com
#Search for a user based on string in first characters of DisplayName or userPrincipalName (wildcard not supported)
Get-MgUser -Filter "startsWith(DisplayName, 'a')" -ConsistencyLevel eventual
Search for users who contain the word "admin" in their Display name:
Get-MgUser -All | ?{$_.Displayname -match "admin"}
Get-MgUser -Search 'DisplayName:admin' -ConsistencyLevel eventual
Get-MgUser -UserId <email> | fl *
Get-MgUser -UserId <email> | %{$_.PSObject.Properties.Name}
All users who are synced from on-prem:
Get-MgUser -All | ?{$_.OnPremisesSecurityIdentifier -ne $null}
All users who are from Azure AD:
Get-MgUser -All | ?{$_.OnPremisesSecurityIdentifier -eq $null}
#Retrieves objects created by any user, with an option to specify a particular user using -ObjectId
Get-MgUserCreatedObject -UserId <email> | fl *
#Retrieves objects owned by a specific user.
Get-MgUserOwnedObject -UserId test@defcorphq.onmicrosoft.com | fl *
Groups
#All groups that are synced from on-prem (note that security groups are not synced)
Get-MgGroup -All | ?{$_.OnPremisesSecurityIdentifier -ne $null}
#All groups that are from Azure AD
Get-MgGroup -All | ?{$_.OnPremisesSecurityIdentifier -eq $null}
#Get groups and roles where the specified user is a member
(Get-MgUserMemberof -UserId <email>).AdditionalProperties
#Roles
Get all available role templates
Get-MgDirectoryRoleTemplate
#Roles which have been enabled atleast once
Get-MgDirectoryRole
Get-MgDirectoryRole | fl
#Enumerate users to whom roles are assigned
$RoleId = (Get-MgDirectoryRole -Filter "DisplayName eq 'Global Administrator'").Id `
; ((Get-MgDirectoryRoleMember -DirectoryRoleId $RoleId).AdditionalProperties).userPrincipalName
Domain Joined Devices:
Get all Azure joined and registered devices
Get-MgDevice -All | fl *
Get-MgDevice -All | Where-Object { $_.DisplayName -like "*honeypot*" } | fl *
List Registered Owners of all the devices
$ids = (Get-MgDevice -All).Id; foreach ($id in $ids) { (Get-MgDeviceRegisteredOwner -DeviceId $id).AdditionalProperties }
Registered Owner's email
$ids = (Get-MgDevice -All).Id; foreach ($id in $ids) { (Get-MgDeviceRegisteredOwner -DeviceId $id).AdditionalProperties.userPrincipalName }
List Registered Users of all the devices
$Ids = (Get-MgDevice -All).Id; foreach($i in $Ids){ (Get-MgDeviceRegisteredUser -DeviceId $i).AdditionalProperties}
List Registered User's email
$Ids = (Get-MgDevice -All).Id; foreach($i in $Ids){ (Get-MgDeviceRegisteredUser -DeviceId $i).AdditionalProperties.userPrincipalName}
Get owned devices by a user
(Get-MgUserOwnedDevice -userId <email>).AdditionalProperties
Get registered devices by user
(Get-MgUserRegisteredDevice -userId <email>).AdditionalProperties
List devices managed using Intune
Get-MgDevice -All | ?{$_.IsCompliant -eq "True"} | fl *
- Registered User (
Get-MgDeviceRegisteredUser
): This refers to users who have signed into or registered with the device but are not necessarily the owners of the device. - Registered Owner (
Get-MgDeviceRegisteredOwner
): This refers to the user(s) who are officially considered the owner(s) of the device.
App Registrations-
#App registrations (All registered applications in an Azure Active Directory (AAD) tenant.)
Get-MgApplication -All
#Get information of a specific App
Get-MgApplicationByAppId -AppId 3c67156d-b5ff-4eed-a66f-e2b5462f7b70 | fl *
#Below cmd will show all the applications details including password but password value is not shown. List all the apps with an application password
Get-MgApplication -All | ?{ $_.PasswordCredentials -ne $null }
Service Principals/Enterprise Applications-
Get-MgServicePrincipal -All
#Get all details about a service principal
Get-MgServicePrincipal -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791 | fl *
#Get an service principal based on the display name
Get-MgServicePrincipal -All | ?{ $_.DisplayName -match "chatgpt" }
#List all the service principals with an application password
Get-MgServicePrincipal -All | ?{ $_.KeyCredentials -ne $null }
Get-MgServicePrincipal -All | ?{ $_.KeyCredentials -ne $null } | fl *
#Get owner of a service principal
(Get-MgServicePrincipalOwner -ServicePrincipalId 9d9c5d6e-a594-4148-a48e-9551fbb0de07).AdditionalProperties.userPrincipalName
#Get Objects owned by a service principal
Get-MgServicePrincipalOwnedObject -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791
#Get Objects Created by a service principal
Get-MgServicePrincipalCreatedObject -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791
#Get group and role memberships of a service principal
Get-MgServicePrincipalMemberOf -ServicePrincipalId 9d9c5d6e-a594-4148-a48e-9551fbb0de07 | fl *
Using Az Powershell Module-
Authenticating-
#Opens browser for authentication
Connect-AzAccount
#Takes id/password in a prompt
$creds = Get-Credential
Connect-AzAccount -Credential $creds
#Uses
$passwd = ConvertTo-SecureString "SuperVeryEasytoGuesPassword@1234" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("Email", $passwd)
Connect-AzAccount -Credential $creds
Login
We can use the Az PowerShell module to enumerate Azure and Azure EntraID resources.
Listing logged-in accounts-
Get-AzContext -ListAvailable
Checking current context(Account being used to run command):
Get-AzContext
There are 51 Azure AD/Entra ID-related commands and overall 6300 commands related to Azure
#All AzureAD commands have
Get-Command *azad*
Get-Command *azad* | measure
Get-Command -Verb Get -Noun *vm*
Get-AzADUser
#Get the information about the current context (Account, Tenant, Subscription etc.)
Get-AzContext
#lists all the contexts which were used on the device.
#We can use Set-Azcontext to use one of the availble context
#with active access token
Get-AzContext -ListAvailable
#Enumerate all resources visible to the current user
Get-AzSubscription
#get all the resources which are visible to current user
Get-Azresource
#Enumerate all Azure RBAC role assignments
Get-AzRoleAssignment
#List VMs
Get-AzVM | fl
Get-AzVM | Select-Object -ExpandProperty NetworkProfile | fl
#List Web APPs
Get-AzWebapp
#List Function Apps
Get-AzFunctionApp
#Storage accounts
(Get-AzStorageAccount | Select -ExpandProperty NetworkRuleSet).IpRules
Get-AzResourceGroup
Get-AzResource
Get-AzWebApp
Get-AzStorageAccount
Get-AzKeyVault
Get-AzSqlServer
Azure cli-
az login
#If the user has no permissions on the subscription
az login -u test@defcorphq.onmicrosoft.com -p SuperVeryEasytoGuessPassword@1234 --allow-no-subscriptions
#Get details of the current tenant (uses the account extension):
az account tenant list
#Whoami
az account show
#Get details of the current subscription (uses the account extension)
az account subscription list
#List the current signed-in user:
az ad signed-in-user show
#List available profiles
az account list
#Switching profiles
az account set --subscription 4034513d-bdad-429d-bc93-6b4d9f0b0c97
az configure
#To find popular commands for VMs
az find "vm"
#To find popular commands within "az vm"
az find "az vm"
#To find popular subcommands and parameters within "az vm list"
az find "az vm list"
#Enumerate all users
az ad user list
az ad user list --query "[].displayName" -o table
az ad user list --output table
#Enumerate a specific user (lists all attributes)
az ad user show --id <emial>
#Search for users who contain the word "admin" in their Display name (case sensitive):
az ad user list --query "[?contains(displayName,'admin')].displayName"
#When using PowerShell, search for users who contain the word "admin" in their Display name. This is NOT case-sensitive:
az ad user list | ConvertFrom-Json | %{$_.displayName -match "admin"}
#All users who are synced from on-prem
az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName"
#All users who are from Azure AD
az ad user list --query "[?onPremisesSecurityIdentifier==null].displayName"
#Get all the application objects registered with the current tenant
#(visible in App Registrations in Azure portal). An application object
#is the global representation of an app.
az ad app list
az ad app list --query "[].[displayName]" -o table
#Get all details about an application using identifier URI,
#application ID, or object ID.
az ad app show --id fd0beb15-718d-43a5-a1f2-b5ef9229afa7
#Get an application based on the display name(Run in cmd and it is case sensitive)
az ad app list --query "[?contains(displayName,'App')].displayName"
#Get an application based on the display name(run in powershell and not casesensitive)
az ad app list | ConvertFrom-Json | %{ $_.displayName -match "app" }
#Get owner of an application
az ad app owner list --id a1333e88-1278-41bf-8145-155a069ebed0 --query "[].displayName" -o table
#List apps that have password credentials
az ad app list --query "[?passwordCredentials != null].displayName"
#List apps that have key credentials (use of certificate authentication)
az ad app list --query "[?keyCredentials != null].displayName"
#List all Groups
az ad group list
az ad group list --query "[].displayName" -o table
#Enumerate a specific group using display name or object id
az ad group show -g "VM Admins"
az ad group show -g 783a312d-0de2-4490-92e4-539b0e4ee03e
#Search for groups that contain the word "admin" in their Display name (case sensitive) - run from cmd:
az ad group list --query "[?contains(displayName,'admin')].displayName"
az ad group list | ConvertFrom-Json | %{$_.displayName -match "admin"}
#All groups that are synced from on-prem
az ad group list --query "[?onPremisesSecurityIdentifier!=null].displayName"
#All groups that are from Azure AD
az ad group list --query "[?onPremisesSecurityIdentifier==null].displayName"
#Get members of a group
az ad group member list -g "VM Admins" --query "[].displayName" -o table
#Check if a user is member of the specified group
az ad group member check --group "VM Admins" --member-id b71d21f6-8e09-4a9d-932a-cb73df519787
#Get the object IDs of the groups of which the specified group is a member
az ad group get-member-groups -g "VM Admins"
#Service Principals
#Enumerate Service Principals (visible as Enterprise Applications
#in Azure Portal). Service principal is local representation for
#an app in a specific tenant and it is the security object that has privileges. This is the 'service account'!
#Service Principals can be assigned Azure roles.
#Get all service principals:
az ad sp list --all
az ad sp list --all --query "[].[displayName]" -o table
#Get all details about a service principal using service principal ID or object ID:
az ad sp show --id ffedb8fa-6b7c-4d18-946e-30d330c00645
#Get a service principal based on the display name
az ad sp list --all --query "[?contains(displayName,'app')].displayName"
#When using PowerShell, search for service principals that contain the
#word "slack" in their display name. This is NOT case-sensitive
az ad sp list --all | ConvertFrom-Json | %{ $_.displayName -match "app" }
#
az ad sp owner list --id fd51bc12-e707-4df0-b45f-af2e0c5aa4a9 --query "[].[displayName]" -o table
#Service Principals owned by current user
az ad sp list --show-mine
#List apps that has password credentials
az ad sp list --all --query "[?passwordCredentials != null].displayName"
#List apps that have key credentials (use of certificate authentication)
az ad sp list --all --query "[?keyCredentials != null].displayName"
Location of Tokens and Auth info:
C:\Users\<User>\.Azure
#ServicePrincipalSecret is stored in clear text in AzureRmContext.json in C:\Users\<User>\.Azure\ directory
Azurehound-
(Get-AzAccessToken -ResourceTypeName MSGraph).Token
.\azurehound.exe -j <token> --tenant <example.onmicrosoft.com> list -o output.json
#To upload the zip/json
http://localhost:8080/ui/administration/file-ingest
Setting up o365stealer
apt update -y && apt install python3 php-cli git python3-pip python3-venv sqlite3 vim -y
cd /opt
git clone https://github.com/AlteredSecurity/365-Stealer.git
cd /opt/365-Stealer
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
php -S 0.0.0.0:80
line number 961 remove comments extension=sqlite3
Thanks for Reading!!