# Az - Storage Accounts & Blobs

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

## Osnovne informacije

Azure Storage Accounts su osnovne usluge u Microsoft Azure koje pružaju skalabilnu, sigurnu i visoko dostupnu cloud **pohranu za različite tipove podataka**, uključujući blobove (binarni veliki objekti), datoteke, redove i tabele. Oni služe kao kontejneri koji grupišu ove različite usluge pohrane pod jednim imenom za lakše upravljanje.

**Glavne opcije konfiguracije**:

- Svaki storage account mora imati **jedinstveno ime u okviru celog Azure-a**.
- Svaki storage account se implementira u **regionu** ili u proširenoj zoni Azure-a.
- Moguće je odabrati **premium** verziju storage account-a za bolju performansu.
- Moguće je odabrati između **4 tipa redundancije za zaštitu** od kvarova rack-a, diska i datacentra.

**Opcije konfiguracije sigurnosti**:

- **Zahtevati sigurni prenos za REST API operacije**: Zahtevati TLS u bilo kojoj komunikaciji sa pohranom.
- **Omogućava omogućavanje anonimnog pristupa na pojedinačnim kontejnerima**: Ako ne, neće biti moguće omogućiti anonimni pristup u budućnosti.
- **Omogućiti pristup ključu storage account-a**: Ako ne, pristup sa Shared Keys će biti zabranjen.
- **Minimalna TLS verzija**.
- **Dozvoljeni opseg za operacije kopiranja**: Dozvoliti iz bilo kog storage account-a, iz bilo kog storage account-a iz istog Entra tenant-a ili iz storage account-a sa privatnim krajnjim tačkama u istoj virtuelnoj mreži.

**Opcije Blob Storage-a**:

- **Dozvoliti replikaciju između tenant-a**.
- **Pristupni nivo**: Vrući (često pristupani podaci), Hladan i Zaleđen (retko pristupani podaci).

**Opcije umrežavanja**:

- **Pristup mreži**:
- Dozvoliti iz svih mreža.
- Dozvoliti iz odabranih virtuelnih mreža i IP adresa.
- Onemogućiti javni pristup i koristiti privatni pristup.
- **Privatne krajnje tačke**: Omogućava privatnu vezu sa storage account-om iz virtuelne mreže.

**Opcije zaštite podataka**:

- **Obnavljanje u tački vremena za kontejnere**: Omogućava vraćanje kontejnera u ranije stanje.
- Zahteva verzionisanje, promena feed-a i soft delete za blobove da bi bili omogućeni.
- **Omogućiti soft delete za blobove**: Omogućava period zadržavanja u danima za obrisane blobove (čak i prepisane).
- **Omogućiti soft delete za kontejnere**: Omogućava period zadržavanja u danima za obrisane kontejnere.
- **Omogućiti soft delete za deljene datoteke**: Omogućava period zadržavanja u danima za obrisane deljene datoteke.
- **Omogućiti verzionisanje za blobove**: Održava prethodne verzije vaših blobova.
- **Omogućiti blob change feed**: Čuva logove o kreiranju, izmenama i brisanju blobova.
- **Omogućiti podršku za imutabilnost na nivou verzije**: Omogućava postavljanje politike zadržavanja zasnovane na vremenu na nivou naloga koja će se primenjivati na sve verzije blobova.
- Podrška za imutabilnost na nivou verzije i obnavljanje u tački vremena za kontejnere ne mogu se omogućiti istovremeno.

**Opcije konfiguracije enkripcije**:

- **Tip enkripcije**: Moguće je koristiti ključeve koje upravlja Microsoft (MMK) ili ključeve koje upravlja korisnik (CMK).
- **Omogućiti infrastrukturalnu enkripciju**: Omogućava dvostruku enkripciju podataka "za veću sigurnost".

### Storage krajnje tačke

<table data-header-hidden><thead><tr><th width="197">Storage usluga</th><th>Krajnja tačka</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>

### Javno izlaganje

Ako je "Dozvoli javni pristup blobovima" **omogućeno** (podrazumevano onemogućeno), prilikom kreiranja kontejnera moguće je:

- Dati **javni pristup za čitanje blobova** (morate znati ime).
- **Lista kontejnerskih blobova** i **čitati** ih.
- Učiniti ga potpuno **privatnim**.

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

### Povezivanje sa pohranom

Ako pronađete bilo koju **pohranu** kojoj možete pristupiti, možete koristiti alat [**Microsoft Azure Storage Explorer**](https://azure.microsoft.com/es-es/products/storage/storage-explorer/) za to.

## Pristup pohrani <a href="#about-blob-storage" id="about-blob-storage"></a>

### RBAC

Moguće je koristiti Entra ID principe sa **RBAC rolama** za pristup storage account-ima i to je preporučeni način.

### Pristupni ključevi

Storage account-i imaju pristupne ključeve koji se mogu koristiti za pristup. Ovo pruža **potpun pristup storage account-u.**

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

### **Deljeni ključevi i Lite deljeni ključevi**

Moguće je [**generisati deljene ključeve**](https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key) potpisane pristupnim ključevima za autorizaciju pristupa određenim resursima putem potpisanog URL-a.

> [!NOTE]
> Imajte na umu da deo `CanonicalizedResource` predstavlja resurs usluga pohrane (URI). I ako je bilo koji deo u URL-u kodiran, takođe bi trebao biti kodiran unutar `CanonicalizedResource`.

> [!NOTE]
> Ovo je **podrazumevano korišćeno od strane `az` cli** za autentifikaciju zahteva. Da biste koristili kredencijale Entra ID principa, navedite parametar `--auth-mode login`.

- Moguće je generisati **deljeni ključ za blob, red i usluge datoteka** potpisivanjem sledećih informacija:
```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;
```
- Moguće je generisati **deljeni ključ za usluge tabela** potpisivanjem sledećih informacija:
```bash
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
```
- Moguće je generisati **lite deljeni ključ za blob, queue i file servise** potpisivanjem sledećih informacija:
```bash
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
```
- Moguće je generisati **lite shared key for table services** potpisivanjem sledećih informacija:
```bash
StringToSign = Date + "\n"
CanonicalizedResource
```
Zatim, da biste koristili ključ, to se može uraditi u Authorization header-u prema sintaksi:
```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)

Shared Access Signatures (SAS) su sigurni, vremenski ograničeni URL-ovi koji **dodeljuju specifične dozvole za pristup resursima** u Azure Storage nalogu bez izlaganja pristupnih ključeva naloga. Dok pristupni ključevi pružaju punu administrativnu kontrolu nad svim resursima, SAS omogućava granularnu kontrolu tako što specificira dozvole (kao što su čitanje ili pisanje) i definiše vreme isteka.

#### SAS Types

- **User delegation SAS**: Ovo se kreira iz **Entra ID principal** koji će potpisati SAS i delegirati dozvole od korisnika na SAS. Može se koristiti samo sa **blob i data lake storage** ([docs](https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas)). Moguće je **opozvati** sve generisane korisničke delegirane SAS.
- Čak i ako je moguće generisati delegaciju SAS sa "više" dozvola nego što korisnik ima. Međutim, ako principal nema te dozvole, neće raditi (nema privesc).
- **Service SAS**: Ovo se potpisuje koristeći jedan od pristupnih ključeva **storage** naloga. Može se koristiti za dodeljivanje pristupa specifičnim resursima u jednoj usluzi skladištenja. Ako se ključ obnovi, SAS će prestati da funkcioniše.
- **Account SAS**: Takođe se potpisuje jednim od pristupnih ključeva **storage** naloga. Dodeljuje pristup resursima širom usluga skladištenja naloga (Blob, Queue, Table, File) i može uključivati operacije na nivou usluge.

SAS URL potpisan **pristupnim ključem** izgleda ovako:

- `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`

SAS URL potpisan kao **user delegation** izgleda ovako:

- `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`

Napomena o nekim **http params**:

- **`se`** param označava **datum isteka** SAS-a
- **`sp`** param označava **dozvole** SAS-a
- **`sig`** je **potpis** koji validira SAS

#### SAS permissions

Kada se generiše SAS, potrebno je naznačiti dozvole koje bi trebalo da dodeljuje. U zavisnosti od objekta nad kojim se generiše SAS, različite dozvole mogu biti uključene. Na primer:

- (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

## SFTP Support for Azure Blob Storage

Azure Blob Storage sada podržava SSH File Transfer Protocol (SFTP), omogućavajući sigurnu razmenu i upravljanje datotekama direktno u Blob Storage bez potrebe za prilagođenim rešenjima ili proizvodima trećih strana.

### Key Features

- Protocol Support: SFTP radi sa Blob Storage nalozima konfiguriranim sa hijerarhijskim imenskim prostorom (HNS). Ovo organizuje blobove u direktorijume i poddirektorijume radi lakše navigacije.
- Security: SFTP koristi lokalne korisničke identitete za autentifikaciju i ne integriše se sa RBAC ili ABAC. Svaki lokalni korisnik može se autentifikovati putem:
- Azure-generisanih lozinki
- Javnih i privatnih SSH ključeva
- Granular Permissions: Dozvole kao što su Čitanje, Pisanje, Brisanje i Lista mogu se dodeliti lokalnim korisnicima za do 100 kontejnera.
- Networking Considerations: SFTP veze se uspostavljaju preko porta 22. Azure podržava mrežne konfiguracije kao što su vatrozidi, privatne tačke ili virtuelne mreže za zaštitu SFTP saobraćaja.

### Setup Requirements

- Hierarchical Namespace: HNS mora biti omogućen prilikom kreiranja naloga za skladištenje.
- Supported Encryption: Zahteva Microsoft Security Development Lifecycle (SDL)-odobrene kriptografske algoritme (npr. rsa-sha2-256, ecdsa-sha2-nistp256).
- SFTP Configuration:
- Omogućite SFTP na nalogu za skladištenje.
- Kreirajte lokalne korisničke identitete sa odgovarajućim dozvolama.
- Konfigurišite početne direktorijume za korisnike kako biste definisali njihovu početnu lokaciju unutar kontejnera.

### Permissions

| Permission             | Symbol | Description                          |
| ---------------------- | ------ | ------------------------------------ |
| **Read**               | `r`    | Čitaj sadržaj datoteke.              |
| **Write**              | `w`    | Učitaj datoteke i kreiraj direktorijume. |
| **List**               | `l`    | Lista sadržaj direktorijuma.        |
| **Delete**             | `d`    | Obriši datoteke ili direktorijume.   |
| **Create**             | `c`    | Kreiraj datoteke ili direktorijume.  |
| **Modify Ownership**   | `o`    | Promeni korisnika ili grupu vlasnika. |
| **Modify Permissions** | `p`    | Promeni ACL-ove na datotekama ili direktorijumima. |

## Enumeration

{{#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 }}

### Deljenje fajlova

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

## Eskalacija privilegija

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

## Post Eksploatacija

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

## Postojanost

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

## Reference

- [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}}
