# Az - Container Registry

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

## Informazioni di base

Azure Container Registry (ACR) è un registro privato e sicuro che consente di **memorizzare, gestire e accedere alle immagini dei container nel cloud Azure**. Si integra perfettamente con diversi servizi Azure, fornendo flussi di lavoro automatizzati per la creazione e il deployment su larga scala. Con funzionalità come la geo-replicazione e la scansione delle vulnerabilità, ACR aiuta a garantire sicurezza e conformità di livello enterprise per le applicazioni containerizzate.

### 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 concessi su un Container Registry:

- Access Resource Manager
- Create/delete registry
- Push image
- Pull image
- Delete image data
- Change policies
- Sign images

Ci sono anche alcuni **ruoli predefiniti** che possono essere assegnati, ed è anche possibile creare **ruoli personalizzati**.

![](/images/registry_roles.png)

### Autenticazione

> [!WARNING]
> È molto importante che anche se il nome del registro contiene alcune lettere maiuscole, dovresti sempre usare **lettere minuscole** per accedere, caricare e scaricare immagini.

Ci sono 4 modi per autenticarsi a un ACR:

- **Con Entra ID**: Questo è il **metodo predefinito** per autenticarsi a un ACR. Utilizza il comando **`az acr login`** per autenticarsi all'ACR. Questo comando **memorizzerà le credenziali** nel file **`~/.docker/config.json`**. Inoltre, se stai eseguendo questo comando da un ambiente senza accesso a un socket docker come in una **cloud shell**, è possibile utilizzare 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` come: `docker login myregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin <<< $TOKEN`
- **Con un account admin**: L'utente admin è disabilitato per impostazione predefinita, ma può essere abilitato e poi sarà possibile accedere al registro con il **nome utente** e la **password** dell'account admin con pieni permessi sul registro. Questo è ancora supportato perché alcuni servizi Azure lo utilizzano. Nota che **2 password** vengono create per questo utente e entrambe sono valide. Puoi abilitarlo con `az acr update -n <acrName> --admin-enabled true`. Nota che il nome utente è solitamente il nome del registro (e non `admin`).
- **Con un token**: È possibile creare un **token** con una **specifica `scope map`** (permessi) per accedere al registro. Poi, è possibile utilizzare il nome del token come nome utente e una delle password generate per autenticarsi al registro 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 scaricare immagini. Poi, sarà possibile **accedere al registro** utilizzando l'appId SP come nome utente e un segreto generato come password.

Esempio di script dalla [documentazione](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal) per generare un SP con accesso su un registro:
```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"
```
### Crittografia

Solo il **Premium SKU** supporta la **crittografia a riposo** per le immagini e altri artefatti.

### Rete

Solo il **Premium SKU** supporta i **punti finali privati**. Gli altri supportano solo l'**accesso pubblico**. Un punto finale pubblico ha il formato `<registry-name>.azurecr.io` e un punto finale privato ha il formato `<registry-name>.privatelink.azurecr.io`. Per questo motivo, il nome del registro deve essere unico in tutto Azure.

### Microsoft Defender for Cloud

Questo ti consente di **scansionare le immagini** nel registro per **vulnerabilità**.

### Soft-delete

La funzione di **soft-delete** ti consente di **recuperare un registro eliminato** entro il numero di giorni indicato. Questa funzione è **disabilitata per impostazione predefinita**.

### Webhook

È possibile **creare webhook** all'interno dei registri. In questo webhook è necessario specificare l'URL dove una **richiesta sarà inviata ogni volta che viene eseguita un'azione di push o delete**. Inoltre, i Webhook possono indicare un ambito per indicare i repository (immagini) che saranno interessati. Ad esempio, 'foo:\*' significa eventi sotto il repository 'foo'.

Dal punto di vista di un attaccante, è interessante controllare questo **prima di eseguire qualsiasi azione** nel registro e rimuoverlo temporaneamente se necessario, per evitare di essere rilevati.

### Registri connessi

Questo consente fondamentalmente di **rispecchiare le immagini** da un registro a un altro, solitamente situato on-premises.

Ha 2 modalità: **ReadOnly** e **ReadWrite**. Nella prima, le immagini vengono solo **scaricate** dal registro sorgente, e nella seconda, le immagini possono anche essere **caricate** nel registro sorgente.

Affinché i client possano accedere al registro da Azure, viene generato un **token** quando viene utilizzato il registro connesso.

### Esecuzioni e Attività

Esecuzioni e Attività consentono di eseguire in Azure azioni relative ai container che normalmente avresti dovuto fare localmente o in una pipeline CI/CD. Ad esempio, puoi **costruire, caricare ed eseguire immagini nel registro**.

Il modo più semplice per costruire ed eseguire un container è utilizzare un'esecuzione regolare:
```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
```
Tuttavia, ciò attiverà esecuzioni che non sono molto interessanti dal punto di vista di un attaccante poiché non hanno alcuna identità gestita ad esse associata.

Tuttavia, **tasks** possono avere un'**identità gestita di sistema e utente** ad esse associata. Queste attività sono quelle utili per **escalare privilegi** nel contenitore. Nella sezione sull'escalation dei privilegi è possibile vedere come utilizzare le attività per escalare privilegi.

### Cache

La funzione di cache consente di **scaricare immagini da un repository esterno** e memorizzare le nuove versioni nel registro. Richiede di avere alcune **credenziali configurate** selezionando le credenziali da un Azure Vault.

Questo è molto interessante dal punto di vista di un attaccante perché consente di **pivotare su una piattaforma esterna** se l'attaccante ha abbastanza permessi per accedere alle credenziali, **scaricare immagini da un repository esterno** e configurare una cache potrebbe anche essere utilizzato come **meccanismo di persistenza**.

## Enumeration

> [!WARNING]
> È molto importante che anche se il nome del registro contiene alcune lettere maiuscole, dovresti utilizzare solo lettere minuscole nell'url per accedervi.
```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>
```
## Accesso non autenticato

{{#ref}}
../az-unauthenticated-enum-and-initial-entry/az-container-registry-unauth.md
{{#endref}}

## Escalation dei privilegi e Post Exploitation

{{#ref}}
../az-privilege-escalation/az-container-registry-privesc.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)

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