# Az - Container Registry

{{#include ../../../banners/hacktricks-training.md}}

## Informations de base

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, offrant des workflows de construction et de déploiement automatisés à grande échelle. Avec des fonctionnalités telles que la géo-réplication et l'analyse de vulnérabilités, ACR aide à garantir la sécurité et la conformité de niveau entreprise pour les applications conteneurisées.

### Permissions

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 :

- Accéder au Resource Manager
- Créer/supprimer un registre
- Pousser une image
- Tirer une image
- Supprimer des données d'image
- Modifier des politiques
- Signer des images

Il existe également des **rôles intégrés** qui peuvent être attribués, et il est également possible de créer des **rôles personnalisés**.

![](/images/registry_roles.png)

### Authentification

> [!WARNING]
> Il est très important que même si le nom du registre contient des lettres majuscules, vous devez toujours utiliser des **lettres minuscules** pour vous connecter, pousser et tirer des images.

Il existe 4 façons de s'authentifier à un ACR :

- **Avec Entra ID** : C'est la **méthode par défaut** pour s'authentifier à un ACR. Elle utilise la commande **`az acr login`** pour s'authentifier à 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 drapeau **`--expose-token`** pour obtenir le **token** pour s'authentifier à l'ACR. Ensuite, pour s'authentifier, vous devez utiliser comme nom d'utilisateur `00000000-0000-0000-0000-000000000000` comme : `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é et ensuite il sera possible d'accéder au registre avec le **nom d'utilisateur** et le **mot de passe** du compte administrateur avec des permissions complètes sur le registre. Cela est toujours pris en charge car certains services Azure l'utilisent. Notez que **2 mots de passe** sont créés pour cet utilisateur et les deux sont valides. Vous pouvez l'activer avec `az acr update -n <acrName> --admin-enabled true`. Notez que le nom d'utilisateur est généralement le nom du registre (et non `admin`).
- **Avec un token** : Il est possible de créer un **token** avec une **`scope map`** (permissions) spécifique pour accéder au registre. Ensuite, il est possible d'utiliser ce nom de token comme nom d'utilisateur et certains des mots de passe générés pour s'authentifier au registre avec `docker login -u <registry-name> -p <password> aregistry-url>`
- **Avec un Service Principal** : Il est possible de créer un **service principal** et d'attribuer un rôle comme **`AcrPull`** pour tirer des images. Ensuite, il sera 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 provenant de la [documentation](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) pour générer un SP avec accès à un registre :
```bash
#!/bin/bash
ACR_NAME=$containerRegistry
SERVICE_PRINCIPAL_NAME=$servicePrincipal

# Obtain the full registry ID
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query "id" --output tsv)

PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)

echo "Service principal ID: $USER_NAME"
echo "Service principal password: $PASSWORD"
```
### Chiffrement

Seul le **Premium SKU** prend en charge le **chiffrement au repos** pour les images et autres artefacts.

### Réseautage

Seul le **Premium SKU** prend en charge les **points de terminaison privés**. Les autres ne prennent en charge que l'**accès public**. Un point de terminaison public a le format `<registry-name>.azurecr.io` et un point de terminaison privé a le format `<registry-name>.privatelink.azurecr.io`. Pour cette raison, le nom du registre doit être unique dans tout Azure.

### Microsoft Defender for Cloud

Cela vous permet de **scanner les images** dans le registre pour des **vulnérabilités**.

### Suppression douce

La fonctionnalité de **suppression douce** vous permet de **récupérer un registre 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** à l'intérieur des registres. Dans ce webhook, il est nécessaire de spécifier l'URL où une **demande sera envoyée chaque fois qu'une action de push ou de suppression est effectuée**. De plus, les Webhooks peuvent indiquer un scope pour indiquer les dépôts (images) qui seront affectés. Par exemple, 'foo:\*' signifie des événements sous le dépôt 'foo'.

Du point de vue d'un attaquant, il est intéressant de vérifier cela **avant d'effectuer toute action** dans le registre, et de le supprimer temporairement si nécessaire, pour éviter d'être détecté.

### Registres connectés

Cela permet essentiellement de **miroiter les images** d'un registre à un autre, généralement situé sur site.

Il a 2 modes : **ReadOnly** et **ReadWrite**. Dans le premier, les images sont uniquement **tirées** du registre source, et dans le second, les images peuvent également être **poussées** vers le registre source.

Pour que les clients accèdent au registre depuis Azure, un **jeton** est généré lorsque le registre connecté est utilisé.

### Exécutions & Tâches

Les Exécutions & Tâches permettent d'exécuter dans Azure des actions liées aux conteneurs que vous deviez généralement effectuer localement ou dans un pipeline CI/CD. Par exemple, vous pouvez **construire, pousser et exécuter des images dans le registre**.

Le moyen le plus simple de construire et d'exécuter un conteneur est d'utiliser une Exécution régulière :
```bash
# Build
echo "FROM mcr.microsoft.com/hello-world" > Dockerfile
az acr build --image sample/hello-world:v1 --registry mycontainerregistry008 --file Dockerfile .

# Run
az acr run --registry mycontainerregistry008 --cmd '$Registry/sample/hello-world:v1' /dev/null
```
Cependant, cela déclenchera des exécutions qui ne sont pas très intéressantes du point de vue d'un attaquant car elles n'ont pas d'identité gérée qui leur est attachée.

Cependant, **tasks** peuvent avoir une **identité gérée système et utilisateur** qui leur est attachée. Ces tâches sont celles utiles pour **escalader les privilèges** dans le conteneur. Dans la section sur l'escalade des privilèges, il est possible de voir comment utiliser les tâches pour escalader les privilèges.

### Cache

La fonctionnalité de cache permet de **télécharger des images depuis un dépôt externe** et de stocker les nouvelles versions dans le registre. Cela nécessite d'avoir des **identifiants configurés** en sélectionnant les identifiants d'un Azure Vault.

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 a suffisamment de permissions pour accéder aux identifiants, **télécharger des images depuis un dépôt externe** et configurer un cache pourrait également être utilisé comme **mécanisme de persistance**.

## Enumeration

> [!WARNING]
> Il est très important que même si le nom du registre contient des lettres majuscules, vous ne devez utiliser que des lettres minuscules dans l'URL pour y accéder.
```bash
# List of all the registries
# Check the network, managed identities, adminUserEnabled, softDeletePolicy, url...
az acr list

# Get the details of a registry
az acr show --name <registry-name>

# List tokens of a registry
az acr token list --registry <registry-name> --resource-group <res-group>

# List repositories in a registry
az acr repository list --name <registry-name> --resource-group <res-group>

# List the tags of a repository
az acr repository show-tags --repository <repository-name> --name <registry-name> --resource-group <res-group>

# List deleted repository tags
## At the time of this writing there isn't yet any command to restore it
az acr repository list-deleted --name <registry-name>

# List tasks
## Check the git URL or the command
az acr task list --registry <registry-name>

# List tasks runs
az acr task list-runs --registry <registry-name>

# List connected registries
az acr connected-registry list --registry <registry-name>

# List cache
az acr cache list --registry <registry-name>

# Get cache details
az acr cache show --name <cache-name> --registry <registry-name>
```
## Escalade de privilèges & Post-exploitation

{{#ref}}
../az-privilege-escalation/az-automation-accounts-privesc.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)
- [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)

{{#include ../../../banners/hacktricks-training.md}}
