Okta Successful Login After Credential Attack

Last updated 6 days ago on 2026-02-19
Created 13 days ago on 2026-02-12

About

Correlates Okta credential attack alerts with subsequent successful authentication for the same user account, identifying potential compromise following brute force, password spray, or credential stuffing attempts.
Tags
Domain: IdentityUse Case: Identity and Access AuditUse Case: Threat DetectionData Source: OktaData Source: Okta System LogsTactic: Credential AccessTactic: Initial AccessRule Type: Higher-Order RuleLanguage: esql
Severity
high
Risk Score
73
MITRE ATT&CK™

Credential Access (TA0006)(external, opens in a new tab or window)

Initial Access (TA0001)(external, opens in a new tab or window)

False Positive Examples
A user experiencing legitimate login issues (forgotten password, typos) may trigger credential attack alerts before successfully authenticating.Automated password reset flows where a user fails multiple times then succeeds after resetting their password.
License
Elastic License v2(external, opens in a new tab or window)

Definition

Integration Pack
Prebuilt Security Detection Rules
Related Integrations

okta(external, opens in a new tab or window)

Query
text code block:
FROM .alerts-security.*, logs-okta.system-* METADATA _id, _version, _index // Filter for credential attack alerts OR successful Okta authentications | WHERE ( // Credential attack alerts from the five correlated rules kibana.alert.rule.rule_id IN ( "94e734c0-2cda-11ef-84e1-f661ea17fbce", // Credential Stuffing "42bf698b-4738-445b-8231-c834ddefd8a0", // Password Spraying "23f18264-2d6d-11ef-9413-f661ea17fbce", // DT Brute Force "5889760c-9858-4b4b-879c-e299df493295", // Distributed Brute Force "2d3c27d5-d133-4152-8102-8d051619ec4a" // Distributed Spray ) ) OR ( // Successful Okta authentication events event.dataset == "okta.system" AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start") AND okta.outcome.result == "SUCCESS" AND okta.actor.alternate_id IS NOT NULL ) // correlation - alerts may store user/IP in different fields than raw logs | EVAL Esql.user = COALESCE(okta.actor.alternate_id, user.name, user.email), Esql.source_ip = COALESCE(okta.client.ip, client.ip, source.ip) // Must have user identity to correlate | WHERE Esql.user IS NOT NULL // Classify events and capture timestamps/IPs by event type | EVAL Esql.is_attack_alert = CASE( kibana.alert.rule.rule_id IN ( "94e734c0-2cda-11ef-84e1-f661ea17fbce", "42bf698b-4738-445b-8231-c834ddefd8a0", "23f18264-2d6d-11ef-9413-f661ea17fbce", "5889760c-9858-4b4b-879c-e299df493295", "2d3c27d5-d133-4152-8102-8d051619ec4a" ), 1, 0 ), Esql.is_success_login = CASE( event.dataset == "okta.system" AND okta.outcome.result == "SUCCESS", 1, 0 ), Esql.attack_ip = CASE( kibana.alert.rule.rule_id IN ( "94e734c0-2cda-11ef-84e1-f661ea17fbce", "42bf698b-4738-445b-8231-c834ddefd8a0", "23f18264-2d6d-11ef-9413-f661ea17fbce", "5889760c-9858-4b4b-879c-e299df493295", "2d3c27d5-d133-4152-8102-8d051619ec4a" ), Esql.source_ip, null ), Esql.login_ip = CASE( event.dataset == "okta.system" AND okta.outcome.result == "SUCCESS", Esql.source_ip, null ), Esql.attack_ts = CASE( kibana.alert.rule.rule_id IN ( "94e734c0-2cda-11ef-84e1-f661ea17fbce", "42bf698b-4738-445b-8231-c834ddefd8a0", "23f18264-2d6d-11ef-9413-f661ea17fbce", "5889760c-9858-4b4b-879c-e299df493295", "2d3c27d5-d133-4152-8102-8d051619ec4a" ), @timestamp, null ), Esql.login_ts = CASE( event.dataset == "okta.system" AND okta.outcome.result == "SUCCESS", @timestamp, null ) // Aggregate by user (catches IP rotation: spray from IP A, login from IP B) | STATS Esql.attack_count = SUM(Esql.is_attack_alert), Esql.login_count = SUM(Esql.is_success_login), Esql.earliest_attack = MIN(Esql.attack_ts), Esql.latest_attack = MAX(Esql.attack_ts), Esql.earliest_login = MIN(Esql.login_ts), Esql.latest_login = MAX(Esql.login_ts), Esql.attack_source_ips = VALUES(Esql.attack_ip), Esql.login_source_ips = VALUES(Esql.login_ip), Esql.all_source_ips = VALUES(Esql.source_ip), Esql.alert_rule_ids = VALUES(kibana.alert.rule.rule_id), Esql.alert_rule_names = VALUES(kibana.alert.rule.name), Esql.event_action_values = VALUES(event.action), Esql.geo_country_values = VALUES(client.geo.country_name), Esql.geo_city_values = VALUES(client.geo.city_name), Esql.source_asn_values = VALUES(source.as.number), Esql.source_asn_org_values = VALUES(source.as.organization.name), Esql.user_agent_values = VALUES(okta.client.user_agent.raw_user_agent), Esql.device_values = VALUES(okta.client.device), Esql.is_proxy_values = VALUES(okta.security_context.is_proxy) BY Esql.user // Calculate time gap between latest attack and earliest subsequent login | EVAL Esql.attack_to_login_minutes = DATE_DIFF("minute", Esql.latest_attack, Esql.earliest_login) // Correlation: attack BEFORE login + success within reasonable window (3 hours) | WHERE Esql.attack_count > 0 AND Esql.login_count > 0 AND Esql.latest_attack < Esql.earliest_login AND Esql.attack_to_login_minutes <= 180 | SORT Esql.login_count DESC | KEEP Esql.*

Install detection rules in Elastic Security

Detect Okta Successful Login After Credential Attack in the Elastic Security detection engine by installing this rule into your Elastic Stack.

To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).