23 KiB
Az - Contas de Storage e Blobs
{{#include ../../../banners/hacktricks-training.md}}
Informações básicas
As Azure Storage Accounts são serviços fundamentais do Microsoft Azure que fornecem storage escalável, seguro e altamente disponível para vários tipos de dados, incluindo blobs (binary large objects), files, queues e tables. Elas funcionam como containers que agrupam esses diferentes serviços de storage em um único namespace para facilitar o gerenciamento.
Principais opções de configuração:
- Toda storage account deve ter um nome único em todo o Azure.
- Toda storage account é implantada em uma região ou em uma extended zone do Azure
- É possível selecionar a versão premium da storage account para obter melhor desempenho
- É possível selecionar entre 4 tipos de redundância para proteção contra falhas de rack, drive e datacenter.
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: Caso contrário, não será possível habilitar acesso anônimo no futuro
- Enable storage account key access: Caso contrário, o acesso com Shared Keys será proibido
- Minimum TLS version
- Permitted scope for copy operations: Permite operações a partir de qualquer storage account, de qualquer storage account do mesmo Entra tenant ou de uma storage account com private endpoints na mesma virtual network.
Opções de Blob Storage:
- Allow cross-tenant replication
- Access tier: Hot (dados acessados frequentemente), Cool e Cold (dados acessados raramente)
Opções de rede:
- Network access:
- Permitir acesso de todas as redes
- Permitir acesso de virtual networks e endereços IP selecionados
- Desabilitar o acesso público e usar acesso privado
- 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 habilitados.
- Enable soft delete for blobs: Habilita um período de retenção em dias para blobs excluídos (inclusive sobrescritos)
- Enable soft delete for containers: Habilita um período de retenção em dias para containers excluídos
- Enable soft delete for file shares: Habilita um período de retenção em dias para file shares excluídos
- Enable versioning for blobs: Mantém versões anteriores dos seus blobs
- Enable blob change feed: Mantém logs das alterações de criação, modificação e exclusão dos blobs
- Enable version-level immutability support: Permite definir uma política de retenção baseada em tempo no nível da account, que será aplicada a todas as versões de blobs.
- O version-level immutability support e o point-in-time restore for containers não podem ser habilitados simultaneamente.
Opções de configuração de criptografia:
- Encryption type: É possível usar chaves gerenciadas pela Microsoft (MMK) ou chaves gerenciadas pelo cliente (CMK)
- Enable infrastructure encryption: Permite criptografar os dados duas vezes "para obter mais segurança"
Endpoints de storage
| Serviço de storage | Endpoint |
|---|---|
| Blob storage | https://<storage-account>.blob.core.windows.net |
| Listagem de containers de Blob storage | https://<stg-acc>.blob.core.windows.net/<container-name>?restype=container&comp=list |
| Data Lake Storage | https://<storage-account>.dfs.core.windows.net |
| Azure Files | https://<storage-account>.file.core.windows.net |
| Queue storage | https://<storage-account>.queue.core.windows.net |
| Table storage | https://<storage-account>.table.core.windows.net |
Exposição pública
Se "Allow Blob public access" estiver habilitado (desabilitado por padrão), ao criar um container será possível:
- Conceder acesso público para ler blobs (é necessário conhecer o nome).
- Listar os blobs do container e lê-los.
- Torná-lo totalmente privado
Exposição de static website ($web) e segredos expostos
- Static websites são servidos a partir do container especial
$webpor meio de um endpoint específico da região, comohttps://<account>.z13.web.core.windows.net/. - O container
$webpode informarpublicAccess: nullpor meio da blob API, mas os arquivos ainda podem ser acessados pelo endpoint do static site; portanto, colocar artefatos de configuração/IaC nesse local pode causar o leak de secrets. - Fluxo rápido de auditoria:
# 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
Auditando a exposição anônima de blobs
- Localize contas de armazenamento que podem expor dados:
az storage account list | jq -r '.[] | select(.properties.allowBlobPublicAccess==true) | .name'. SeallowBlobPublicAccessforfalse, você não poderá tornar os containers públicos. - Inspecione contas de risco para confirmar a configuração e outras definições fracas:
az storage account show --name <acc> --query '{allow:properties.allowBlobPublicAccess, minTls:properties.minimumTlsVersion}'. - Enumere a exposição no nível dos containers onde a configuração estiver habilitada:
az storage container list --account-name <acc> \
--query '[].{name:name, access:properties.publicAccess}'
"Blob": leituras anônimas permitidas somente quando o nome do blob é conhecido (sem listagem)."Container": listagem + leitura anônimas de todos os blobs.null: privado; autenticação necessária.- Comprove o acesso sem credenciais:
- Se
publicAccessforContainer, a listagem anônima funciona:curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list". - Tanto para
Blobquanto paraContainer, 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 você encontrar algum storage ao qual possa se conectar, poderá usar a ferramenta Microsoft Azure Storage Explorer para isso.
Acesso ao Storage
RBAC
É possível usar principals do Entra ID com funções RBAC para acessar contas de storage, e essa é a forma recomendada.
Chaves de acesso
As contas de storage possuem chaves de acesso que podem ser usadas para acessá-las. Isso fornece acesso total à conta de storage.

Shared Keys e Lite Shared Keys
É possível gerar Shared Keys assinadas com as chaves de acesso para autorizar o acesso a determinados recursos por meio de uma URL assinada.
Note
Observe que a parte
CanonicalizedResourcerepresenta o recurso dos serviços de storage (URI). E, se alguma parte da URL estiver codificada, ela também deverá ser codificada dentro deCanonicalizedResource.
Note
Isso é usado por padrão pelo
azcli para autenticar requisições. Para fazê-lo usar as credenciais do principal do Entra ID, indique o parâmetro--auth-mode login.
- É possível gerar uma shared key para os serviços de blob, queue e file, assinando as seguintes informações:
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 para os serviços blob, queue e file assinando as seguintes informações:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
- É possível gerar uma chave compartilhada lite para serviços de tabela assinando as seguintes informações:
StringToSign = Date + "\n"
CanonicalizedResource
Então, para usar a chave, isso pode ser feito no cabeçalho Authorization 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
Shared Access Signature (SAS)
Shared Access Signatures (SAS) são URLs seguras e limitadas por tempo 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 completo a todos os recursos, o SAS permite um controle granular ao especificar permissões (como leitura ou escrita) e definir um tempo de expiração.
Tipos de SAS
- User delegation SAS: É criado a partir de um principal do Entra ID, que assinará o SAS e delegará as permissões do usuário ao SAS. Ele só pode ser usado com blob e data lake storage (docs). É possível revogar todos os user delegated SAS gerados.
- Mesmo que seja possível gerar um delegation SAS com "mais" permissões do que as que o usuário possui, se o principal não tiver essas permissões, ele não funcionará (sem privesc).
- Service SAS: É assinado usando uma das chaves de acesso da conta de storage. Pode ser usado para conceder acesso a recursos específicos em um único serviço de storage. Se a chave for renovada, o SAS deixará de funcionar.
- Account SAS: Também é assinado com uma das chaves de acesso da conta de storage. Ele concede acesso a recursos em vários serviços de uma conta de storage (Blob, Queue, Table, File) e pode incluir operações no nível do serviço.
Uma URL SAS assinada por uma chave de acesso é semelhante a esta:
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
Uma URL SAS assinada como user delegation é semelhante a esta:
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 http params:
- O parâmetro
seindica a data de expiração do SAS - O parâmetro
spindica as permissões do SAS - O
sigé a assinatura que valida o SAS
Permissões do SAS
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)dicionar, (c)riar, (d)eletar, (e)xecutar, (f)ilter_by_tags, (i)set_immutability_policy, (l)istar, (m)over, (r)ead, (t)ag, (w)rite, (x)delete_previous_version, (y)permanent_delete
Suporte a SFTP para Azure Blob Storage
O Azure Blob Storage agora oferece suporte ao SSH File Transfer Protocol (SFTP), permitindo a transferência e o gerenciamento seguros de arquivos diretamente no Blob Storage sem exigir soluções personalizadas ou produtos de terceiros.
Principais recursos
- Suporte a protocolos: O SFTP funciona com contas do Blob Storage configuradas com hierarchical namespace (HNS). Isso organiza os blobs em diretórios e subdiretórios para facilitar a navegação.
- Segurança: O SFTP pode usar identidades de usuários locais, mas também oferece suporte ao acesso baseado no Microsoft Entra ID com Azure RBAC para autorização. Isso significa que o acesso pode ser concedido com as funções usuais do data-plane do Blob Storage, em vez de criar usuários SFTP locais. Usuários locais podem se autenticar por meio de:
- Senhas geradas pelo Azure
- Pares de chaves SSH públicas e privadas
- Permissões granulares: Permissões como Read, Write, Delete e List podem ser atribuídas a usuários locais para até 100 containers.
- Considerações de rede: As conexões SFTP são feitas pela porta 22. O Azure oferece suporte a configurações de rede como firewalls, private endpoints ou redes virtuais para proteger o tráfego SFTP.
Requisitos de configuração
- Hierarchical Namespace: O HNS deve estar habilitado ao criar a conta de storage.
- Criptografia compatível: Requer algoritmos criptográficos aprovados pelo Microsoft Security Development Lifecycle (SDL) (por exemplo, rsa-sha2-256, ecdsa-sha2-nistp256).
- Configuração do SFTP:
- Habilite o SFTP na conta de storage.
- Para acesso de usuários locais, crie identidades de usuários locais com as permissões apropriadas.
- Para usuários locais, configure os diretórios home para definir sua localização inicial dentro do container.
Permissões
| Permissão | Símbolo | Descrição |
|---|---|---|
| Read | r |
Ler o conteúdo dos arquivos. |
| Write | w |
Fazer upload de arquivos e criar diretórios. |
| List | l |
Listar o conteúdo dos diretórios. |
| Delete | d |
Deletar arquivos ou diretórios. |
| Create | c |
Criar arquivos ou diretórios. |
| Modify Ownership | o |
Alterar o usuário ou grupo proprietário. |
| Modify Permissions | p |
Alterar ACLs em arquivos ou diretórios. |
Enumeração
{{#tabs }} {{#tab name="az cli" }}
enumeração do az cli
```bash # Get storage accounts az storage account list #Get the account name from hereBLOB 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>Enumeração do Az PowerShell</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")
{{#endtab }} {{#endtabs }}
Compartilhamentos de Arquivos
{{#ref}} az-file-shares.md {{#endref}}
Escalonamento de Privilégios
{{#ref}} ../az-privilege-escalation/az-storage-privesc.md {{#endref}}
Pós-Exploração
{{#ref}} ../az-post-exploitation/az-blob-storage-post-exploitation.md {{#endref}}
Persistência
{{#ref}} ../az-persistence/az-storage-persistence.md {{#endref}}
Referências
- 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/blobs/secure-file-transfer-protocol-support
- https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support-entra-id-based-access
- Holiday Hack Challenge 2025 – Spare Key (Azure static website SAS leak)
- Holiday Hack Challenge 2025: Blob Storage (Storage Secrets)
- https://learn.microsoft.com/en-us/cli/azure/storage/account
- https://learn.microsoft.com/en-us/cli/azure/storage/container
- https://learn.microsoft.com/en-us/cli/azure/storage/blob
{{#include ../../../banners/hacktricks-training.md}}