Detect Multi-Factor Authentication Request Generation in Splunk
This detection identifies MFA fatigue attacks where adversaries possessing valid credentials repeatedly trigger MFA push notifications, SMS codes, or phone calls to overwhelm target users into approving fraudulent authentication requests. The detection monitors Azure AD and identity provider sign-in logs for abnormally high volumes of MFA challenge events against a single account within a short time window, with elevated severity when a successful authentication follows the bombardment — a pattern consistent with documented TTPs from APT29, Scattered Spider, and LAPSUS$. The technique may also abuse Self-Service Password Reset (SSPR) flows to generate MFA requests without initially possessing valid credentials.
MITRE ATT&CK
- Tactic
- Credential Access
- Canonical reference
- https://attack.mitre.org/techniques/T1621/
SPL Detection Query
index=* sourcetype IN ("azure:aad:signin", "azure:monitor:aad:signinlogs")
| eval error_code=coalesce('properties.status.errorCode', errorCode, "")
| eval failure_reason=lower(coalesce('properties.status.failureReason', failureReason, ""))
| eval mfa_interrupt=if(
match(error_code, "50074|50076|50158|500121|50072|53003")
OR match(failure_reason, "mfa|multi-factor|strong auth"),
1, 0)
| where mfa_interrupt=1
| eval user=coalesce('properties.userPrincipalName', userPrincipalName)
| eval src_ip=coalesce('properties.ipAddress', ipAddress)
| eval app=coalesce('properties.appDisplayName', appDisplayName)
| eval event_epoch=if(isnum(_time), _time, strptime(coalesce('properties.createdDateTime', ""), "%Y-%m-%dT%H:%M:%S"))
| bin _time span=1h
| stats
count as mfa_attempts,
dc(src_ip) as unique_ips,
values(src_ip) as ip_list,
min(event_epoch) as first_attempt_epoch,
max(event_epoch) as last_attempt_epoch,
values(app) as targeted_apps
by user, _time
| where mfa_attempts >= 5
| eval duration_mins=round((last_attempt_epoch - first_attempt_epoch) / 60, 1)
| eval first_attempt=strftime(first_attempt_epoch, "%Y-%m-%d %H:%M:%S")
| eval last_attempt=strftime(last_attempt_epoch, "%Y-%m-%d %H:%M:%S")
| eval risk_level=case(mfa_attempts >= 15, "Critical", mfa_attempts >= 10, "High", true(), "Medium")
| table _time, user, mfa_attempts, unique_ips, ip_list, duration_mins, first_attempt, last_attempt, targeted_apps, risk_level
| sort -mfa_attempts Detects MFA fatigue campaigns by aggregating Azure AD sign-in events with known MFA interrupt error codes via the Microsoft Azure Add-on for Splunk, bucketing per user per hour, and alerting when a single account receives 5+ MFA challenges within one hour. Risk level escalates to Critical at 15+ attempts. Works with data ingested via the Microsoft Azure Add-on (azure:aad:signin sourcetype).
Data Sources
Required Sourcetypes
False Positives & Tuning
- Users with persistent browser or app sessions that repeatedly request MFA on each sub-request due to aggressive Conditional Access policy configuration
- Service accounts using delegated authentication with misconfigured MFA requirements that trigger repeated 50076 events during automated workflows
- Users in regions with poor mobile coverage who receive and must retry MFA push notifications multiple times before approval registers
- Shared accounts accessed by multiple staff members simultaneously, each triggering separate MFA prompts that aggregate above threshold
Other platforms for T1621
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1MFA Fatigue via Python MSAL Repeated Authentication Requests
Expected signal: Azure AD SigninLogs generates 10 entries for [email protected] with ResultType 50076 or 50158 within a 60-second window, all from the test machine's egress IP. If user approves, a ResultType 0 entry appears.
- Test 2MFA Bombardment via Azure AD Token Endpoint curl Loop
Expected signal: Azure AD SigninLogs shows 10 entries for [email protected] with ResultType 50076 or 500121, all with identical IPAddress (test machine egress IP), within 30 seconds. UserAgent field shows curl version string.
- Test 3Okta MFA Bombing via Okta Authentication API
Expected signal: Okta System Log generates policy.auth.mfa.push.sent events for [email protected], 8 events within 40 seconds. In Splunk: sourcetype=okta:im2:log eventType=policy.auth.mfa.push.sent target{}[email protected]
References (6)
- https://attack.mitre.org/techniques/T1621/
- https://www.cisa.gov/sites/default/files/publications/fact-sheet-implement-number-matching-in-mfa-applications-508c.pdf
- https://www.obsidiansecurity.com/blog/account-takeover-through-sspr-abuse/
- https://portswigger.net/daily-swig/mfa-fatigue-attacks-users-tricked-into-allowing-device-access
- https://www.crowdstrike.com/blog/scattered-spider-attempts-to-avoid-detection-with-bring-your-own-vulnerable-driver-tactic/
- https://www.microsoft.com/en-us/security/blog/2022/10/25/microsoft-mitigates-lapsus-attacks-via-mfa-policy/
Unlock Pro Content
Get the full detection package for T1621 including response playbook, investigation guide, and atomic red team tests.