Rules/MFA-003.admins-phishing-resistant.psd1
|
@{ Id = 'MFA-003' Title = 'Administrators use phishing-resistant authentication methods' Area = 'MfaRegistration' Severity = 'High' References = @( 'https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths' ) Rationale = 'Push/OTP MFA still falls to real-time phishing and fatigue attacks. For admin accounts the bar is passkeys, FIDO2 or Windows Hello for Business.' Remediation = 'Register a phishing-resistant method (passkey, FIDO2 key, Windows Hello for Business) for every admin and enforce it via an authentication strength in Conditional Access.' Test = { param($Snapshot) # Exclude directory-sync service accounts - they never sign in interactively. $syncUpns = Get-TLSyncAccountUpn -Snapshot $Snapshot $admins = @($Snapshot.MfaRegistration.users | Where-Object { $_.isAdmin -and -not $syncUpns.Contains([string]$_.userPrincipalName) }) if ($admins.Count -eq 0) { return New-TLRuleResult -Status Manual -Evidence 'No interactive admin entries in the registration report - review manually.' } $phishingResistantPattern = '(?i)(fido2|passKey|windowsHelloForBusiness|certificate)' $weakAdmins = @($admins | Where-Object { @($_.methodsRegistered | Where-Object { $_ -match $phishingResistantPattern }).Count -eq 0 }) if ($weakAdmins.Count -gt 0) { New-TLRuleResult -Status Fail -Evidence @($weakAdmins | Select-Object -First 10 | ForEach-Object { "{0}: {1}" -f $_.userPrincipalName, $(if (@($_.methodsRegistered).Count -gt 0) { @($_.methodsRegistered) -join ', ' } else { 'no methods registered' }) }) } else { New-TLRuleResult -Status Pass -Evidence ("All {0} interactive admins have a phishing-resistant method registered." -f $admins.Count) } } } |