Back

Pivoting with Azure Automation Account Connections

Intro 

Azure Automation Accounts are a frequent topic on the NetSPI technical blog. To the point that we compiled our research into a presentation for the DEFCON 30 cloud village and the Azure Cloud Security Meetup Group. We’re always trying to find new ways to leverage Automation Accounts during cloud penetration testing. To automate enumerating our privilege escalation options, we looked at how Automation Accounts handle authenticating as other accounts within a runbook, and how we can abuse those authentication connections to pivot to other Azure resources.

Passing the Identity in Azure Active Directory 

As a primer, an Azure Active Directory (AAD) identity (User, App Registration, or Managed Identity) can have a role (Contributor) on an Automation Account that allows them to modify the account. The Automation Account can have attached identities that allow the account to authenticate to Azure AD as those identities. Once authenticated as the identity, the Automation Account runbook code will then run any Azure commands in the context of the identity. If that Identity has additional (or different) permissions from those of the AAD user that is writing the runbook, the AAD user can abuse those permissions to escalate or move laterally.

Simply put, Contributor on the Automation Account allows an attacker to be any identity attached to the Automation Account. These attached identities can have additional privileges, leading to a privilege escalation for the original Contributor account. 

Available Identities for Azure Automation Accounts 

There are two types of identities available for Automation Accounts: Run As Accounts and Managed Identities. The Run As Accounts will be deprecated on September 30, 2023, but they have been a source of several issues since they were introduced. When initially created, a Run As Account will be granted the Contributor role on the subscription it is created in.  

These accounts are also App Registrations in Azure Active Directory that use certificates for authentication. These certificates can be extracted from Automation Accounts with a runbook and used for gaining access to the Run As Account. This is also helpful for persistence, as App Registrations typically don’t have conditional access restrictions applied. 

For more on Azure Privilege Escalation using Managed Identities, check out this blog.

Screenshot of the Run As account type, one of two identities available for Azure Automation Accounts.

Managed Identities are the currently recommended option for using an execution identity in Automation Account runbooks. Managed Identities can either be system-assigned or user-assigned. System-assigned identities are tied to the resource that they are created for and cannot be shared between resources. User-assigned Managed Identities are a subscription level resource that can be shared across resources, which is handy for situations where resources, like multiple App Services applications, require shared access to a specific resource (Storage Account, Key Vault, etc.). Managed Identities are a more secure option for Automation Account Identities, as their access is temporary and must be generated from the attached resource.

A description of a system-assigned identity in Azure Automation Account.

Since Automation Accounts are frequently used to automate actions in multiple subscriptions, they are often granted roles in other subscriptions, or on higher level management groups. As attackers, we like to look for resources in Azure that can allow for pivoting to other parts of an Azure tenant. To help in automating this enumeration of the identity privileges, we put together a PowerShell script. 

Automating Privilege Enumeration 

The Get-AzAutomationConnectionScope function in MicroBurst is a relatively simple PowerShell script that uses the following logic:

  • Get a list of available subscriptions 
    • For each selected subscription 
      • Get a list of available connections (Run As or Managed Identity) 
      • Build the Automation Account runbook to authenticate as the connection, and list available subscriptions and available Key Vaults 
      • Upload and run the runbook 
      • Retrieve the output and return it
      • Delete the runbook 

In general, we are going to create a “malicious” automation runbook that goes through all the available identities in the Automation Account to tell us the available subscriptions and Key Vaults. Since the Key Vaults utilize a secondary access control mechanism (Access Policies), the script will also review the policies for each available Key Vault and report back any that have entries for our current identity. While a Contributor on a Key Vault can change these Access Policies, it is helpful to know which identities already have Key Vault access. 

The usage of the script is simple. Just authenticate to the Az PowerShell module (Connect-AzAccount) as a Contributor on an Automation Account and run “Get-AzAutomationConnectionScope”. The verbose flag is very helpful here, as runbooks can take a while to run, and the verbose status update is nice.

PowerShell script for automating the enumeration of identity privileges.

Note that this will also work for cross-tenant Run As connections. As a proof of concept, we created a Run As account in another tenant (see “Automation Account Connection – dso” above), uploaded the certificate and authentication information (Application ID and Tenant) to our Automation Account, and the connection was usable with this script. This can be a convenient way to pivot to other tenants that your Automation Account is responsible for. That said, it’s rare for us to see a cross-tenant connection like that.

As a final note on the script, the “Classic Run As” connections in an older Automation Account will not work with this script. They may show up in your output, but they require additional authentication logic in the runbook, and given the low likelihood of their usage, we’ve opted to avoid adding the logic in for those connections. 

Indicators of Compromise 

To help out the Azure defenders, here is a rough outline on how this script would look in a subscription/tenant from an incident response perspective: 

  1. Initial Account Authentication 
    a.   User/App Registration authenticates via the Az PowerShell cmdlets 
  1. Subscriptions / Automation Accounts Enumerated 
    a.   The script has you select an available subscription to test, then lists the available Automation Accounts to select from 
  1. Malicious Runbook draft is created in the Automation Account
    a.   Microsoft.Automation/automationAccounts/runbooks/write
    b.   Microsoft.Automation/automationAccounts/runbooks/draft/write 
  1. Malicious Runbook is published to the Automation Account
    a.   Microsoft.Automation/automationAccounts/runbooks/publish/action 
  1. Malicious Runbook is executed as a job
    a.   Microsoft.Automation/automationAccounts/jobs/write 
  1. Run As connections and/or Managed Identities should show up as authentication events 
  1. Malicious Runbook is deleted from the Automation Account
    a.   Microsoft.Automation/automationAccounts/runbooks/delete 

Providing the full rundown is a little beyond the scope of this blog, but Lina Lau (@inversecos) has a great blog on detections for Automation Accounts that covers a persistence technique I previously outlined in a previous article titled, Maintaining Azure Persistence via Automation Accounts. Lina’s blog should also cover most of the steps that we have outlined above. 

For additional detail on Automation Account attack paths, take a look at Andy Robbins’ blog, Managed Identity Attack Paths, Part 1: Automation Accounts

Conclusion 

While Automation Account identities are often a necessity for automating actions in an Azure tenant, they can allow a user (with the correct role) to abuse the identity permissions to escalate and/or pivot to other subscriptions.

The function outlined in this blog should be helpful for enumerating potential pivot points from an existing Automation Account where you have Contributor access. From here, you could create custom runbooks to extract credentials, or pivot to Virtual Machines that your identity has access to. Alternatively, defenders can use this script to see the potential blast radius of a compromised Automation Account in their subscriptions. 

Ready to improve your Azure security? Explore NetSPI’s Azure Cloud Penetration Testing solutions. Or checkout these blog posts for more in-depth research on Azure Automation Accounts:  

Discover how the NetSPI BAS solution helps organizations validate the efficacy of existing security controls and understand their Security Posture and Readiness.

X