AZ CLI
Virtual Machines
Enumerating VM’s
for a in $(cat azure_subscriptions.txt); do az vm list --subscription $a >> vm_$a.txt; done
App Registrations
Retrieve API Permissions
az ad app list --query '[].{Name:displayName,API:requiredResourceAccess[]}' --all
Check (https://s1hb.sharepoint.com/:x:/g/Technical%20Resources/EQGFqPrbAZBEiGtPa0BChucBBN4aCzF_2lsliHlzx9Oaag?e=6Bz3lU) for the resourceAccess ID to determine what permissions is given for the resourceAccess scope.
Functions
Generate Function Config Statements
for a in $(cat azure_subscriptions.txt); do az functionapp list --subscription $a | jq -rj '.[] | "az functionapp config appsettings list --name ", .name, " --resource-group ", .resourceGroup, .name,"\n"' >> all_function_config_statements.sh; done
Blob Public Access
Query Storage Accounts for Blob Public Access
az storage account list | jq -r '.[] | "Name: " + .name + " | Public Access: " + (.allowBlobPublicAccess|tostring)'
Classic Resources
Generate List of Classic Resources
az resource list | jq -r '.[].id' | grep -i classic | grep -v Tutorial > all_classic_resources.txt
Runbooks
Extract all the Runbooks for all the Automation Accounts for all the Resource Groups
Get-AzAutomationAccount|foreach{Get-AzAutomationRunbook $_.ResourceGroupName $_.AutomationAccountName|foreach{Export-AzAutomationRunbook $_.ResourceGroupName $_.AutomationAccountName $_.Name}}
Web Applications
Extract Hostnames from Websites and Website Slots
az graph query -q "resources | where type == 'microsoft.web/sites' or type == 'microsoft.web/sites/slots' | extend resourceProperties = parse_json(properties) | extend defaultHostName = tostring(resourceProperties.defaultHostName) | project defaultHostName" | jq -r '.data | .[].defaultHostName' >> all_webapp_urls.txt
Managed Identities
Extract managed identities being used by virtual machines
(az vm list | ConvertFrom-Json) | ForEach-Object {$_.name;(az vm identity show --resource-group $_.resourceGroup --name $_.name | ConvertFrom-Json)}
Deployment Parameters
Extracting sensitive data from parameters
Get-AzResourceGroup |Get-AzResourceGroupDeployment >> deployments.txt
RunBook to Extract Managed Identity SP JWT
$tokenAuthURI = $env:MSI_ENDPOINT + “?resource=https://graph.microsoft.com/&api-version=2017-09-01"$tokenResponse = Invoke-RestMethod -Method Get -Headers @{“Secret”=”$env:MSI_SECRET”} -Uri $tokenAuthURI$tokenResponse.access_token
RunBook to Extract Run As SP JWT
$connectionName = “AzureRunAsConnection”
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName$TenantId = $servicePrincipalConnection.TenantId
$ClientId = $servicePrincipalConnection.ApplicationId
$CertificateThumbprint = $servicePrincipalConnection.CertificateThumbprintfunction GenerateJWT (){
$thumbprint = $CertificateThumbprint $cert = Get-Item Cert:\CurrentUser\My\$Thumbprint $hash = $cert.GetCertHash()
$hashValue = [System.Convert]::ToBase64String($hash) -replace ‘\+’,’-’ -replace ‘/’,’_’ -replace ‘=’ $exp = ([DateTimeOffset](Get-Date).AddHours(1).ToUniversalTime()).ToUnixTimeSeconds()
$nbf = ([DateTimeOffset](Get-Date).ToUniversalTime()).ToUnixTimeSeconds() $jti = New-Guid
[hashtable]$header = @{alg = “RS256”; typ = “JWT”; x5t=$hashValue}
[hashtable]$payload = @{aud = “https://login.microsoftonline.com/$TenantId/oauth2/token"; iss = “$ClientId”; sub=”$ClientId”; jti = “$jti”; exp = $Exp; Nbf= $Nbf}
$headerjson = $header | ConvertTo-Json -Compress
$payloadjson = $payload | ConvertTo-Json -Compress $headerjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($headerjson)).Split(‘=’)[0].Replace(‘+’, ‘-’).Replace(‘/’, ‘_’)
$payloadjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($payloadjson)).Split(‘=’)[0].Replace(‘+’, ‘-’).Replace(‘/’, ‘_’) $toSign = [System.Text.Encoding]::UTF8.GetBytes($headerjsonbase64 + “.” + $payloadjsonbase64) $rsa = $cert.PrivateKey -as [System.Security.Cryptography.RSACryptoServiceProvider] $signature = [Convert]::ToBase64String($rsa.SignData($toSign,[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)) -replace ‘\+’,’-’ -replace ‘/’,’_’ -replace ‘=’ $token = “$headerjsonbase64.$payloadjsonbase64.$signature” return $token
}$reqToken = GenerateJWT$Body = @{
scope = “https://graph.microsoft.com/.default"
client_id = $ClientId
client_assertion_type = “urn:ietf:params:oauth:client-assertion-type:jwt-bearer”
client_assertion = $reqToken
grant_type = “client_credentials” `
}$MGToken = Invoke-RestMethod `
-URI “https://login.microsoftonline.com/$($TenantId)/oauth2/v2.0/token" `
-Body $Body `
-Method POST
$MGToken.access_token
DevOps
Retrive Projects for Organization
Useful for most of the DevOps commands.
az devops project list --organization https://dev.azure.com/ORGANIZATION_NAME | jq -r '.value[].name'
Retrieve Projects and their Releases
Search release scripts for plaintext passwords, keys, and tokens
$orgUrl = 'https://dev.azure.com/ORGANIZATION_NAME'
az devops project list --organization $orgUrl | jq -r '.value[].name' | ForEach-Object { az pipelines release list --organization $orgUrl --project $_ | jq -r '.[].url' }