MFA Fatigue OKTA
Id | c2697b81-7fe9-4f57-ba1d-de46c6f91f9c |
Rulename | MFA Fatigue (OKTA) |
Description | MFA fatigue attack is a cybersecurity threat where attackers exploit user exhaustion from multi-factor authentication prompts to trick them into providing their MFA details thus compromising their own security. The query identifies MFA fatigue attempts in the Okta data. Ref: https://sec.okta.com/everythingisyes. |
Severity | Medium |
Tactics | CredentialAccess |
Techniques | T1621 |
Required data connectors | OktaSSO OktaSSOv2 |
Kind | Scheduled |
Query frequency | 1h |
Query period | 1h |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta Single Sign-On/Analytic Rules/MFAFatigue.yaml |
Version | 1.1.0 |
Arm template | c2697b81-7fe9-4f57-ba1d-de46c6f91f9c.json |
let PushThreshold = 10;
OktaSSO
| where ((eventType_s =="user.authentication.auth_via_mfa" and debugContext_debugData_factor_s == "OKTA_VERIFY_PUSH") or eventType_s == "system.push.send_factor_verify_push" or eventType_s == "user.mfa.okta_verify.deny_push")
| summarize IPAddress = make_set(client_ipAddress_s,100), City = make_set(client_geographicalContext_city_s,100),
successes = countif(eventType_s == "user.authentication.auth_via_mfa"),
denies = countif(eventType_s == "user.mfa.okta_verify.deny_push"),
pushes = countif(eventType_s == "system.push.send_factor_verify_push") by TimeGenerated, authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s
| summarize lasttime = max(TimeGenerated), firsttime = min(TimeGenerated),
successes = sum(successes), failures = sum(denies), pushes = sum(pushes) by authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s
| extend seconds = lasttime - firsttime
| where pushes > (PushThreshold)
| extend totalattempts = successes + failures
| extend finding = case(
failures == pushes and pushes > 1, "Authentication attempts not successful because multiple pushes denied",
totalattempts == 0, "Multiple pushes sent and ignored",
successes > 0 and pushes > 3, "Multiple pushes sent, eventual successful authentication!",
"Normal authentication pattern")
relevantTechniques:
- T1621
name: MFA Fatigue (OKTA)
requiredDataConnectors:
- dataTypes:
- Okta_CL
connectorId: OktaSSO
- dataTypes:
- OktaSSO
connectorId: OktaSSOv2
entityMappings:
- fieldMappings:
- identifier: Name
columnName: actor_alternateId_s
- identifier: DisplayName
columnName: actor_displayName_s
entityType: Account
triggerThreshold: 0
id: c2697b81-7fe9-4f57-ba1d-de46c6f91f9c
tactics:
- CredentialAccess
version: 1.1.0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta Single Sign-On/Analytic Rules/MFAFatigue.yaml
queryPeriod: 1h
kind: Scheduled
queryFrequency: 1h
severity: Medium
status: Available
description: |
'MFA fatigue attack is a cybersecurity threat where attackers exploit user exhaustion from multi-factor authentication prompts to trick them into providing their MFA details thus compromising their own security. The query identifies MFA fatigue attempts in the Okta data.
Ref: https://sec.okta.com/everythingisyes.'
query: |
let PushThreshold = 10;
OktaSSO
| where ((eventType_s =="user.authentication.auth_via_mfa" and debugContext_debugData_factor_s == "OKTA_VERIFY_PUSH") or eventType_s == "system.push.send_factor_verify_push" or eventType_s == "user.mfa.okta_verify.deny_push")
| summarize IPAddress = make_set(client_ipAddress_s,100), City = make_set(client_geographicalContext_city_s,100),
successes = countif(eventType_s == "user.authentication.auth_via_mfa"),
denies = countif(eventType_s == "user.mfa.okta_verify.deny_push"),
pushes = countif(eventType_s == "system.push.send_factor_verify_push") by TimeGenerated, authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s
| summarize lasttime = max(TimeGenerated), firsttime = min(TimeGenerated),
successes = sum(successes), failures = sum(denies), pushes = sum(pushes) by authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s
| extend seconds = lasttime - firsttime
| where pushes > (PushThreshold)
| extend totalattempts = successes + failures
| extend finding = case(
failures == pushes and pushes > 1, "Authentication attempts not successful because multiple pushes denied",
totalattempts == 0, "Multiple pushes sent and ignored",
successes > 0 and pushes > 3, "Multiple pushes sent, eventual successful authentication!",
"Normal authentication pattern")
triggerOperator: gt
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/c2697b81-7fe9-4f57-ba1d-de46c6f91f9c')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/c2697b81-7fe9-4f57-ba1d-de46c6f91f9c')]",
"properties": {
"alertRuleTemplateName": "c2697b81-7fe9-4f57-ba1d-de46c6f91f9c",
"customDetails": null,
"description": "'MFA fatigue attack is a cybersecurity threat where attackers exploit user exhaustion from multi-factor authentication prompts to trick them into providing their MFA details thus compromising their own security. The query identifies MFA fatigue attempts in the Okta data. \n Ref: https://sec.okta.com/everythingisyes.'\n",
"displayName": "MFA Fatigue (OKTA)",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "actor_alternateId_s",
"identifier": "Name"
},
{
"columnName": "actor_displayName_s",
"identifier": "DisplayName"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Okta Single Sign-On/Analytic Rules/MFAFatigue.yaml",
"query": "let PushThreshold = 10;\nOktaSSO\n| where ((eventType_s ==\"user.authentication.auth_via_mfa\" and debugContext_debugData_factor_s == \"OKTA_VERIFY_PUSH\") or eventType_s == \"system.push.send_factor_verify_push\" or eventType_s == \"user.mfa.okta_verify.deny_push\") \n| summarize IPAddress = make_set(client_ipAddress_s,100), City = make_set(client_geographicalContext_city_s,100),\n successes = countif(eventType_s == \"user.authentication.auth_via_mfa\"),\n denies = countif(eventType_s == \"user.mfa.okta_verify.deny_push\"),\n pushes = countif(eventType_s == \"system.push.send_factor_verify_push\") by TimeGenerated, authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s \n| summarize lasttime = max(TimeGenerated), firsttime = min(TimeGenerated),\n successes = sum(successes), failures = sum(denies), pushes = sum(pushes) by authenticationContext_externalSessionId_s, actor_alternateId_s,actor_displayName_s, outcome_result_s \n| extend seconds = lasttime - firsttime\n| where pushes > (PushThreshold)\n| extend totalattempts = successes + failures\n| extend finding = case(\n failures == pushes and pushes > 1, \"Authentication attempts not successful because multiple pushes denied\",\n totalattempts == 0, \"Multiple pushes sent and ignored\",\n successes > 0 and pushes > 3, \"Multiple pushes sent, eventual successful authentication!\",\n \"Normal authentication pattern\")\n",
"queryFrequency": "PT1H",
"queryPeriod": "PT1H",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CredentialAccess"
],
"techniques": [
"T1621"
],
"templateVersion": "1.1.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}