Detection rules › Splunk
Okta Authentication Failed During MFA Challenge
The following analytic identifies failed authentication attempts during the Multi-Factor Authentication (MFA) challenge in an Okta tenant. It uses the Authentication datamodel to detect specific failed events where the authentication signature is user.authentication.auth_via_mfa. This activity is significant as it may indicate an adversary attempting to authenticate with compromised credentials on an account with MFA enabled. If confirmed malicious, this could suggest an ongoing attempt to bypass MFA protections, potentially leading to unauthorized access and further compromise of the affected account.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Resource Development | T1586.003 Compromise Accounts: Cloud Accounts |
| Initial Access | T1078.004 Valid Accounts: Cloud Accounts |
| Persistence | T1078.004 Valid Accounts: Cloud Accounts |
| Privilege Escalation | T1078.004 Valid Accounts: Cloud Accounts |
| Stealth | T1078.004 Valid Accounts: Cloud Accounts |
| Credential Access | T1621 Multi-Factor Authentication Request Generation |
Rule body splunk
name: Okta Authentication Failed During MFA Challenge
id: e2b99e7d-d956-411a-a120-2b14adfdde93
version: 11
creation_date: '2024-04-17'
modification_date: '2026-05-13'
author: Bhavin Patel, Splunk
status: production
type: TTP
description: The following analytic identifies failed authentication attempts during the Multi-Factor Authentication (MFA) challenge in an Okta tenant. It uses the Authentication datamodel to detect specific failed events where the authentication signature is `user.authentication.auth_via_mfa`. This activity is significant as it may indicate an adversary attempting to authenticate with compromised credentials on an account with MFA enabled. If confirmed malicious, this could suggest an ongoing attempt to bypass MFA protections, potentially leading to unauthorized access and further compromise of the affected account.
data_source:
- Okta
search: |-
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime values(Authentication.app) as app values(Authentication.reason) as reason values(Authentication.signature) as signature values(Authentication.method) as method FROM datamodel=Authentication
WHERE Authentication.signature=user.authentication.auth_via_mfa Authentication.action = failure
BY _time Authentication.src Authentication.user
Authentication.dest Authentication.action
| `drop_dm_object_name("Authentication")`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| iplocation src
| `okta_authentication_failed_during_mfa_challenge_filter`
how_to_implement: The analytic leverages Okta OktaIm2 logs to be ingested using the Splunk Add-on for Okta Identity Cloud (https://splunkbase.splunk.com/app/6553).
known_false_positives: A user may have accidentally entered the wrong credentials during the MFA challenge. If the user is new to MFA, they may have trouble authenticating. Ensure that the user is aware of the MFA process and has the correct credentials.
references:
- https://sec.okta.com/everythingisyes
- https://splunkbase.splunk.com/app/6553
drilldown_searches:
- name: View the detection results for - "$user$"
search: '%original_detection_search% | search user = "$user$"'
earliest_offset: $info_min_time$
latest_offset: $info_max_time$
- name: View risk events for the last 7 days for - "$user$"
search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
earliest_offset: 7d
latest_offset: "0"
finding:
title: A user [$user$] has failed to authenticate via MFA from IP Address - [$src$]"
entity:
field: user
type: user
score: 50
threat_objects:
- field: src
type: ip_address
analytic_story:
- Okta Account Takeover
- Scattered Lapsus$ Hunters
asset_type: Okta Tenant
mitre_attack_id:
- T1078.004
- T1586.003
- T1621
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
category: application
security_domain: identity
tests:
- name: True Positive Test
attack_data:
- data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1621/okta_mfa_login_failed/okta_mfa_login_failed.log
source: okta_log
sourcetype: OktaIM2:log
test_type: unit
Stages and Predicates
Stage 1: tstats
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime values(Authentication.app) as app values(Authentication.reason) as reason values(Authentication.signature) as signature values(Authentication.method) as method FROM datamodel=Authentication
WHERE Authentication.signature=user.authentication.auth_via_mfa Authentication.action = failure
BY _time Authentication.src Authentication.user
Authentication.dest Authentication.action
Stage 2: search
| `drop_dm_object_name("Authentication")`
Stage 3: search
| `security_content_ctime(firstTime)`
Stage 4: search
| `security_content_ctime(lastTime)`
Stage 5: search
| iplocation src
Stage 6: search
| `okta_authentication_failed_during_mfa_challenge_filter`
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
Authentication.action | eq |
|
Authentication.signature | eq |
|
Search terms
Bare-string tokens in the SPL search body. Splunk matches each token against _raw (the untyped raw event text) anywhere it appears, not against a specific field. These don't surface in the Indicators table because they aren't predicates on a known field.
| Stage | Term |
|---|---|
| 5 | iplocation |
| 5 | src |