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
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:
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
The attacker creates a malicious YAML task file
The task authenticates to the Az CLI as the Managed Identity, then generates a token
A Task is created with the AZ CLI and the YAML file
The Task is run in the ACR Task container
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:
Authenticate to the AZ CLI (AZ Login) with an account with the Contributor role on the ACR
Identify the available Container Registries with the following command:
az acr list
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
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
Create the task in the ACR ($ACRName) with the following command
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
Use the following command to run the command in the ACR
az acr task run -n sample_acr_task -r $acrName
The task output, including the token, should be displayed in the output for the run command.
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.
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.
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
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:
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.
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.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
Name
Domain
Purpose
Expiry
Type
YSC
youtube.com
YouTube session cookie.
52 years
HTTP
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Name
Domain
Purpose
Expiry
Type
VISITOR_INFO1_LIVE
youtube.com
YouTube cookie.
6 months
HTTP
Test
test.com
Testing
7 days
HTTP
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
We do not use cookies of this type.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
We do not use cookies of this type.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
We do not use cookies of this type.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.
Cookie Settings
Discover how the NetSPI BAS solution helps organizations validate the efficacy of existing security controls and understand their Security Posture and Readiness.