top of page
Search

Deployment Scripts, Managed Identities, and When Good Features Go Bad

  • Writer: infiniteloop
    infiniteloop
  • Dec 19, 2024
  • 6 min read

Updated: Mar 9

A while back, I was messing around and testing things out in my own Azure tenant. During one of these sessions, I stumbled upon a pretty interesting lead. After a bit of searching, I came across a blog post by Karl Fosaaen, someone I’ve always considered a mentor (thanks for all the chats, brilliant ideas, and your endless generosity in sharing knowledge). His post connected the dots for me and sparked an idea: what if this could be pushed even further?

I pinged him to pick his brain. Turns out, he’d been working on this for a while and was kind enough to share some of the ideas and attack vectors he’d come up with. Our back-and-forth conversations helped me refine my approach as I tinkered away, trying to get it all to actually work. In the end, I even got a little credit, thanks again for everything, Karl! I've learned a lot from it, Much appreciated.


In addition to Karl's blogpost, I've also come across Rogier Dijkman's research blog post on the subject, huge props on the amazing research and tool. With Karl and Rogier's findings and a bit of my own experimentation, this post takes a closer look at Managed Identities, Deployment Scripts, and how it can be used to escalate privileges in Azure. Whether you’re curious about how these features work or you’re looking for creative ways to break your Azure environment (responsibly, of course), I hope you'll find something to chew on here.


Now, let’s dig into Azure managed identities, specifically, user-assigned managed identities (UAMIs). We’ll explore what they are, how they work, and how they can be leveraged for privilege escalation in Azure environments.


What's Actually Happening Behind the Scenes

Before we jump into the attack path, you need to understand what's happening under the hood. When you create a Deployment Script in Azure, you're actually getting:

  • A containerized Azure environment

  • A supporting storage account (look for "*azscripts")

  • Container Instance resources linked to your script

This is more than just a simple script execution, it's a full environment you can leverage.


Managed Identities 101

Managed identities in Azure let you authenticate to other services without worrying about passwords, keys, or other secrets. They come in two types: System-assigned managed identities and User-assigned managed identities (UAMIs).

Here's how they differ:

Property

System-assigned managed identity

User-assigned managed identity

Creation

Created as part of an Azure resource (for example, Azure Virtual Machines or Azure App Service).

Created as a stand-alone Azure resource.

Life cycle

Shared life cycle with the Azure resource that the managed identity is created with.


When the parent resource is deleted, the managed identity is deleted as well.

Independent life cycle.


Must be explicitly deleted.

Sharing across Azure resources

Can’t be shared.


It can only be associated with a single Azure resource.

Can be shared.


The same user-assigned managed identity can be associated with more than one Azure resource.

Common use cases

Workloads contained within a single Azure resource.


Workloads needing independent identities.


For example, an application that runs on a single virtual machine.

Workloads that run on multiple resources and can share a single identity.


Workloads needing preauthorization to a secure resource, as part of a provisioning flow.


Workloads where resources are recycled frequently, but permissions should stay consistent.


For example, a workload where multiple virtual machines need to access the same resource.

Quick recap:

  • System-assigned Managed Identity: This is like a disposable coffee cup handed out at a café. It’s created specifically for one customer (resource) and thrown away when the coffee is finished (the resource is deleted). It’s simple, single-use, and tied directly to that one order.

  • User-assigned Managed Identity: This is like a reusable travel mug. It’s not tied to any one café (resource) and can be used across multiple locations. It sticks around until you decide to retire it, making it perfect for situations where consistent and flexible access is needed.


Where Can MIs Be Attached?

UAMIs can be attached to various Azure resources, including:

  • Virtual Machines

  • Azure Container Registries (ACR)

  • Automation Accounts

  • App Services (like Function Apps)

  • Azure Kubernetes Service (AKS)

  • Data Factory

  • Logic Apps

  • Deployment Scripts

The Technical Stuff You Need to Know

Here's what makes this interesting, Deployment Scripts in Azure let you execute PowerShell, CLI, or Bash commands in a containerized environment. When you combine this with a UAMI that has elevated permissions, you've got a potential privilege escalation path.

A few technical points to keep in mind:

  • MIs can have permissions across multiple subscriptions

  • You might not see all assigned roles due to permission limitations

  • Quick way to check available roles: Get-AzUserAssignedIdentity | ForEach-Object { Get-AzRoleAssignment -ObjectId $_.PrincipalId }


How an Attacker Sees This

Let's put on our adversarial hats for a minute:

Recon

  • Search for Resource Groups where you have User Access Administrator/Owner permissions (Shamelessly plugging RoleCrawl - you can read more about it here, TLDR; it's a PowerShell tool I have created that helps enumerate Azure role assignments, perfect for understanding what permissions your user/compromised MI actually has.)

  • Within those RGs, look for resources that have MIs attached

  • Check what permissions these MIs have, often they'll have high-privileged roles like Owner or Contributor

  • Focus on finding MIs with permissions beyond their RG, especially subscription-level access

Access the MI

  • Once you find a high-privileged MI, deploy a script to get its token

  • That token inherits ALL the MI's permissions, for example: if the MI has Owner rights on a subscription, your token will too

Privilege Escalation

Use the MI's token to access resources you normally couldn't!

Example: MI has Owner on subscription A, but you only had User Access Admin on a single RG.

  • By getting the MI's token, you've escalated from RG-level access to subscription Owner

  • Common scenario: Developers give MIs Owner rights for "ease of use", this becomes your path to higher privileges


The Attack Chain:

Let's break down how an attacker could leverage this:

  1. Initial Access

    • You have Owner or User Access Administrator over a Resource Group

    • There's a resource in that RG with a high-privileged UAMI attached

  2. Preparation

    • Use User Access Administrator (for example) to give yourself "Owner" permission on the RG

    • This grants you the Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/action permission

  3. Execution

    • Deploy an ARM template with a Deployment Script

    • Attach the high-privileged UAMI

    • Get its token

    • Use the token to authenticate


There's actually more you can do, in addition you can also:

  • Run commands directly on VMs

  • Create new role assignments

  • Access Key Vaults and Storage accounts

  • Execute external PowerShell code


A quick note about token scopes: while we used management.azure.com in our example, you can request tokens for different resources:

- graph.microsoft.com for Graph API access

- vault.azure.net for Key Vault operations

- storage.azure.com for Storage access

Just modify the Get-AzAccessToken command with -ResourceUrl for the scope you need.


You can execute this attack manually through the Azure Portal or CLI, but for simplicity and/or in the case you have no access to the Azure portal, I've created a PowerShell script that automates the entire process and handles the cleanup (You can either run it interactively, or in the case you use a C2, you can just run with all the flags without any further interaction required). Link to the DeployMI Github Repository


Azure Portal

Deploying a custom ARM template
Deploying a custom ARM template
Using the "Get-AzAccessToken" cmdlet via the ARM template to get the MI's token
Using the "Get-AzAccessToken" cmdlet via the ARM template to get the MI's token
ARM Template successfully deployed
ARM Template successfully deployed
MI's token returned after successful deployment
MI's token returned after successful deployment

Azure CLI

Enumerating our user with Contributor and UAD Privileges over the Resource Group the MI is a part of
Enumerating our user with Contributor and UAD Privileges over the Resource Group the MI is a part of
Automating the ARM template deployment using our PowerShell script
Automating the ARM template deployment using our PowerShell script
Successfully connecting to the MI with the token previously received
Successfully connecting to the MI with the token previously received
Enumerating the MI's permissions using RoleCrawl
Enumerating the MI's permissions using RoleCrawl

All things Blue

If this attack path has your attention (as it should), let's see how it can be mitigated.

Start with the basics: lock down your MI permissions to absolute minimums and regularly audit who has access to what. Remember, deployment scripts are just tools; it's misconfigured permissions and overprivileged MIs that create the attack paths.


To effectively detect this privilege escalation attack, you could monitor both specific Resource Provider Operations and common attack patterns. Here's what to look for:


IoCs

Resource Provider Operations

  1. Identity and Role Operations

    • Microsoft.ManagedIdentity/userAssignedIdentities/assign/action

    • Microsoft.Authorization/roleAssignments/write

    • Microsoft.ManagedIdentity/identities/getToken/action

  2. Deployment Operations

    • Microsoft.Resources/deployments/validate/action

    • Microsoft.Resources/deployments/write

    • Microsoft.Resources/deploymentScripts/write

  3. Resource Operations

    • Microsoft.Storage/storageAccounts/write

    • Microsoft.Storage/storageAccounts/listKeys/action

    • Microsoft.ContainerInstance/containerGroups/write

    • Microsoft.Resources/deploymentScripts/logs/read

    • Microsoft.Resources/deploymentScripts/outputs/read

  4. Cleanup Operations

    • Microsoft.Resources/deploymentScripts/delete

    • Microsoft.Resources/deployments/delete


Suspicious Patterns

In addition to monitoring Resource Provider Operations, watch for these common attack patterns that might indicate privilege escalation attempts:

  • MI role assignments outside business hours

  • Deployment scripts in unexpected resource groups

  • Short-lived deployment scripts (quick create-use-delete pattern)

  • Cross-subscription activities after MI token acquisition

  • Multiple deployment scripts created/deleted rapidly

  • New role assignments following deployment script execution



For Azure Sentinel users, here's a few KQL queries to detect rapid deployment script creation/deletion, Monitor for MI token acquisition followed by role assignments, and Monitor for cross-subscription activity:


AzureActivity
| where OperationName in ("Microsoft.Resources/deploymentScripts/write", "Microsoft.Resources/deploymentScripts/delete")
| summarize Count = count() by bin(TimeGenerated, 1h), ResourceGroup, Caller
| where Count > 3
 AzureActivity
| where TimeGenerated > ago(1h)
| where OperationName in ("Microsoft.ManagedIdentity/identities/getToken/action", "Microsoft.Authorization/roleAssignments/write")
| order by TimeGenerated asc
| summarize Operations=make_list(OperationName), Times=make_list(TimeGenerated) by Caller, ResourceGroup
AzureActivity
| where TimeGenerated > ago(1h)
| where OperationName == "Microsoft.ManagedIdentity/identities/getToken/action"
| join kind=inner (
    AzureActivity
    | where TimeGenerated > ago(1h)
    | where OperationName has "write"
) on Caller
| where ResourceGroup != "ResourceGroup1"


Credits & References:


 
 
 

Recent Posts

See All
Cloudy With a Chance of Backdoors

Introduction You know the saying, "Keep your friends close, and your enemies closer." The same principle applies here. Collaboration with...

 
 
 
RoleCrawl

RoleCrawl is a PowerShell tool I designed to audit User and Group role assignments in Azure, covering both subscription and resource...

 
 
 

Komentar


bottom of page