# Az - Storage Accounts & Blobs

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

## Informazioni di base

Gli Azure Storage Accounts sono servizi fondamentali in Microsoft Azure che forniscono **storage cloud scalabile, sicuro e altamente disponibile per vari tipi di dati**, inclusi blob (oggetti binari di grandi dimensioni), file, code e tabelle. Servono come contenitori che raggruppano questi diversi servizi di storage sotto un unico namespace per una gestione facile.

**Opzioni di configurazione principali**:

- Ogni storage account deve avere un **nome unico in tutti gli Azure**.
- Ogni storage account è distribuito in una **regione** o in una zona estesa di Azure.
- È possibile selezionare la versione **premium** dello storage account per migliori prestazioni.
- È possibile scegliere tra **4 tipi di ridondanza per proteggere** contro guasti di rack, disco e datacenter.

**Opzioni di configurazione della sicurezza**:

- **Richiedere trasferimento sicuro per le operazioni API REST**: Richiedere TLS in qualsiasi comunicazione con lo storage.
- **Consente di abilitare l'accesso anonimo su contenitori individuali**: In caso contrario, non sarà possibile abilitare l'accesso anonimo in futuro.
- **Abilitare l'accesso con chiave dello storage account**: In caso contrario, l'accesso con chiavi condivise sarà vietato.
- **Versione minima TLS**.
- **Ambito consentito per le operazioni di copia**: Consenti da qualsiasi storage account, da qualsiasi storage account dello stesso tenant Entra o da storage account con endpoint privati nella stessa rete virtuale.

**Opzioni di Blob Storage**:

- **Consenti replicazione cross-tenant**.
- **Livello di accesso**: Hot (dati accessibili frequentemente), Cool e Cold (dati raramente accessibili).

**Opzioni di rete**:

- **Accesso di rete**:
- Consenti da tutte le reti.
- Consenti da reti virtuali e indirizzi IP selezionati.
- Disabilita l'accesso pubblico e utilizza l'accesso privato.
- **Endpoint privati**: Consente una connessione privata allo storage account da una rete virtuale.

**Opzioni di protezione dei dati**:

- **Ripristino point-in-time per contenitori**: Consente di ripristinare i contenitori a uno stato precedente.
- Richiede versioning, change feed e blob soft delete per essere abilitati.
- **Abilitare soft delete per i blob**: Abilita un periodo di retention in giorni per i blob eliminati (anche sovrascritti).
- **Abilitare soft delete per i contenitori**: Abilita un periodo di retention in giorni per i contenitori eliminati.
- **Abilitare soft delete per le condivisioni di file**: Abilita un periodo di retention in giorni per le condivisioni di file eliminate.
- **Abilitare versioning per i blob**: Mantieni le versioni precedenti dei tuoi blob.
- **Abilitare blob change feed**: Tieni traccia dei log di creazione, modifica ed eliminazione dei blob.
- **Abilitare il supporto per l'immutabilità a livello di versione**: Consente di impostare una politica di retention basata sul tempo a livello di account che si applicherà a tutte le versioni dei blob.
- Il supporto per l'immutabilità a livello di versione e il ripristino point-in-time per i contenitori non possono essere abilitati simultaneamente.

**Opzioni di configurazione della crittografia**:

- **Tipo di crittografia**: È possibile utilizzare chiavi gestite da Microsoft (MMK) o chiavi gestite dal cliente (CMK).
- **Abilitare la crittografia dell'infrastruttura**: Consente di crittografare i dati "per maggiore sicurezza".

### Endpoint di storage

<table data-header-hidden><thead><tr><th width="197">Servizio di storage</th><th>Endpoint</th></tr></thead><tbody><tr><td><strong>Blob storage</strong></td><td><code>https://<storage-account>.blob.core.windows.net</code><br><br><code>https://<stg-acc>.blob.core.windows.net/<container-name>?restype=container&comp=list</code></td></tr><tr><td><strong>Data Lake Storage</strong></td><td><code>https://<storage-account>.dfs.core.windows.net</code></td></tr><tr><td><strong>Azure Files</strong></td><td><code>https://<storage-account>.file.core.windows.net</code></td></tr><tr><td><strong>Queue storage</strong></td><td><code>https://<storage-account>.queue.core.windows.net</code></td></tr><tr><td><strong>Table storage</strong></td><td><code>https://<storage-account>.table.core.windows.net</code></td></tr></tbody></table>

### Esposizione pubblica

Se "Consenti accesso pubblico ai blob" è **abilitato** (disabilitato per impostazione predefinita), durante la creazione di un contenitore è possibile:

- Dare **accesso pubblico per leggere i blob** (è necessario conoscere il nome).
- **Elencare i blob del contenitore** e **leggerli**.
- Renderlo completamente **privato**.

<figure><img src="https://lh7-rt.googleusercontent.com/slidesz/AGV_vUfoetUnYBPWQpRrWNnnlbqWpl8Rdoaeg5uBrCVlvcNDlnKwQHjZe8nUb2SfPspBgbu-lCZLmUei-hFi_Jl2eKbaxUtBGTjdUSDmkrcwr90VZkmuMjk9tyh92p75btfyzGiUTa0-=s2048?key=m8TV59TrCFPlkiNnmhYx3aZt" alt=""><figcaption></figcaption></figure>

### Connettersi allo Storage

Se trovi qualche **storage** a cui puoi connetterti, puoi utilizzare lo strumento [**Microsoft Azure Storage Explorer**](https://azure.microsoft.com/es-es/products/storage/storage-explorer/) per farlo.

## Accesso allo Storage <a href="#about-blob-storage" id="about-blob-storage"></a>

### RBAC

È possibile utilizzare i principi di Entra ID con **ruoli RBAC** per accedere agli storage account ed è il modo raccomandato.

### Chiavi di accesso

Gli storage account hanno chiavi di accesso che possono essere utilizzate per accedervi. Questo fornisce **accesso completo allo storage account.**

<figure><img src="../../../images/image (5).png" alt=""><figcaption></figcaption></figure>

### **Chiavi condivise & Chiavi condivise Lite**

È possibile [**generare Chiavi Condivise**](https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key) firmate con le chiavi di accesso per autorizzare l'accesso a determinate risorse tramite un URL firmato.

> [!NOTE]
> Nota che la parte `CanonicalizedResource` rappresenta la risorsa dei servizi di storage (URI). E se qualche parte nell'URL è codificata, dovrebbe essere codificata anche all'interno del `CanonicalizedResource`.

> [!NOTE]
> Questo è **utilizzato per impostazione predefinita da `az` cli** per autenticare le richieste. Per farlo utilizzare le credenziali del principale Entra ID, indica il parametro `--auth-mode login`.

- È possibile generare una **chiave condivisa per i servizi blob, queue e file** firmando le seguenti informazioni:
```bash
StringToSign = VERB + "\n" +
Content-Encoding + "\n" +
Content-Language + "\n" +
Content-Length + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
If-Modified-Since + "\n" +
If-Match + "\n" +
If-None-Match + "\n" +
If-Unmodified-Since + "\n" +
Range + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
```
- È possibile generare una **chiave condivisa per i servizi di tabella** firmando le seguenti informazioni:
```bash
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
```
- È possibile generare una **lite shared key per i servizi blob, queue e file** firmando le seguenti informazioni:
```bash
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
```
- È possibile generare una **lite shared key for table services** firmando le seguenti informazioni:
```bash
StringToSign = Date + "\n"
CanonicalizedResource
```
Quindi, per utilizzare la chiave, può essere fatto nell'intestazione Authorization seguendo la sintassi:
```bash
Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"
#e.g.
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=

PUT http://myaccount/mycontainer?restype=container&timeout=30 HTTP/1.1
x-ms-version: 2014-02-14
x-ms-date: Fri, 26 Jun 2015 23:39:12 GMT
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=
Content-Length: 0
```
### **Shared Access Signature** (SAS)

Le Shared Access Signatures (SAS) sono URL sicuri e limitati nel tempo che **concedono permessi specifici per accedere a risorse** in un account di Azure Storage senza esporre le chiavi di accesso dell'account. Mentre le chiavi di accesso forniscono accesso amministrativo completo a tutte le risorse, la SAS consente un controllo granulare specificando i permessi (come lettura o scrittura) e definendo un tempo di scadenza.

#### Tipi di SAS

- **User delegation SAS**: Questa viene creata da un **Entra ID principal** che firmerà la SAS e delega i permessi dall'utente alla SAS. Può essere utilizzata solo con **blob e data lake storage** ([docs](https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas)). È possibile **revocare** tutte le SAS delegate generate dall'utente.
- Anche se è possibile generare una SAS di delega con "più" permessi di quelli che l'utente ha. Tuttavia, se il principal non li ha, non funzionerà (no privesc).
- **Service SAS**: Questa è firmata utilizzando una delle **chiavi di accesso** dell'account di storage. Può essere utilizzata per concedere accesso a risorse specifiche in un singolo servizio di storage. Se la chiave viene rinnovata, la SAS smetterà di funzionare.
- **Account SAS**: È anch'essa firmata con una delle **chiavi di accesso** dell'account di storage. Concede accesso a risorse attraverso i servizi di un account di storage (Blob, Queue, Table, File) e può includere operazioni a livello di servizio.

Un URL SAS firmato da una **chiave di accesso** appare così:

- `https://<container_name>.blob.core.windows.net/newcontainer?sp=r&st=2021-09-26T18:15:21Z&se=2021-10-27T02:14:21Z&spr=https&sv=2021-07-08&sr=c&sig=7S%2BZySOgy4aA3Dk0V1cJyTSIf1cW%2Fu3WFkhHV32%2B4PE%3D`

Un URL SAS firmato come **user delegation** appare così:

- `https://<container_name>.blob.core.windows.net/testing-container?sp=r&st=2024-11-22T15:07:40Z&se=2024-11-22T23:07:40Z&skoid=d77c71a1-96e7-483d-bd51-bd753aa66e62&sktid=fdd066e1-ee37-49bc-b08f-d0e152119b04&skt=2024-11-22T15:07:40Z&ske=2024-11-22T23:07:40Z&sks=b&skv=2022-11-02&spr=https&sv=2022-11-02&sr=c&sig=7s5dJyeE6klUNRulUj9TNL0tMj2K7mtxyRc97xbYDqs%3D`

Nota alcuni **parametri http**:

- Il parametro **`se`** indica la **data di scadenza** della SAS
- Il parametro **`sp`** indica i **permessi** della SAS
- Il **`sig`** è la **firma** che convalida la SAS

#### Permessi SAS

Quando si genera una SAS è necessario indicare i permessi che dovrebbe concedere. A seconda dell'oggetto su cui viene generata la SAS, potrebbero essere inclusi permessi diversi. Ad esempio:

- (a)dd, (c)reate, (d)elete, (e)xecute, (f)ilter_by_tags, (i)set_immutability_policy, (l)ist, (m)ove, (r)ead, (t)ag, (w)rite, (x)delete_previous_version, (y)permanent_delete

## Supporto SFTP per Azure Blob Storage

Azure Blob Storage ora supporta il protocollo SSH File Transfer Protocol (SFTP), consentendo il trasferimento e la gestione sicura dei file direttamente su Blob Storage senza richiedere soluzioni personalizzate o prodotti di terze parti.

### Caratteristiche principali

- Supporto del protocollo: SFTP funziona con gli account di Blob Storage configurati con namespace gerarchico (HNS). Questo organizza i blob in directory e sottodirectory per una navigazione più semplice.
- Sicurezza: SFTP utilizza identità utente locali per l'autenticazione e non si integra con RBAC o ABAC. Ogni utente locale può autenticarsi tramite:
- Password generate da Azure
- Coppie di chiavi SSH pubbliche-private
- Permessi granulari: Permessi come Lettura, Scrittura, Cancellazione e Elenco possono essere assegnati agli utenti locali per un massimo di 100 contenitori.
- Considerazioni di rete: Le connessioni SFTP vengono effettuate tramite la porta 22. Azure supporta configurazioni di rete come firewall, endpoint privati o reti virtuali per proteggere il traffico SFTP.

### Requisiti di configurazione

- Namespace gerarchico: L'HNS deve essere abilitato durante la creazione dell'account di storage.
- Crittografia supportata: Richiede algoritmi crittografici approvati dal Microsoft Security Development Lifecycle (SDL) (ad es., rsa-sha2-256, ecdsa-sha2-nistp256).
- Configurazione SFTP:
- Abilitare SFTP sull'account di storage.
- Creare identità utente locali con permessi appropriati.
- Configurare le directory home per gli utenti per definire la loro posizione di partenza all'interno del contenitore.

### Permessi

| Permesso              | Simbolo | Descrizione                          |
| --------------------- | ------- | ------------------------------------ |
| **Lettura**           | `r`     | Leggi il contenuto del file.         |
| **Scrittura**         | `w`     | Carica file e crea directory.       |
| **Elenco**            | `l`     | Elenca i contenuti delle directory.  |
| **Cancellazione**     | `d`     | Cancella file o directory.           |
| **Creazione**         | `c`     | Crea file o directory.               |
| **Modifica proprietà**| `o`     | Cambia l'utente o il gruppo proprietario. |
| **Modifica permessi** | `p`     | Cambia le ACL su file o directory.   |

## Enumerazione

{{#tabs }}
{{#tab name="az cli" }}
```bash
# Get storage accounts
az storage account list #Get the account name from here

# BLOB STORAGE
## List containers
az storage container list --account-name <name>
## Check if public access is allowed
az storage container show-permission \
--account-name <acc-name> \
-n <container-name>
## Make a container public
az storage container set-permission \
--public-access container \
--account-name <acc-name> \
-n <container-name>
## List blobs in a container
az storage blob list \
--container-name <container name> \
--account-name <account name>
## Download blob
az storage blob download \
--account-name <account name> \
--container-name <container name> \
--name <blob name> \
--file </path/to/local/file>
## Create container policy
az storage container policy create \
--account-name mystorageaccount \
--container-name mycontainer \
--name fullaccesspolicy \
--permissions racwdl \
--start 2023-11-22T00:00Z \
--expiry 2024-11-22T00:00Z

# QUEUE
az storage queue list --account-name <name>
az storage message peek --account-name <name> --queue-name <queue-name>

# ACCESS KEYS
az storage account keys list --account-name <name>
## Check key policies (expiration time?)
az storage account show -n <name> --query "{KeyPolicy:keyPolicy}"
## Once having the key, it's possible to use it with the argument --account-key
## Enum blobs with account key
az storage blob list \
--container-name <container name> \
--account-name <account name> \
--account-key "ZrF40pkVKvWPUr[...]v7LZw=="
## Download a file using an account key
az storage blob download \
--account-name <account name> \
--account-key "ZrF40pkVKvWPUr[...]v7LZw==" \
--container-name <container name> \
--name <blob name> \
--file </path/to/local/file>
## Upload a file using an account key
az storage blob upload \
--account-name <account name> \
--account-key "ZrF40pkVKvWPUr[...]v7LZw==" \
--container-name <container name> \
--file </path/to/local/file>

# SAS
## List access policies
az storage <container|queue|share|table> policy list \
--account-name <acc name> \
--container-name <container name>

## Generate SAS with all permissions using an access key
az storage <container|queue|share|table|blob> generate-sas \
--permissions acdefilmrtwxy \
--expiry 2024-12-31T23:59:00Z \
--account-name <acc-name> \
-n <container-name>

## Generate SAS with all permissions using via user delegation
az storage <container|queue|share|table|blob> generate-sas \
--permissions acdefilmrtwxy \
--expiry 2024-12-31T23:59:00Z \
--account-name <acc-name> \
--as-user --auth-mode login \
-n <container-name>

## Generate account SAS
az storage account generate-sas \
--expiry 2024-12-31T23:59:00Z \
--account-name <acc-name>  \
--services qt \
--resource-types sco \
--permissions acdfilrtuwxy

## Use the returned SAS key with the param --sas-token
## e.g.
az storage blob show \
--account-name <account name> \
--container-name <container name> \
--sas-token 'se=2024-12-31T23%3A59%3A00Z&sp=racwdxyltfmei&sv=2022-11-02&sr=c&sig=ym%2Bu%2BQp5qqrPotIK5/rrm7EMMxZRwF/hMWLfK1VWy6E%3D' \
--name 'asd.txt'

#Local-Users
## List users
az storage account local-user list \
--account-name <storage-account-name> \
--resource-group <resource-group-name>
## Get user
az storage account local-user show \
--account-name <storage-account-name> \
--resource-group <resource-group-name> \
--name <local-user-name>

## List keys
az storage account local-user list \
--account-name <storage-account-name> \
--resource-group <resource-group-name>
```
{{#endtab }}

{{#tab name="Az PowerShell" }}
```bash
# Get storage accounts
Get-AzStorageAccount | fl
# Get rules to access the storage account
Get-AzStorageAccount | select -ExpandProperty NetworkRuleSet
# Get IPs
(Get-AzStorageAccount | select -ExpandProperty NetworkRuleSet).IPRules
# Get containers of a storage account
Get-AzStorageContainer -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context
# Get blobs inside container
Get-AzStorageBlob -Container epbackup-planetary -Context (Get-AzStorageAccount -name <name> -ResourceGroupName <name>).context
# Get a blob from a container
Get-AzStorageBlobContent -Container <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context -Blob <blob_name> -Destination .\Desktop\filename.txt

# Create a Container Policy
New-AzStorageContainerStoredAccessPolicy `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context `
-Container <container-name> `
-Policy <policy-name> `
-Permission racwdl `
-StartTime (Get-Date "2023-11-22T00:00Z") `
-ExpiryTime (Get-Date "2024-11-22T00:00Z")
#Get Container policy
Get-AzStorageContainerStoredAccessPolicy `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context `
-Container "storageaccount1994container"

# Queue Management
Get-AzStorageQueue -Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context
(Get-AzStorageQueue -Name <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).Context).QueueClient.PeekMessage().Value

#Blob Container
Get-AzStorageBlob -Container <container-name> -Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context
Get-AzStorageBlobContent `
-Container <container-name> `
-Blob <blob-name> `
-Destination <local-path> `
-Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context

Set-AzStorageBlobContent `
-Container <container-name> `
-File <local-file-path> `
-Blob <blob-name> `
-Context $(Get-AzStorageAccount -name "teststorageaccount1998az" -ResourceGroupName "testStorageGroup").Context

# Shared Access Signatures (SAS)
Get-AzStorageContainerAcl `
-Container <container-name> `
-Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <NAME>).Context

New-AzStorageBlobSASToken `
-Context $ctx `
-Container <container-name> `
-Blob <blob-name> `
-Permission racwdl `
-ExpiryTime (Get-Date "2024-12-31T23:59:00Z")
```
{{#endtab }}
{{#endtabs }}

### Condivisioni di File

{{#ref}}
az-file-shares.md
{{#endref}}

## Escalation dei Privilegi

{{#ref}}
../az-privilege-escalation/az-storage-privesc.md
{{#endref}}

## Post Exploitation

{{#ref}}
../az-post-exploitation/az-blob-storage-post-exploitation.md
{{#endref}}

## Persistenza

{{#ref}}
../az-persistence/az-storage-persistence.md
{{#endref}}

## Riferimenti

- [https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction)
- [https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview](https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview)
- [https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support)

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