Holiday Hack 2025: Blob Storage Challenge in the Neighborhood
Introduction
Blob Storage Challenge in the Neighborhood
Difficulty:❅❅❅❅❅Grace the Goose is over by the frozen lake with a cranberry-pi:
Grace
HONK!!! HONK!!!!
The Neighborhood HOA uses Azure storage accounts for various IT operations.
You’ve been asked to audit their storage security configuration to ensure no sensitive data is publicly accessible.
Recent security reports suggest some storage accounts might have public blob access enabled, creating potential data exposure risks.
The Storage Secrets terminal opens up a terminal with two panes. The top pane has instructions, and the bottom a place to interact:
Solution
Background
Azure Blob Storage is Microsoft’s object storage solution, similar to AWS S3. The hierarchy works like this:
- Subscription - The billing/management boundary
- Resource Group - A logical container for related resources
- Storage Account - A namespace for storage services (blobs, files, queues, tables)
- Container - Similar to a folder, holds blobs
- Blob - The actual file/object
A critical security setting is allowBlobPublicAccess at the storage account level. When enabled, individual containers can be configured to allow anonymous access - meaning anyone on the internet can read the files without authentication.
#1
You may not know this but the Azure cli help messages are very easy to access. First, try typing: $
az help | less
To complete this, I just need to run the given command, az help | less. az is the command line tool for interactign with Azure cloud. This opens the help output:
#2
Next, you’ve already been configured with credentials. 🔑
$
az account show \| less
- Pipe the output to | less so you can scroll.
- Press ‘q’ to exit less.
Running the given command (minus the less, not needed here) shows the user I’m logged in as:
neighbor@2f4d0caec829:~$ az account show
{
"environmentName": "AzureCloud",
"id": "2b0942f3-9bca-484b-a508-abdae2db5e64",
"isDefault": true,
"name": "theneighborhood-sub",
"state": "Enabled",
"tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
"user": {
"name": "theneighborhood@theneighborhood.invalid",
"type": "user"
}
}
I’m running as theneighborhood@theneighborhood.invalid. This data is also cached in the .azure directory in the current user’s home directory:
neighbor@2f4d0caec829:~$ cat .azure/azureProfile.json
{
"subscriptions": [
{
"id": "2b0942f3-9bca-484b-a508-abdae2db5e64",
"name": "theneighborhood-sub",
"state": "Enabled",
"user": {
"name": "theneighborhood@theneighborhood.invalid",
"type": "user"
},
"isDefault": true,
"tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
"environmentName": "AzureCloud"
}
],
"installationId": "1de3b9db-5e5b-48a5-81e5-7eafe2d2bace"
If I move that file, I’m no longer logged in:
neighbor@2f4d0caec829:~$ mv .azure/azureProfile.json{,.bk}
neighbor@2f4d0caec829:~$ az account show
Please run 'az login' to setup account.
neighbor@2f4d0caec829:~$ mv .azure/azureProfile.json{.bk,}
#3
Now that you’ve run a few commands, Let’s take a look at some Azure storage accounts. Try:
az storage account list | lessFor more information: https://learn.microsoft.com/en-us/cli/azure/storage/account?view=azure-cli-latest
A storage account is Azure’s top-level namespace for data storage. Each account can contain multiple containers, and each container holds blobs (files). The id field in the output shows the full Azure Resource Manager (ARM) path: subscription → resource group → provider → resource.
This command outputs a lot of data. I’ll use jq to parse the JSON data and show bits at a time. It’s a list with 6 items:
neighbor@2f4d0caec829:~$ az storage account list | jq '.|length'
6
For example, the first one looks like:
neighbor@2f4d0caec829:~$ az storage account list | jq .[0]
{
"id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/theneighborhood-rg1/providers/Microsoft.Storage/storageAccounts/neighborhood1",
"kind": "StorageV2",
"location": "eastus",
"name": "neighborhood1",
"properties": {
"accessTier": "Hot",
"allowBlobPublicAccess": false,
"encryption": {
"keySource": "Microsoft.Storage",
"services": {
"blob": {
"enabled": true
}
}
},
"minimumTlsVersion": "TLS1_2"
},
"resourceGroup": "theneighborhood-rg1",
"sku": {
"name": "Standard_LRS"
},
"tags": {
"env": "dev"
}
}
They have names neighborhood1 - neighborhood6:
neighbor@2f4d0caec829:~$ az storage account list | jq -r .[].name
neighborhood1
neighborhood2
neighborhood3
neighborhood4
neighborhood5
neighborhood6
Looking at the properties of each account, the second one jumps out as potentially having a security issue:
neighbor@38c41877bb80:~$ az storage account list | jq '.[1]'
{
"id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/theneighborhood-rg1/providers/Microsoft.Storage/storageAccounts/neighborhood2",
"kind": "StorageV2",
"location": "eastus2",
"name": "neighborhood2",
"properties": {
"accessTier": "Cool",
"allowBlobPublicAccess": true,
"encryption": {
"keySource": "Microsoft.Storage",
"services": {
"blob": {
"enabled": false
}
}
},
"minimumTlsVersion": "TLS1_0"
},
"resourceGroup": "theneighborhood-rg1",
"sku": {
"name": "Standard_GRS"
},
"tags": {
"owner": "Admin"
}
}
allowBlobPublicAccess is set to true. This could be ok if it is meant to host files for the public, but it’s worth investigating further.
#4
hmm… one of these looks suspicious 🚨, i think there may be a misconfiguration here somewhere. Try showing the account that has a common misconfiguration:
az storage account show --name xxxxxxxxxx | less
Running az storage account show --name neighborhood2 shows the same information, but it does show the challenge that I’m focused on the correct account:
neighbor@38c41877bb80:~$ az storage account show --name neighborhood2
{
"id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/theneighborhood-rg1/providers/Microsoft.Storage/storageAccounts/neighborhood2",
"name": "neighborhood2",
"location": "eastus2",
"kind": "StorageV2",
"sku": {
"name": "Standard_GRS"
},
"properties": {
"accessTier": "Cool",
"allowBlobPublicAccess": true,
"minimumTlsVersion": "TLS1_0",
"encryption": {
"services": {
"blob": {
"enabled": false
}
},
"keySource": "Microsoft.Storage"
}
},
"resourceGroup": "theneighborhood-rg1",
"tags": {
"owner": "Admin"
}
}
#5
Now we need to list containers in neighborhood2. After running the command what’s interesting in the list? For more information: https://learn.microsoft.com/en-us/cli/azure/storage/container?view=azure-cli-latest#az-storage-container-list
I’ll run the az storage container list command with the --account-name flag to get containers associated with this account:
neighbor@38c41877bb80:~$ az storage container list --account-name neighborhood2
[
{
"name": "public",
"properties": {
"lastModified": "2024-01-15T09:00:00Z",
"publicAccess": "Blob"
}
},
{
"name": "private",
"properties": {
"lastModified": "2024-02-05T11:12:00Z",
"publicAccess": null
}
}
]
There are two containers. The publicAccess property controls anonymous access:
"Blob"- Anyone can read blobs if they know the URL (but can’t list the container)"Container"- Anyone can list and read all blobsnull- No anonymous access (authentication required)
The “public” container with publicAccess: "Blob" means files are accessible to anyone who knows the URL.
#6
Let’s take a look at the blob list in the public container for neighborhood2. For more information: https://learn.microsoft.com/en-us/cli/azure/storage/blob?view=azure-cli-latest#az-storage-blob-list
I’ll give the az storage blob list command both the container name and the account name:
neighbor@38c41877bb80:~$ az storage blob list --container-name public --account-name neighborhood2
[
{
"name": "refrigerator_inventory.pdf",
"properties": {
"contentLength": 45678,
"contentType": "application/pdf",
"metadata": {
"created_by": "NeighborhoodWatch",
"document_type": "inventory",
"last_updated": "2024-12-15"
}
}
},
{
"name": "admin_credentials.txt",
"properties": {
"contentLength": 1024,
"contentType": "text/plain",
"metadata": {
"note": "admins only"
}
}
},
{
"name": "network_config.json",
"properties": {
"contentLength": 2048,
"contentType": "application/json",
"metadata": {
"encrypted": "false",
"environment": "prod"
}
}
}
]
There are three files. Two of these (admin_credentials.txt and network_config.json) clearly shouldn’t be in a publicly accessible container. This is exactly the kind of misconfiguration that leads to data breaches.
#7
Try downloading and viewing the blob file named admin_credentials.txt from the public container. 💡 hint:
--file /dev/stdoutshould print in the terminal. Dont forget to use| less!
The documentation for az shows a download command:
neighbor@38c41877bb80:~$ az storage blob download -c public -n admin_credentials.txt --file /dev/stdout
# You have discovered an Azure Storage account with "allowBlobPublicAccess": true.
# This misconfiguration allows ANYONE on the internet to view and download files
# from the blob container without authentication.
# Public blob access is highly insecure when sensitive data (like admin credentials)
# is stored in these containers. Always disable public access unless absolutely required.
Azure Portal Credentials
User: azureadmin
Pass: AzUR3!P@ssw0rd#2025
Windows Server Credentials
User: administrator
Pass: W1nD0ws$Srv!@42
SQL Server Credentials
User: sa
Pass: SqL!P@55#2025$
Active Directory Domain Admin
User: corp\administrator
Pass: D0m@in#Adm!n$765
Exchange Admin Credentials
User: exchangeadmin
Pass: Exch@ng3!M@il#432
VMware vSphere Credentials
User: vsphereadmin
Pass: VMW@r3#Clu$ter!99
Network Switch Credentials
User: netadmin
Pass: N3t!Sw!tch$C0nfig#
Firewall Admin Credentials
User: fwadmin
Pass: F1r3W@ll#S3cur3!77
Backup Server Credentials
User: backupadmin
Pass: B@ckUp!Srv#2025$
Monitoring System Admin
User: monitoradmin
Pass: M0n!t0r#Sys$P@ss!
SharePoint Admin Credentials
User: spadmin
Pass: Sh@r3P0!nt#Adm!n2025
Git Server Admin
User: gitadmin
Pass: G1t#Srv!Rep0$C0de
That’s a lot of passwords!
Outro
On completing question 7, the banner says:
🎊 Great, you found the misconfiguration allowing public access to sensitive information!
✅ Challenge Complete! To finish, type: finish
Running finish completes the challenge.
Storage Secrets
Congratulations! You have completed the Storage Secrets challenge!
Grace seems annoyed in a goose-like manner:
Grace
HONK HONK HONK! ‘No sensitive data publicly accessible’ they claimed. Meanwhile, literally everything was public! Good save, security expert!