Az - Storage Accounts & Blobs

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Informações Básicas

Azure Storage Accounts são serviços fundamentais na Microsoft Azure que fornecem armazenamento em nuvem escalável, seguro e altamente disponível para vários tipos de dados, incluindo blobs (binary large objects), files, queues e tables. Eles funcionam como contêineres que agrupam esses diferentes serviços de storage sob um único namespace para facilitar a gestão.

Principais opções de configuração:

  • Cada storage account deve ter um nome único em todo o Azure.
  • Cada storage account é implantada em uma região ou em uma zona estendida do Azure.
  • É possível selecionar a versão premium da storage account para melhor desempenho.
  • É possível escolher entre 4 tipos de redundância para proteger contra falhas em racks, discos e datacenters.

Opções de configuração de segurança:

  • Require secure transfer for REST API operations: Exige TLS em qualquer comunicação com o storage.
  • Allows enabling anonymous access on individual containers: Se desativado, não será possível habilitar acesso anônimo no futuro.
  • Enable storage account key access: Se desativado, o acesso com Shared Keys será proibido.
  • Minimum TLS version
  • Permitted scope for copy operations: Permitir de qualquer storage account, de qualquer storage account do mesmo Entra tenant ou de storage accounts com private endpoints na mesma virtual network.

Opções de Blob Storage:

  • Allow cross-tenant replication
  • Access tier: Hot (dados acessados com frequência), Cool e Cold (dados raramente acessados)

Opções de rede:

  • Network access:
  • Allow from all networks
  • Allow from selected virtual networks and IP addresses
  • Disable public access and use private access
  • Private endpoints: Permite uma conexão privada à storage account a partir de uma virtual network

Opções de proteção de dados:

  • Point-in-time restore for containers: Permite restaurar containers para um estado anterior.
  • Requer que versioning, change feed e blob soft delete estejam ativados.
  • Enable soft delete for blobs: Habilita um período de retenção (em dias) para blobs deletados (mesmo sobrescritos).
  • Enable soft delete for containers: Habilita um período de retenção (em dias) para containers deletados.
  • Enable soft delete for file shares: Habilita um período de retenção (em dias) para file shares deletados.
  • Enable versioning for blobs: Mantém versões anteriores dos seus blobs.
  • Enable blob change feed: Mantém logs de criação, modificação e deleção de blobs.
  • Enable version-level immutability support: Permite definir uma política de retenção baseada em tempo no nível da conta que se aplicará a todas as versões de blob.
  • Version-level immutability support e point-in-time restore for containers não podem ser habilitados simultaneamente.

Opções de configuração de criptografia:

  • Encryption type: É possível usar Microsoft-managed keys (MMK) ou Customer-managed keys (CMK).
  • Enable infrastructure encryption: Permite uma dupla criptografia dos dados “para mais segurança”.

Storage endpoints

Storage ServiceEndpoint
Blob storagehttps://.blob.core.windows.net

https://.blob.core.windows.net/?restype=container&comp=list
Data Lake Storagehttps://.dfs.core.windows.net
Azure Fileshttps://.file.core.windows.net
Queue storagehttps://.queue.core.windows.net
Table storagehttps://.table.core.windows.net

Exposição Pública

Se “Allow Blob public access” estiver habilitado (desabilitado por padrão), ao criar um container é possível:

  • Conceder acesso público para leitura de blobs (é preciso conhecer o nome).
  • Listar blobs do container e lê-los.
  • Torná-lo totalmente privado

Static website ($web) exposure & leaked secrets

  • Static websites são servidos a partir do contêiner especial $web através de um endpoint específico da região, por exemplo https://<account>.z13.web.core.windows.net/.
  • O contêiner $web pode reportar publicAccess: null via a blob API, mas os arquivos ainda são alcançáveis através do static site endpoint, então deixar artifacts de config/IaC lá pode leak secrets.
  • Quick audit workflow:
# Identify storage accounts with static website hosting enabled
az storage blob service-properties show --account-name <acc-name> --auth-mode login
# Enumerate containers (including $web) and their public flags
az storage container list --account-name <acc-name> --auth-mode login
# List files served by the static site even when publicAccess is null
az storage blob list --container-name '$web' --account-name <acc-name> --auth-mode login
# Pull suspicious files directly (e.g., IaC tfvars containing secrets/SAS)
az storage blob download -c '$web' --name iac/terraform.tfvars --file /dev/stdout --account-name <acc-name> --auth-mode login

Auditoria da exposição anônima de blob

  • Locate storage accounts que podem expor dados: az storage account list | jq -r '.[] | select(.properties.allowBlobPublicAccess==true) | .name'. Se allowBlobPublicAccess for false você não pode tornar containers públicos.
  • Inspect risky accounts para confirmar a flag e outras configurações fracas: az storage account show --name <acc> --query '{allow:properties.allowBlobPublicAccess, minTls:properties.minimumTlsVersion}'.
  • Enumerate container-level exposure onde a flag está habilitada:
az storage container list --account-name <acc> \
--query '[].{name:name, access:properties.publicAccess}'
  • "Blob": leituras anônimas permitidas apenas quando o nome do blob é conhecido (sem listagem).
  • "Container": listagem + leitura anônimas de todos os blobs.
  • null: privado; autenticação necessária.
  • Comprove acesso sem credenciais:
  • Se publicAccess estiver definido como Container, a listagem anônima funciona: curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list".
  • Para ambos Blob e Container, o download anônimo do blob funciona quando o nome é conhecido:
az storage blob download -c <container> -n <blob> --account-name <acc> --file /dev/stdout
# or via raw HTTP
curl "https://<acc>.blob.core.windows.net/<container>/<blob>"

Conectar ao Storage

Se encontrar algum storage ao qual possa conectar, pode usar a ferramenta Microsoft Azure Storage Explorer para isso.

Acesso ao Storage

RBAC

É possível usar principals do Entra ID com RBAC roles para aceder contas de armazenamento, e esta é a forma recomendada.

Chaves de Acesso

As contas de armazenamento têm chaves de acesso que podem ser usadas para aceder a elas. Isto fornece acesso total à conta de armazenamento.

Shared Keys & Lite Shared Keys

É possível gerar Shared Keys assinadas com as chaves de acesso para autorizar o acesso a certos recursos através de um URL assinado.

Note

Note que a parte CanonicalizedResource representa o recurso do serviço de armazenamento (URI). E se qualquer parte no URL estiver codificada, também deverá estar codificada dentro do CanonicalizedResource.

Note

Isto é usado por padrão pelo az cli para autenticar solicitações. Para que utilize as credenciais do principal Entra ID indique o parâmetro --auth-mode login.

  • É possível gerar uma shared key para os serviços blob, queue e file assinando a seguinte informação:
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;
  • É possível gerar uma chave compartilhada para serviços de tabela assinando as seguintes informações:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
  • É possível gerar uma lite shared key for blob, queue and file services assinando as seguintes informações:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
  • É possível gerar uma lite shared key for table services assinando as seguintes informações:
StringToSign = Date + "\n"
CanonicalizedResource

Então, para usar a key, ela pode ser colocada no Authorization header seguindo a sintaxe:

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

Assinatura de Acesso Compartilhado (SAS)

Shared Access Signatures (SAS) são URLs seguras e por tempo limitado que concedem permissões específicas para acessar recursos em uma conta do Azure Storage sem expor as chaves de acesso da conta. Enquanto as chaves de acesso fornecem acesso administrativo total a todos os recursos, o SAS permite controle granular especificando permissões (como read ou write) e definindo um tempo de expiração.

SAS Types

  • User delegation SAS: Isso é criado a partir de um Entra ID principal que vai assinar o SAS e delegar as permissões do usuário para o SAS. Só pode ser usado com blob and data lake storage (docs). É possível revogar todos os SAS delegados de usuário gerados.
  • Mesmo que seja possível gerar um delegation SAS com “mais” permissões do que as que o usuário possui. Contudo, se o principal não as tiver, não funcionará (no privesc).
  • Service SAS: É assinado usando uma das access keys da storage account. Pode ser usado para conceder acesso a recursos específicos em um único serviço de storage. Se a key for renovada, o SAS deixará de funcionar.
  • Account SAS: Também é assinado com uma das access keys da storage account. Concede acesso a recursos através dos serviços de uma storage account (Blob, Queue, Table, File) e pode incluir operações a nível de serviço.

A SAS URL assinada por uma access key fica assim:

  • 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

A SAS URL assinada como user delegation fica assim:

  • 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

Observe alguns parâmetros http:

  • O se indica a data de expiração do SAS
  • O sp indica as permissões do SAS
  • O sig é a assinatura que valida o SAS

SAS permissions

Ao gerar um SAS é necessário indicar as permissões que ele deve conceder. Dependendo do objeto sobre o qual o SAS está sendo gerado, diferentes permissões podem ser incluídas. Por exemplo:

  • (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 agora suporta o SSH File Transfer Protocol (SFTP), permitindo transferência segura de arquivos e gerenciamento diretamente no Blob Storage sem exigir soluções customizadas ou produtos de terceiros.

Key Features

  • Protocol Support: SFTP funciona com storage accounts configuradas com hierarchical namespace (HNS). Isso organiza blobs em diretórios e subdiretórios para facilitar a navegação.
  • Security: SFTP usa identidades de usuários locais para autenticação e não se integra com RBAC ou ABAC. Cada usuário local pode autenticar via:
  • Azure-generated passwords
  • Public-private SSH key pairs
  • Granular Permissions: Permissões como Read, Write, Delete e List podem ser atribuídas a usuários locais para até 100 containers.
  • Networking Considerations: Conexões SFTP são feitas pela porta 22. A Azure suporta configurações de rede como firewalls, private endpoints ou virtual networks para proteger o tráfego SFTP.

Setup Requirements

  • Hierarchical Namespace: HNS deve estar habilitado ao criar a storage account.
  • Supported Encryption: Requer algoritmos criptográficos aprovados pelo Microsoft Security Development Lifecycle (SDL) (ex.: rsa-sha2-256, ecdsa-sha2-nistp256).
  • SFTP Configuration:
  • Habilitar SFTP na storage account.
  • Criar identidades de usuários locais com permissões apropriadas.
  • Configurar home directories para os usuários definirem sua localização inicial dentro do container.

Permissions

PermissionSymbolDescription
ReadrLer o conteúdo do arquivo.
WritewFazer upload de arquivos e criar diretórios.
ListlListar conteúdo de diretórios.
DeletedExcluir arquivos ou diretórios.
CreatecCriar arquivos ou diretórios.
Modify OwnershipoAlterar o usuário ou grupo proprietário.
Modify PermissionspAlterar ACLs em arquivos ou diretórios.

Enumeração

az cli enumeração ```bash # Get storage accounts az storage account list #Get the account name from here

BLOB STORAGE

List containers

az storage container list –account-name

Check if public access is allowed

az storage container show-permission
–account-name
-n

Make a container public

az storage container set-permission
–public-access container
–account-name
-n

List blobs in a container

az storage blob list
–container-name
–account-name

Download blob

az storage blob download
–account-name
–container-name
–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 az storage message peek –account-name –queue-name

ACCESS KEYS

az storage account keys list –account-name

Check key policies (expiration time?)

az storage account show -n –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
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”

Download a file using an account key

az storage blob download
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”
–container-name
–name
–file </path/to/local/file>

Upload a file using an account key

az storage blob upload
–account-name
–account-key “ZrF40pkVKvWPUr[…]v7LZw==”
–container-name
–file </path/to/local/file>

SAS

List access policies

az storage <container|queue|share|table> policy list
–account-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
-n

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
–as-user –auth-mode login
-n

Generate account SAS

az storage account generate-sas
–expiry 2024-12-31T23:59:00Z
–account-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
–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
–resource-group

Get user

az storage account local-user show
–account-name
–resource-group
–name

List keys

az storage account local-user list
–account-name
–resource-group

</details>

{{#endtab }}

{{#tab name="Az PowerShell" }}

<details>
<summary>Az PowerShell enumeração</summary>
```powershell
# 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")

Compartilhamentos de Arquivos

Az - File Shares

Elevação de Privilégios

Az - Storage Privesc

Pós-Exploração

Az - Blob Storage Post Exploitation

Persistência

Az - Storage Persistence

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks