Files
hacktricks-cloud/src/pentesting-cloud/azure-security/az-services/az-storage.md
T

23 KiB
Raw Blame History

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 $web por meio de um endpoint específico da região, como https://<account>.z13.web.core.windows.net/.
  • O container $web pode informar publicAccess: null por 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'. Se allowBlobPublicAccess for false, 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 publicAccess for Container, a listagem anônima funciona: curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list".
  • Tanto para Blob quanto para 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 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 CanonicalizedResource representa o recurso dos serviços de storage (URI). E, se alguma parte da URL estiver codificada, ela também deverá ser codificada dentro de CanonicalizedResource.

Note

Isso é usado por padrão pelo az cli 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 se indica a data de expiração do SAS
  • O parâmetro sp indica 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 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>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

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