Az - Storage Accounts & Blobs

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Informations de base

Azure Storage Accounts sont des services fondamentaux de Microsoft Azure qui fournissent un stockage cloud évolutif, sécurisé et hautement disponible pour différents types de données, y compris blobs (binary large objects), files, queues et tables. Ils servent de conteneurs regroupant ces différents services de stockage sous un même namespace pour une gestion simplifiée.

Principales options de configuration :

  • Chaque storage account doit avoir un nom unique dans tout Azure.
  • Chaque storage account est déployé dans une région ou dans une zone étendue Azure.
  • Il est possible de sélectionner la version premium du storage account pour de meilleures performances.
  • Il est possible de choisir parmi 4 types de redondance pour se protéger contre les pannes de rack, disque et datacenter.

Options de configuration de sécurité :

  • Require secure transfer for REST API operations : Exiger TLS pour toute communication avec le storage.
  • Allows enabling anonymous access on individual containers : Sinon, il ne sera pas possible d’activer l’accès anonyme ultérieurement.
  • Enable storage account key access : Sinon, l’accès avec Shared Keys sera interdit.
  • Minimum TLS version
  • Permitted scope for copy operations : Autoriser depuis n’importe quel storage account, depuis n’importe quel storage account du même tenant Entra ou depuis des storage account avec private endpoints dans le même virtual network.

Blob Storage options :

  • Allow cross-tenant replication
  • Access tier : Hot (données fréquemment consultées), Cool et Cold (données rarement consultées)

Options réseau :

  • Network access :
  • Allow from all networks
  • Allow from selected virtual networks and IP addresses
  • Disable public access and use private access
  • Private endpoints : Permet une connexion privée au storage account depuis un virtual network

Options de protection des données :

  • Point-in-time restore for containers : Permet de restaurer des containers à un état antérieur.
  • Cela nécessite l’activation de versioning, change feed, et blob soft delete.
  • Enable soft delete for blobs : Active une période de rétention en jours pour les blobs supprimés (même écrasés).
  • Enable soft delete for containers : Active une période de rétention en jours pour les containers supprimés.
  • Enable soft delete for file shares : Active une période de rétention en jours pour les file shares supprimés.
  • Enable versioning for blobs : Conserve les versions précédentes de vos blobs.
  • Enable blob change feed : Conserve des logs de création, modification et suppression des blobs.
  • Enable version-level immutability support : Permet de définir une politique de rétention temporelle au niveau du compte qui s’appliquera à toutes les versions de blobs.
  • Version-level immutability support et point-in-time restore for containers ne peuvent pas être activés simultanément.

Options de chiffrement :

  • Encryption type : Il est possible d’utiliser Microsoft-managed keys (MMK) ou Customer-managed keys (CMK).
  • Enable infrastructure encryption : Permet de chiffrer doublement les données “pour plus de sécurité”.

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

Exposition publique

Si “Allow Blob public access” est activé (désactivé par défaut), lors de la création d’un container il est possible de :

  • Donner un accès public en lecture aux blobs (il faut connaître le nom).
  • Lister les blobs du container et les lire.
  • Le rendre complètement privé.

Exposition du site statique ($web) & leaked secrets

  • Static websites sont servies depuis le container spécial $web via un endpoint spécifique à la région, par exemple https://<account>.z13.web.core.windows.net/.
  • Le container $web peut renvoyer publicAccess: null via l’API blob, mais les fichiers restent accessibles via l’endpoint du site statique, donc déposer des artefacts de config/IaC là-bas peut leak des secrets.
  • Flux de travail d’audit rapide:
# 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

Audit de l’exposition anonyme des blobs

  • Localisez les storage accounts pouvant exposer des données : az storage account list | jq -r '.[] | select(.properties.allowBlobPublicAccess==true) | .name'. Si allowBlobPublicAccess est false vous ne pouvez pas rendre les containers publics.
  • Inspectez les comptes risqués pour confirmer le flag et d’autres paramètres faibles : az storage account show --name <acc> --query '{allow:properties.allowBlobPublicAccess, minTls:properties.minimumTlsVersion}'.
  • Énumérez l’exposition au niveau du container lorsque le flag est activé:
az storage container list --account-name <acc> \
--query '[].{name:name, access:properties.publicAccess}'
  • "Blob": accès en lecture anonyme autorisé uniquement lorsque le nom du blob est connu (sans possibilité de lister).
  • "Container": liste + lecture anonymes de chaque blob.
  • null: privé ; authentification requise.
  • Prouver l’accès sans identifiants :
  • Si publicAccess est Container, le listing anonyme fonctionne : curl "https://<acc>.blob.core.windows.net/<container>?restype=container&comp=list".
  • Pour Blob et Container, le téléchargement anonyme d’un blob fonctionne lorsque son nom est connu :
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>"

Se connecter au stockage

Si vous trouvez un compte de stockage auquel vous pouvez vous connecter, vous pouvez utiliser l’outil Microsoft Azure Storage Explorer pour ce faire.

Accès au stockage

RBAC

Il est possible d’utiliser des principals Entra ID avec des RBAC roles pour accéder aux comptes de stockage ; c’est la méthode recommandée.

Clés d’accès

Les comptes de stockage disposent de clés d’accès qui peuvent être utilisées pour y accéder. Cela fournit un accès complet au compte de stockage.

Shared Keys & Lite Shared Keys

Il est possible de générer des Shared Keys signées avec les clés d’accès pour autoriser l’accès à certaines ressources via une URL signée.

Note

Notez que la partie CanonicalizedResource représente la ressource du service de stockage (URI). Et si une partie de l’URL est encodée, elle doit également être encodée à l’intérieur de la CanonicalizedResource.

Note

Ceci est utilisé par défaut par az cli pour authentifier les requêtes. Pour qu’il utilise les identifiants du principal Entra ID, précisez le paramètre --auth-mode login.

  • Il est possible de générer une shared key for blob, queue and file services en signant les informations suivantes :
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;
  • Il est possible de générer une clé partagée pour les services Table en signant les informations suivantes :
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
  • Il est possible de générer une lite shared key for blob, queue and file services en signant les informations suivantes :
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
  • Il est possible de générer une lite shared key for table services en signant les informations suivantes :
StringToSign = Date + "\n"
CanonicalizedResource

Ensuite, pour utiliser la clé, cela peut se faire dans l’en-tête Authorization en suivant la syntaxe :

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

Signature d’accès partagé (SAS)

Les Shared Access Signatures (SAS) sont des URL sécurisées et limitées dans le temps qui accordent des autorisations spécifiques d’accès aux ressources dans un compte Azure Storage sans exposer les clés d’accès du compte. Alors que les clés d’accès fournissent un accès administratif complet à toutes les ressources, les SAS permettent un contrôle granulaire en spécifiant des permissions (comme lecture ou écriture) et en définissant une date d’expiration.

SAS Types

  • User delegation SAS : Ceci est créé à partir d’un principal Entra ID qui signera le SAS et délèguera les permissions de l’utilisateur au SAS. Il ne peut être utilisé qu’avec blob and data lake storage (docs). Il est possible de révoquer tous les SAS délégués générés.
  • Même s’il est possible de générer un User delegation SAS avec des permissions « plus » que celles de l’utilisateur. Cependant, si le principal ne les possède pas, cela ne fonctionnera pas (pas de privesc).
  • Service SAS : Celui-ci est signé en utilisant l’une des clés d’accès du compte de stockage. Il peut être utilisé pour accorder l’accès à des ressources spécifiques dans un seul service de stockage. Si la clé est renouvelée, le SAS cessera de fonctionner.
  • Account SAS : Il est aussi signé avec l’une des clés d’accès du compte de stockage. Il accorde l’accès aux ressources à travers les services d’un compte de stockage (Blob, Queue, Table, File) et peut inclure des opérations au niveau du service.

Une URL SAS signée par une clé d’accès ressemble à ceci:

  • 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

Une URL SAS signée via user delegation ressemble à ceci:

  • 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

Notez quelques paramètres http :

  • Le paramètre se indique la date d’expiration du SAS
  • Le paramètre sp indique les permissions du SAS
  • Le sig est la signature validant le SAS

SAS permissions

Lors de la génération d’un SAS, il est nécessaire d’indiquer les permissions qu’il doit accorder. Selon l’objet sur lequel le SAS est généré, différentes permissions peuvent être incluses. Par exemple :

  • (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 supporte désormais le SSH File Transfer Protocol (SFTP), permettant le transfert et la gestion sécurisés de fichiers directement vers Blob Storage sans nécessiter de solutions personnalisées ou de produits tiers.

Key Features

  • Protocol Support : SFTP fonctionne avec les comptes Blob Storage configurés avec hierarchical namespace (HNS). Cela organise les blobs en répertoires et sous-répertoires pour une navigation facilitée.
  • Security : SFTP utilise des identités d’utilisateurs locaux pour l’authentification et ne s’intègre pas à RBAC ou ABAC. Chaque utilisateur local peut s’authentifier via :
    • Azure-generated passwords
    • Public-private SSH key pairs
  • Granular Permissions : Des permissions telles que Read, Write, Delete et List peuvent être assignées aux utilisateurs locaux pour jusqu’à 100 containers.
  • Networking Considerations : Les connexions SFTP s’effectuent via le port 22. Azure prend en charge des configurations réseau comme les firewalls, private endpoints ou virtual networks pour sécuriser le trafic SFTP.

Setup Requirements

  • Hierarchical Namespace : HNS doit être activé lors de la création du compte de stockage.
  • Supported Encryption : Nécessite des algorithmes cryptographiques approuvés par Microsoft Security Development Lifecycle (SDL) (ex. rsa-sha2-256, ecdsa-sha2-nistp256).
  • SFTP Configuration :
    • Enable SFTP on the storage account.
    • Create local user identities with appropriate permissions.
    • Configure home directories for users to define their starting location within the container.

Permissions

PermissionSymboleDescription
ReadrLire le contenu du fichier.
WritewTélécharger des fichiers et créer des répertoires.
ListlLister le contenu des répertoires.
DeletedSupprimer des fichiers ou des répertoires.
CreatecCréer des fichiers ou des répertoires.
Modify OwnershipoChanger l’utilisateur ou le groupe propriétaire.
Modify PermissionspModifier les ACL des fichiers ou des répertoires.

Enumeration

az cli enumeration ```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>Énumération 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")

Partages de fichiers

Az - File Shares

Escalade des privilèges

Az - Storage Privesc

Post-exploitation

Az - Blob Storage Post Exploitation

Persistance

Az - Storage Persistence

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks