# Az - File Shares

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

## Basic Information

**Azure Files** is a fully managed cloud file storage service that provides shared file storage accessible via standard **SMB (Server Message Block)** and **NFS (Network File System)** protocols. The main protocol used is SMB as NFS Azure file shares aren't supported for Windows (according to the [**docs**](https://learn.microsoft.com/en-us/azure/storage/files/files-nfs-protocol)). It allows you to create highly available network file shares that can be accessed simultaneously by multiple virtual machines (VMs) or on-premises systems, enabling seamless file sharing across environments.

### Access Tiers

- **Transaction Optimized**: Optimized for transaction-heavy operations.
- **Hot**: Balanced between transactions and storage.
- **Cool**: Cost-effective for storage.
- **Premium:** High-performance file storage optimized for low-latency and IOPS-intensive workloads.

### Backups

- **Daily backup**: A backup point is created each day at an indicated time (e.g. 19.30 UTC) and stored for from 1 to 200 days.
- **Weekly backup**: A backup point is created each week at an indicated day and time (Sunday at 19.30) and stored for from 1 to 200 weeks.
- **Monthly backup**: A backup point is created each month at an indicated day and time (e.g. first Sunday at 19.30) and stored for from 1 to 120 months.
- **Yearly backup**: A backup point is created each year at an indicated day and time (e.g. January first Sunday at 19.30) and stored for from 1 to 10 years.
- It's also possible to perform **manual backups and snapshots at any time**. Backups and snapshots are actually the same in this context.

### Supported Authentications via SMB

- **On-premises AD DS Authentication**: It uses on-premises Active Directory credentials synced with Microsoft Entra ID for identity-based access. It requires network connectivity to on-premises AD DS.
- **Microsoft Entra Domain Services Authentication**: It leverages Microsoft Entra Domain Services (cloud-based AD) to provide access using Microsoft Entra credentials.
- **Microsoft Entra Kerberos for Hybrid Identities**: It enables Microsoft Entra users to authenticate Azure file shares over the internet using Kerberos. It supports hybrid Microsoft Entra joined or Microsoft Entra joined VMs without requiring connectivity to on-premises domain controllers. But it does not support cloud-only identities.
- **AD Kerberos Authentication for Linux Clients**: It allows Linux clients to use Kerberos for SMB authentication via on-premises AD DS or Microsoft Entra Domain Services.

### Supported "Authentication" via NFS

- It supports 3 root squash configurations (Find more information about this in the [NFS HackTricks section](https://book.hacktricks.wiki/en/network-services-pentesting/nfs-service-pentesting.html?highlight=nfs#squashing)):
    - **Root squash**: The root user is mapped to the anonymous user.
    - **No root squash**: The root user is mapped to the root user.
    - **All squash**: All users are mapped to the anonymous user.
- You **must disabled "Secure transfer required"** at storage account level as NFS doesn't support encryption.
- You must give some kind of **private access to the NFS server as it doesn't support public access**. For example, you can create a **private endpoint** and expose it in a subnet of a virtual network inside the subscription.
    - The private endpoint will be exposed inside an IP address in the subnet **with the port 2059** open to access the NFS service.
    - It's possible to use nmap to discover the private endpoint.

## Enumeration

{{#tabs }}
{{#tab name="az" }}
```bash
# Get storage accounts
az storage account list #Get the account name from here

# List file shares
az storage share list --account-name <name>
az storage share-rm list --storage-account <name> # To see the deleted ones too --include-deleted
# Get dirs/files inside the share
az storage file list --account-name <name> --share-name <share-name>
## If type is "dir", you can continue enumerating files inside of it
az storage file list --account-name <name> --share-name <prev_dir/share-name>
# Download a complete share (with directories and files inside of them)
az storage file download-batch -d . --source <share-name> --account-name <name>
# List snapshots
az storage share snapshot --name <share-name>
# List file shares, including deleted ones
az rest --method GET \
  --url "https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{storageAccountName}/fileServices/default/shares?%24skipToken=&%24maxpagesize=20&%24filter=&%24expand=deleted&api-version=2019-06-01"

# Get snapshots/backups
az storage share list --account-name <name> --include-snapshots --query "[?snapshot != null]"
# List contents of a snapshot/backup
az storage file list --account-name <name> --share-name <share-name> --snapshot <snapshot-version> #e.g. "2024-11-25T11:26:59.0000000Z"
# Download snapshot/backup
az storage file download-batch -d . --account-name <name> --source <share-name> --snapshot <snapshot-version>

# Find private endpoints with NFS access with
sudo nmap -n -T5 -Pn -p 2049 --open <private-ip>/16
# Find if a share is mounted inside a VM with
mount | grep nfs
mount | grep "username="
```

{{#endtab }}

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

```bash
Get-AzStorageAccount

# List File Shares
Get-AzStorageShare -Context (Get-AzStorageAccount -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>").Context

# Get Directories/Files Inside the Share
Get-AzStorageFile -ShareName "<share-name>" -Context (Get-AzStorageAccount -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>").Context
Get-AzStorageFile -ShareName "<share-name>" -Path "<share-directory-path>" -Context (Get-AzStorageAccount -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>").Context

# Download a Complete Share
Get-AzStorageFileContent -ShareName "<share-name>" -Destination "C:\Download" -Path "<share-directory-path>" -Context (Get-AzStorageAccount -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>").Context

# Get Snapshots/Backups
Get-AzStorageShare -Context (Get-AzStorageAccount -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>").Context | Where-Object { $_.SnapshotTime -ne $null }

# List Contents of a Snapshot/Backup
Get-AzStorageFile -ShareName "<share-name>" -Context (New-AzStorageContext -StorageAccountName "<storage-account-name>" -StorageAccountKey (Get-AzStorageAccountKey -ResourceGroupName "<resource-group-name>" -Name "<storage-account-name>" | Select-Object -ExpandProperty Value) -SnapshotTime "<snapshot-version>")

```

{{#endtab }}
{{#endtabs }}

> [!NOTE]
> By default `az` cli will use an account key to sign a key and perform the action. To use the Entra ID principal privileges use the parameters `--auth-mode login --enable-file-backup-request-intent`.

> [!TIP]
> Use the param `--account-key` to indicate the account key to use\
> Use the param `--sas-token` with the SAS token to access via a SAS token

### Connection

These are the scripts proposed by Azure at the time of the writing to connect a File Share:

You need to replace the `<STORAGE-ACCOUNT>`, `<ACCESS-KEY>` and `<FILE-SHARE-NAME>` placeholders.

{{#tabs}}
{{#tab name="Windows"}}

```bash
$connectTestResult = Test-NetConnection -ComputerName filescontainersrdtfgvhb.file.core.windows.net -Port 445
if ($connectTestResult.TcpTestSucceeded) {
    # Save the password so the drive will persist on reboot
    cmd.exe /C "cmdkey /add:`"<STORAGE-ACCOUNT>.file.core.windows.net`" /user:`"localhost\<STORAGE-ACCOUNT>`" /pass:`"<ACCESS-KEY>`""
    # Mount the drive
    New-PSDrive -Name Z -PSProvider FileSystem -Root "\\<STORAGE-ACCOUNT>.file.core.windows.net\<FILE-SHARE-NAME>" -Persist
} else {
    Write-Error -Message "Unable to reach the Azure storage account via port 445. Check to make sure your organization or ISP is not blocking port 445, or use Azure P2S VPN, Azure S2S VPN, or Express Route to tunnel SMB traffic over a different port."
}
```

{{#endtab}}

{{#tab name="Linux"}}

```bash
sudo mkdir /mnt/<FILE-SHARE-NAME>
if [ ! -d "/etc/smbcredentials" ]; then
sudo mkdir /etc/smbcredentials
fi
if [ ! -f "/etc/smbcredentials/<STORAGE-ACCOUNT>.cred" ]; then
    sudo bash -c 'echo "username=<STORAGE-ACCOUNT>" >> /etc/smbcredentials/<STORAGE-ACCOUNT>.cred'
    sudo bash -c 'echo "password=<ACCESS-KEY>" >> /etc/smbcredentials/<STORAGE-ACCOUNT>.cred'
fi
sudo chmod 600 /etc/smbcredentials/<STORAGE-ACCOUNT>.cred

sudo bash -c 'echo "//<STORAGE-ACCOUNT>.file.core.windows.net/<FILE-SHARE-NAME> /mnt/<FILE-SHARE-NAME> cifs nofail,credentials=/etc/smbcredentials/<STORAGE-ACCOUNT>.cred,dir_mode=0777,file_mode=0777,serverino,nosharesock,actimeo=30" >> /etc/fstab'
sudo mount -t cifs //<STORAGE-ACCOUNT>.file.core.windows.net/<FILE-SHARE-NAME> /mnt/<FILE-SHARE-NAME> -o credentials=/etc/smbcredentials/<STORAGE-ACCOUNT>.cred,dir_mode=0777,file_mode=0777,serverino,nosharesock,actimeo=30
```

{{#endtab}}

{{#tab name="macOS"}}

```bash
open smb://<STORAGE-ACCOUNT>:<ACCESS-KEY>@<STORAGE-ACCOUNT>.file.core.windows.net/<FILE-SHARE-NAME>
```

{{#endtab}}
{{#endtabs}}

### Regular storage enumeration (access keys, SAS...)

{{#ref}}
az-storage.md
{{#endref}}

## Privilege Escalation

Same as storage privesc:

{{#ref}}
../az-privilege-escalation/az-storage-privesc.md
{{#endref}}

## Post Exploitation

{{#ref}}
../az-post-exploitation/az-file-share-post-exploitation.md
{{#endref}}

## Persistence

Same as storage persistence:

{{#ref}}
../az-persistence/az-storage-persistence.md
{{#endref}}

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



