Az - Storage Accounts & Blobs

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Información básica

Azure Storage Accounts son servicios fundamentales en Microsoft Azure que proporcionan almacenamiento en la nube escalable, seguro y altamente disponible para diversos tipos de datos, incluyendo blobs (binary large objects), files, queues y tables. Sirven como contenedores que agrupan estos distintos servicios de almacenamiento bajo un único namespace para facilitar la gestión.

Principales opciones de configuración:

  • Cada Storage Account debe tener un nombre único en todo Azure.
  • Cada Storage Account se despliega en una región o en una zona extendida de Azure.
  • Es posible seleccionar la versión premium de la cuenta de almacenamiento para mayor rendimiento.
  • Es posible elegir entre 4 tipos de redundancia para protegerse contra fallos de rack, disco y centro de datos.

Opciones de configuración de seguridad:

  • Require secure transfer for REST API operations: exigir TLS en cualquier comunicación con la cuenta de Storage.
  • Allows enabling anonymous access on individual containers: permite habilitar acceso anónimo en contenedores individuales; si no está, no será posible activarlo en el futuro.
  • Enable storage account key access: si no está habilitado, el acceso con Shared Keys quedará prohibido.
  • Minimum TLS version
  • Permitted scope for copy operations: permitir desde cualquier storage account, desde cualquier storage account del mismo Entra tenant o desde storage accounts con private endpoints en la misma red virtual.

Blob Storage options:

  • Allow cross-tenant replication
  • Access tier: Hot (datos de acceso frecuente), Cool y Cold (datos raramente accedidos)

Opciones de red:

  • Network access:
    • Allow from all networks
    • Allow from selected virtual networks and IP addresses
    • Disable public access and use private access
  • Private endpoints: permite una conexión privada a la cuenta de Storage desde una red virtual.

Opciones de protección de datos:

  • Point-in-time restore for containers: permite restaurar contenedores a un estado anterior.
  • Requiere que estén habilitados versioning, change feed y blob soft delete.
  • Enable soft delete for blobs: habilita un periodo de retención en días para blobs eliminados (incluso sobrescritos).
  • Enable soft delete for containers: habilita un periodo de retención en días para contenedores eliminados.
  • Enable soft delete for file shares: habilita un periodo de retención en días para file shares eliminados.
  • Enable versioning for blobs: mantiene versiones previas de tus blobs.
  • Enable blob change feed: conserva registros de creación, modificación y eliminación de blobs.
  • Enable version-level immutability support: permite establecer una política de retención basada en tiempo a nivel de cuenta que se aplicará a todas las versiones de blobs.
  • Version-level immutability support y point-in-time restore for containers no pueden habilitarse simultáneamente.

Opciones de cifrado:

  • Encryption type: es posible usar Microsoft-managed keys (MMK) o Customer-managed keys (CMK).
  • Enable infrastructure encryption: permite cifrar los datos doblemente “for more security”.

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

Exposición pública

Si “Allow Blob public access” está habilitado (deshabilitado por defecto), al crear un contenedor es posible:

  • Dar public access to read blobs (necesitas conocer el nombre).
  • List container blobs y read los blobs.
  • Hacerlo totalmente private

Static website ($web) exposure & leaked secrets

  • Static websites se sirven desde el contenedor especial $web a través de un endpoint específico por región, por ejemplo https://<account>.z13.web.core.windows.net/.
  • El contenedor $web puede reportar publicAccess: null vía la blob API, pero los archivos siguen siendo alcanzables a través del static site endpoint, por lo que dejar artefactos de config/IaC allí puede leak secrets.
  • Flujo rápido de auditoría:
# 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

Auditoría de exposición anónima de blob

  • Localizar cuentas de almacenamiento que pueden exponer datos: az storage account list | jq -r '.[] | select(.properties.allowBlobPublicAccess==true) | .name'. Si allowBlobPublicAccess es false no puedes poner los contenedores como públicos.
  • Inspeccionar cuentas riesgosas para confirmar el indicador y otras configuraciones débiles: az storage account show --name <acc> --query '{allow:properties.allowBlobPublicAccess, minTls:properties.minimumTlsVersion}'.
  • Enumerar exposición a nivel de contenedor donde el flag esté habilitado:
az storage container list --account-name <acc> \
--query '[].{name:name, access:properties.publicAccess}'
  • "Blob": lecturas anónimas permitidas solo cuando se conoce el nombre del blob (sin listado).
  • "Container": listado anónimo + lectura de cada blob.
  • null: privado; se requiere autenticación.
  • Probar acceso sin credenciales:
  • Si publicAccess es Container, el listado anónimo funciona: curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list".
  • Para ambos Blob y Container, la descarga anónima del blob funciona cuando se conoce el nombre:
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>"

Conectarse al almacenamiento

Si encuentras algún almacenamiento al que puedas conectarte, puedes usar la herramienta Microsoft Azure Storage Explorer para hacerlo.

Acceso al almacenamiento

RBAC

Es posible usar principales de Entra ID con roles RBAC para acceder a cuentas de almacenamiento, y es la forma recomendada.

Claves de acceso

Las cuentas de almacenamiento tienen claves de acceso que pueden usarse para acceder a ellas. Esto proporciona acceso completo a la cuenta de almacenamiento.

Claves compartidas y Claves compartidas Lite

Es posible generar Claves compartidas firmadas con las claves de acceso para autorizar el acceso a ciertos recursos mediante una URL firmada.

Note

Ten en cuenta que la parte CanonicalizedResource representa el recurso del servicio de almacenamiento (URI). Y si alguna parte de la URL está codificada, también debe estar codificada dentro de CanonicalizedResource.

Note

Esto se usa por defecto con la cli az para autenticar solicitudes. Para que use las credenciales del principal de Entra ID indica el parámetro --auth-mode login.

  • Es posible generar una clave compartida para los servicios blob, queue y file firmando la siguiente información:
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;
  • Es posible generar una shared key for table services firmando la siguiente información:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
  • Es posible generar una lite shared key for blob, queue and file services firmando la siguiente información:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
  • Es posible generar una lite shared key for table services firmando la siguiente información:
StringToSign = Date + "\n"
CanonicalizedResource

Entonces, para usar la clave, se puede hacer en el encabezado Authorization siguiendo la sintaxis:

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

Firma de acceso compartido (SAS)

Las Firmas de acceso compartido (SAS) son URLs seguras y con tiempo limitado que conceden permisos específicos para acceder a recursos en una cuenta de Azure Storage sin exponer las claves de acceso de la cuenta. Mientras que las claves de acceso proporcionan acceso administrativo completo a todos los recursos, las SAS permiten un control granular al especificar permisos (como lectura o escritura) y definir una fecha de expiración.

Tipos de SAS

  • SAS de delegación de usuario: Esto se crea a partir de un principal de Entra ID que firmará la SAS y delegará los permisos del usuario a la SAS. Solo puede usarse con blob and data lake storage (docs). Es posible revocar todas las SAS delegadas de usuario generadas.
  • Aunque es posible generar una SAS de delegación con permisos “mayores” a los que tiene el usuario, si el principal no los posee no funcionará (sin privesc).
  • SAS de servicio: Esta se firma usando una de las claves de acceso de la cuenta de almacenamiento. Puede emplearse para otorgar acceso a recursos específicos en un único servicio de almacenamiento. Si la clave se renueva, la SAS dejará de funcionar.
  • SAS de cuenta: También se firma con una de las claves de acceso de la cuenta de almacenamiento. Otorga acceso a recursos a través de los servicios de una cuenta de almacenamiento (Blob, Queue, Table, File) y puede incluir operaciones a nivel de servicio.

Una URL SAS firmada por una access key se ve así:

  • 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

Una URL SAS firmada como user delegation se ve así:

  • 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 algunos parámetros http:

  • El se indica la fecha de expiración de la SAS
  • El sp indica los permisos de la SAS
  • El sig es la firma que valida la SAS

Permisos de SAS

Al generar una SAS es necesario indicar los permisos que debe otorgar. Dependiendo del objeto sobre el que se genere la SAS, se pueden incluir permisos diferentes. Por ejemplo:

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

Soporte SFTP para Azure Blob Storage

Azure Blob Storage ahora soporta el Protocolo de Transferencia de Archivos SSH (SFTP), permitiendo la transferencia y gestión segura de archivos directamente en Blob Storage sin requerir soluciones personalizadas o productos de terceros.

Características clave

  • Soporte de protocolo: SFTP funciona con cuentas de Blob Storage configuradas con hierarchical namespace (HNS). Esto organiza los blobs en directorios y subdirectorios para facilitar la navegación.
  • Seguridad: SFTP utiliza identidades de usuario locales para la autenticación y no se integra con RBAC ni ABAC. Cada usuario local puede autenticarse mediante:
    • contraseñas generadas por Azure
    • pares de claves SSH públicas/privadas
  • Permisos granulares: Se pueden asignar permisos como Leer, Escribir, Eliminar y Listar a usuarios locales para hasta 100 contenedores.
  • Consideraciones de red: Las conexiones SFTP se realizan a través del puerto 22. Azure soporta configuraciones de red como firewalls, private endpoints o virtual networks para securizar el tráfico SFTP.

Requisitos de configuración

  • Hierarchical Namespace: HNS debe estar habilitado al crear la cuenta de almacenamiento.
  • Cifrado soportado: Requiere algoritmos criptográficos aprobados por Microsoft Security Development Lifecycle (SDL) (p.ej., rsa-sha2-256, ecdsa-sha2-nistp256).
  • Configuración de SFTP:
    • Habilitar SFTP en la cuenta de almacenamiento.
    • Crear identidades de usuario locales con permisos apropiados.
    • Configurar directorios home para los usuarios para definir su ubicación inicial dentro del contenedor.

Permisos

PermisoSímboloDescripción
ReadrLeer el contenido del archivo.
WritewSubir archivos y crear directorios.
ListlListar el contenido de directorios.
DeletedEliminar archivos o directorios.
CreatecCrear archivos o directorios.
Modify OwnershipoCambiar el usuario o grupo propietario.
Modify PermissionspCambiar las ACLs en archivos o directorios.

Enumeración

enumeración con 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>Az PowerShell enumeración</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")

Compartición de archivos

Az - File Shares

Escalada de privilegios

Az - Storage Privesc

Post-explotación

Az - Blob Storage Post Exploitation

Persistencia

Az - Storage Persistence

Referencias

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks