Spare Key

  Challenge Progession:
Act I
Difficulty:
  Location:
Dosis Neighborhood
Spare Key
More AZ CLI

This challenge is located next to the Blob Storage Challenge south of the frozen pond. Find the goose Barry to get started. Barry explains that the Neighborhood HOA hosts a static website on Azure where an admin accidentally uploaded a sensitive key. It is up to us to find the leak. Click the terminal to get dropped into an AZ CLI environment.

AZ CLI Investigation

Step one is to list all of the resource groups. We can add the "-o table" option to print the output in a more readable table format.

neighbor@ad75cee5ecfa:~$ az group list -o table
Name                 Location    ProvisioningState
-------------------  ----------  -------------------
rg-the-neighborhood  eastus      Succeeded
rg-hoa-maintenance   eastus      Succeeded
rg-hoa-clubhouse     eastus      Succeeded
rg-hoa-security      eastus      Succeeded
rg-hoa-landscaping   eastus      Succeeded
There are 5 resource groups in our tenant. The next step is to list the storage accounts in our tenant as well.
neighbor@ad75cee5ecfa:~$ az storage account list --resource-group rg-the-neighborhood -o table
Name             Kind         Location    ResourceGroup        ProvisioningState
---------------  -----------  ----------  -------------------  -------------------
neighborhoodhoa  StorageV2    eastus      rg-the-neighborhood  Succeeded
hoamaintenance   StorageV2    eastus      rg-hoa-maintenance   Succeeded
hoaclubhouse     StorageV2    eastus      rg-hoa-clubhouse     Succeeded
hoasecurity      BlobStorage  eastus      rg-hoa-security      Succeeded
hoalandscaping   StorageV2    eastus      rg-hoa-landscaping   Succeeded
There are 5 storage accounts in the tenant. Barry mentioned a static website hosted here by the Neighborhood HOA. One of the storage accounts is "neighborhoodhoa". Lets list the sites for that account.
neighbor@ad75cee5ecfa:~$ az storage blob service-properties show --account-name neighborhoodhoa --auth-mode login
{
  "enabled": true,
  "errorDocument404Path": "404.html",
  "indexDocument": "index.html"
}
The next step is to list the containers associated with that storage account.
neighbor@ad75cee5ecfa:~$ az storage container list --account-name neighborhoodhoa --auth-mode login
[
  {
    "name": "$web",
    "properties": {
      "lastModified": "2025-09-20T10:30:00Z",
      "publicAccess": null
    }
  },
  {
    "name": "public",
    "properties": {
      "lastModified": "2025-09-15T14:20:00Z",
      "publicAccess": "Blob"
    }
  }
]
There are two containers: public and $web. We can list the files for these sites using the az cli. The terminal tells us to be on the lookout for files that should not be public! Lets list the files for the "public" container.
neighbor@ad75cee5ecfa:~$ az storage blob list --account-name neighborhoodhoa --auth-mode login --container-name 'public' -o table
Name                          ContentLength    ContentType
----------------------------  ---------------  ----------------
hoa-calendar.json             256              application/json
forms/request-guidelines.txt  128              text/plain
Next list the files of the $web container.
neighbor@ad75cee5ecfa:~$ az storage blob list --account-name neighborhoodhoa --auth-mode login --container-name '$web' -o table
Name                  ContentLength    ContentType
--------------------  ---------------  -------------
index.html            512              text/html
about.html            384              text/html
iac/terraform.tfvars  1024             text/plain
There is a file here that is an infrastructure-as-code (IaC) configuration file for Terraform. Typically, tfvars files are used to assign values to inputs defined in your Terraform configs. The files can very well contain sensitive information. To be sure, lets print the contents of that file to the terminal.
neighbor@ad75cee5ecfa:~$ az storage blob download --account-name neighborhoodhoa --auth-mode login --container-name '$web' --name 'iac/terraform.tfvars' --file /dev/stdout | less
Sensitive File Contents:
# Terraform Variables for HOA Website Deployment
# Application: Neighborhood HOA Service Request Portal  
# Environment: Production
# Last Updated: 2025-09-20
# DO NOT COMMIT TO PUBLIC REPOS

# === Application Configuration ===
app_name = "hoa-service-portal"
app_version = "2.1.4"
environment = "production"

# === Database Configuration ===
database_server = "sql-neighborhoodhoa.database.windows.net"
database_name = "hoa_requests"
database_username = "hoa_app_user"
# Using Key Vault reference for security
database_password_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/db-password/)"

# === Storage Configuration for File Uploads ===
storage_account = "neighborhoodhoa"
uploads_container = "resident-uploads"
documents_container = "hoa-documents"

# TEMPORARY: Direct storage access for migration script
# WARNING: Remove after data migration to new storage account
# This SAS token provides full access - HIGHLY SENSITIVE!
migration_sas_token = "sv=2023-11-03&ss=b&srt=co&sp=rlacwdx&se=2100-01-01T00:00:00Z&spr=https&sig=1djO1Q%2Bv0wIh7mYi3n%2F7r1d%2F9u9H%2F5%2BQxw8o2i9QMQc%3D"

# === Email Service Configuration ===
# Using Key Vault for sensitive email credentials
sendgrid_api_key_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/sendgrid-key/)"
from_email = "noreply@theneighborhood.com" 
admin_email = "admin@theneighborhood.com"

# === Application Settings ===
session_timeout_minutes = 60
max_file_upload_mb = 10
allowed_file_types = ["pdf", "jpg", "jpeg", "png", "doc", "docx"]

# === Feature Flags ===
enable_online_payments = true
enable_maintenance_requests = true
enable_document_portal = false
enable_resident_directory = true

# === API Keys (Key Vault References) ===
maps_api_key_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/maps-api-key/)"
weather_api_key_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/weather-api-key/)"

# === Notification Settings (Key Vault References) ===
sms_service_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/sms-credentials/)"
notification_webhook_vault_ref = "@Microsoft.KeyVault(SecretUri=https://kv-neighborhoodhoa-prod.vault.azure.net/secrets/slack-webhook/)"

# === Deployment Configuration ===
deploy_static_files_to_cdn = true
cdn_profile = "hoa-cdn-prod"
cache_duration_hours = 24

# Backup schedule
backup_frequency = "daily"
backup_retention_days = 30
There is a migration_sas_token in there that provides full access and is long lived (expires in year 2100)!
# This SAS token provides full access - HIGHLY SENSITIVE!
migration_sas_token = "sv=2023-11-03&ss=b&srt=co&sp=rlacwdx&se=2100-01-01T00:00:00Z&spr=https&sig=1djO1Q%2Bv0wIh7mYi3n%2F7r1d%2F9u9H%2F5%2BQxw8o2i9QMQc%3D"
With the leak found, type "finish" in the terminal to complete the challenge!
Victory!