From 8d91426d0c86f928abe4271afdafd6fe7b5ee666 Mon Sep 17 00:00:00 2001 From: Michael Haag <5632822+MHaggis@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:40:06 -0600 Subject: [PATCH 1/3] OktaUnited --- ...h_invalid_credentials_from_the_same_ip.yml | 37 ++++++----- .../application/okta_account_locked_out.yml | 52 +++++++++++++++ .../okta_account_lockout_events.yml | 29 +++++---- .../application/okta_failed_sso_attempts.yml | 27 ++++---- .../application/okta_mfa_exhaustion_hunt.yml | 63 +++++++++++++++++++ .../okta_new_api_token_created.yml | 59 +++++++++++++++++ .../okta_new_device_enrolled_on_account.yml | 55 ++++++++++++++++ .../okta_suspicious_activity_reported.yml | 55 ++++++++++++++++ .../okta_threatinsight_threat_detected.yml | 60 ++++++++++++++++++ .../okta_two_or_more_rejected_okta_pushes.yml | 56 +++++++++++++++++ stories/okta_mfa_exhaustion.yml | 20 ++++++ 11 files changed, 472 insertions(+), 41 deletions(-) create mode 100644 detections/experimental/application/okta_account_locked_out.yml create mode 100644 detections/experimental/application/okta_mfa_exhaustion_hunt.yml create mode 100644 detections/experimental/application/okta_new_api_token_created.yml create mode 100644 detections/experimental/application/okta_new_device_enrolled_on_account.yml create mode 100644 detections/experimental/application/okta_suspicious_activity_reported.yml create mode 100644 detections/experimental/application/okta_threatinsight_threat_detected.yml create mode 100644 detections/experimental/application/okta_two_or_more_rejected_okta_pushes.yml create mode 100644 stories/okta_mfa_exhaustion.yml diff --git a/detections/experimental/application/multiple_okta_users_with_invalid_credentials_from_the_same_ip.yml b/detections/experimental/application/multiple_okta_users_with_invalid_credentials_from_the_same_ip.yml index c879649f3e..e0bea1863a 100644 --- a/detections/experimental/application/multiple_okta_users_with_invalid_credentials_from_the_same_ip.yml +++ b/detections/experimental/application/multiple_okta_users_with_invalid_credentials_from_the_same_ip.yml @@ -1,25 +1,28 @@ name: Multiple Okta Users With Invalid Credentials From The Same IP id: 19cba45f-cad3-4032-8911-0c09e0444552 -version: 2 -date: '2020-07-21' -author: Rico Valdez, Splunk -type: TTP +version: 3 +date: '2022-09-21' +author: Michael Haag, Rico Valdez, Splunk +type: Hunting datamodel: [] -description: This search detects Okta login failures due to bad credentials for multiple - users originating from the same ip address. -search: '`okta` outcome.reason=INVALID_CREDENTIALS | rename client.geographicalContext.country +description: This hunting analytic identifies multiple failed logon attempts from a single IP. Use this analytic to identify patterns of suspicious logins from a single source and filter as needed or use this to drive tuning for higher fidelity analytics. +search: '`okta` outcome.reason=INVALID_CREDENTIALS + | rename client.geographicalContext.country as country, client.geographicalContext.state as state, client.geographicalContext.city - as city | stats min(_time) as firstTime max(_time) as lastTime dc(user) as distinct_users - values(user) as users by src_ip, displayMessage, outcome.reason, country, state, - city | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` - | search distinct_users > 5| `multiple_okta_users_with_invalid_credentials_from_the_same_ip_filter` ' + as city + | stats min(_time) as firstTime max(_time) as lastTime dc(src_user) as distinct_users + values(src_user) as users by src_ip, displayMessage, outcome.reason, country, state, + city + | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` + | search distinct_users > 5| `multiple_okta_users_with_invalid_credentials_from_the_same_ip_filter` ' how_to_implement: This search is specific to Okta and requires Okta logs are being ingested in your Splunk deployment. known_false_positives: A single public IP address servicing multiple legitmate users may trigger this search. In addition, the threshold of 5 distinct users may be too low for your needs. You may modify the included filter macro `multiple_okta_users_with_invalid_credentials_from_the_same_ip_filter` to raise the threshold or except specific IP adresses from triggering this search. -references: [] +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=INVALID_CREDENTIALS tags: analytic_story: - Suspicious Okta Activity @@ -45,13 +48,13 @@ tags: - src_ip - displayMessage security_domain: access - confidence: 50 - impact: 50 - risk_score: 25 + confidence: 30 + impact: 30 + risk_score: 9 context: [] - message: tbd + message: Multple user accounts have failed to authenticate from a single IP. observable: - - name: user + - name: src_user type: User role: - Victim diff --git a/detections/experimental/application/okta_account_locked_out.yml b/detections/experimental/application/okta_account_locked_out.yml new file mode 100644 index 0000000000..c3cdd77d34 --- /dev/null +++ b/detections/experimental/application/okta_account_locked_out.yml @@ -0,0 +1,52 @@ +name: Okta Account Locked Out +id: d650c0ae-bdc5-400e-9f0f-f7aa0a010ef1 +version: 1 +date: '2022-09-21' +author: Michael Haag, Splunk +type: Anomaly +datamodel: [] +description: The following analytic utilizes the user.acount.lock event to identify associates who are locked out of Okta. An adversary, attempting to brute force or password spray account names, may lock accounts out depending on the threshold. +search: '`okta` eventType=user.account.lock + | stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) by src_user src_ip eventType status + | where count >=3 + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)`| `okta_account_locked_out_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed. Drop to anomaly until tuning is complete. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=user.acount.lock +tags: + analytic_story: + - Suspicious Okta Activity + - Okta MFA Exhaustion + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1110 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - src_user + - src_ip + - eventType + - status + security_domain: access + confidence: 80 + impact: 80 + risk_score: 64 + context: [] + message: $src_user$ account has been locked out. + observable: + - name: src_user + type: User + role: + - Attacker + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_account_lockout_events.yml b/detections/experimental/application/okta_account_lockout_events.yml index 0a42a1e4f1..80664492d4 100644 --- a/detections/experimental/application/okta_account_lockout_events.yml +++ b/detections/experimental/application/okta_account_lockout_events.yml @@ -1,20 +1,25 @@ name: Okta Account Lockout Events id: 62b70968-a0a5-4724-8ac4-67871e6f544d version: 2 -date: '2020-07-21' -author: Rico Valdez, Splunk +date: '2022-09-19' +author: Michael Haag, Rico Valdez, Splunk type: Anomaly datamodel: [] -description: Detect Okta user lockout events -search: '`okta` displayMessage="Max sign in attempts exceeded" | rename client.geographicalContext.country - as country, client.geographicalContext.state as state, client.geographicalContext.city - as city | table _time, user, country, state, city, src_ip | `okta_account_lockout_events_filter` ' -how_to_implement: This search is specific to Okta and requires Okta logs are being - ingested in your Splunk deployment. +description: The following anomaly will generate based on account lockout events utilizing Okta eventTypes of user.account.lock.limit or user.account.lock. Per the Okta docs site, this event is fired when a user account has reached the lockout limit. The account will not auto-unlock and a user or client cannot gain access to the account. This event indicates an account that will not be able to log in until remedial action is taken by the account admin. This event can be used to understand the specifics of an account lockout. Often this indicates a client application that is repeatedly attempting to authenticate with invalid credentials such as an old password. +search: '`okta` eventType IN (user.account.lock.limit,user.account.lock) + | rename client.geographicalContext.country as country, client.geographicalContext.state as state, client.geographicalContext.city as city + | stats count min(_time) as firstTime max(_time) as lastTime values(src_user) by displayMessage, country, state, city, src_ip + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `okta_account_lockout_events_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. known_false_positives: None. Account lockouts should be followed up on to determine if the actual user was the one who caused the lockout, or if it was an unauthorized actor. -references: [] +references: + - https://developer.okta.com/docs/reference/api/event-types/#catalog + - https://developer.okta.com/docs/reference/api/event-types/?q=user.account.lock tags: analytic_story: - Suspicious Okta Activity @@ -36,14 +41,16 @@ tags: - client.geographicalContext.country - client.geographicalContext.state - client.geographicalContext.city + - src_ip + - src_user security_domain: access confidence: 50 impact: 50 risk_score: 25 context: [] - message: tbd + message: The following user $src_user$ has locked out their account within Okta. observable: - - name: user + - name: src_user type: User role: - Victim diff --git a/detections/experimental/application/okta_failed_sso_attempts.yml b/detections/experimental/application/okta_failed_sso_attempts.yml index b3254a1d38..3539428e6b 100644 --- a/detections/experimental/application/okta_failed_sso_attempts.yml +++ b/detections/experimental/application/okta_failed_sso_attempts.yml @@ -1,20 +1,21 @@ name: Okta Failed SSO Attempts id: 371a6545-2618-4032-ad84-93386b8698c5 -version: 2 -date: '2020-07-21' -author: Rico Valdez, Splunk +version: 3 +date: '2022-09-21' +author: Michael Haag, Rico Valdez, Splunk type: Anomaly datamodel: [] -description: Detect failed Okta SSO events -search: '`okta` displayMessage="User attempted unauthorized access to app" | stats min(_time) - as firstTime max(_time) as lastTime values(app) as Apps count by user, result ,displayMessage, +description: The following anomaly identifies failed Okta SSO events utilizing the legacy Okta event "unauth app access attempt". +search: '`okta` eventType=app.generic.unauth_app_access_attempt | stats min(_time) + as firstTime max(_time) as lastTime values(app) as Apps count by src_user, result ,displayMessage, src_ip | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `okta_failed_sso_attempts_filter` ' how_to_implement: This search is specific to Okta and requires Okta logs are being ingested in your Splunk deployment. known_false_positives: There may be a faulty config preventing legitmate users from accessing apps they should have access to. -references: [] +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=app.generic.unauth_app_access_attempt tags: analytic_story: - Suspicious Okta Activity @@ -34,17 +35,17 @@ tags: - _time - displayMessage - app - - user + - src_user - result - src_ip security_domain: access - confidence: 50 - impact: 50 - risk_score: 25 + confidence: 40 + impact: 40 + risk_score: 16 context: [] - message: tbd + message: $src_user$ failed SSO authentication to the app. observable: - - name: user + - name: src_user type: User role: - Victim diff --git a/detections/experimental/application/okta_mfa_exhaustion_hunt.yml b/detections/experimental/application/okta_mfa_exhaustion_hunt.yml new file mode 100644 index 0000000000..979f462f57 --- /dev/null +++ b/detections/experimental/application/okta_mfa_exhaustion_hunt.yml @@ -0,0 +1,63 @@ +name: Okta MFA Exhaustion Hunt +id: 97e2fe57-3740-402c-988a-76b64ce04b8d +version: 1 +date: '2022-09-27' +author: Michael Haag, Splunk +type: Hunting +datamodel: [] +description: The following analytic identifies patterns within Okta data to determine the amount of successful and failed pushes. Based on that, eval statements determine a finding of whether this is suspicious or not. The events are within a window of time and may be tuned as needed. +search: '`okta` + eventType=system.push.send_factor_verify_push OR ((legacyEventType=core.user.factor.attempt_success) AND (debugContext.debugData.factor=OKTA_VERIFY_PUSH)) OR ((legacyEventType=core.user.factor.attempt_fail) AND (debugContext.debugData.factor=OKTA_VERIFY_PUSH)) + | stats count(eval(legacyEventType="core.user.factor.attempt_success")) as successes count(eval(legacyEventType="core.user.factor.attempt_fail")) as failures count(eval(eventType="system.push.send_factor_verify_push")) as pushes by authenticationContext.externalSessionId,user,_time + | stats latest(_time) as lasttime earliest(_time) as firsttime sum(successes) as successes sum(failures) as failures sum(pushes) as pushes by authenticationContext.externalSessionId,user + | eval seconds=lasttime-firsttime + | eval lasttime=strftime(lasttime, "%c") + | search (pushes>1) + | eval totalattempts=successes+failures + | eval finding="Normal authentication pattern" + | eval finding=if(failures==pushes AND pushes>1,"Authentication attempts not successful because multiple pushes denied",finding) + | eval finding=if(totalattempts==0,"Multiple pushes sent and ignored",finding) + | eval finding=if(successes>0 AND pushes>3,"Probably should investigate. Multiple pushes sent, eventual successful authentication!",finding) + | where seconds<600 AND finding="Multiple pushes sent, eventual successful authentication!" AND totalattempts > 5 + | sort - pushes, totalattempts + | `okta_mfa_exhaustion_hunt_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed. Drop to anomaly until tuning is complete. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=user.acount.lock + - https://sec.okta.com/everythingisyes +tags: + analytic_story: + - Suspicious Okta Activity + - Okta MFA Exhaustion + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1110 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - src_user + - src_ip + - eventType + - status + security_domain: access + confidence: 60 + impact: 30 + risk_score: 18 + context: [] + message: $src_user$ account has rejected multiple Okta pushes. + observable: + - name: src_user + type: User + role: + - Attacker + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_new_api_token_created.yml b/detections/experimental/application/okta_new_api_token_created.yml new file mode 100644 index 0000000000..7bdbbd1d28 --- /dev/null +++ b/detections/experimental/application/okta_new_api_token_created.yml @@ -0,0 +1,59 @@ +name: Okta New API Token Created +id: c3d22720-35d3-4da4-bd0a-740d37192bd4 +version: 1 +date: '2022-09-21' +author: Michael Haag, Splunk +type: TTP +datamodel: [] +description: The following analytic identifies when a new API token is created. Adversaries who have gained access to a privileged account may add a new token for persistence. This analytic uses the eventType system.api_token.create. +search: '`okta` eventType=system.api_token.create +| stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) by src_user src_ip eventType status + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `okta_new_api_token_created_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=security.threat.detected +tags: + analytic_story: + - Suspicious Okta Activity + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1078 + - T1078.001 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - signature + - eventType + - displayMessage + - client.device + - city + - state + - country + - user_agent + - outcome.reason + - outcome.result + - severity + security_domain: access + confidence: 50 + impact: 80 + risk_score: 40 + context: [] + message: $src_user$ has created a new API token within Okta. + observable: + - name: src_user + type: User + role: + - Attacker + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_new_device_enrolled_on_account.yml b/detections/experimental/application/okta_new_device_enrolled_on_account.yml new file mode 100644 index 0000000000..4bc92cb62c --- /dev/null +++ b/detections/experimental/application/okta_new_device_enrolled_on_account.yml @@ -0,0 +1,55 @@ +name: Okta New Device Enrolled on Account +id: bb27cbce-d4de-432c-932f-2e206e9130fb +version: 1 +date: '2022-09-21' +author: Michael Haag, Splunk +type: Anomaly +datamodel: [] +description: The following anomaly will be generated when a new device is added to an account. Albeit not malicious, risk is set low, but should be monitored. This anomaly utilizes the legacy events from Okta. +search: '`okta` eventType=system.email.new_device_notification.sent_message +displayMessage="Send user new device notification email" + | stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) by user eventType client.userAgent.rawUserAgent client.userAgent.browser client.geographicalContext.city client.geographicalContext.country + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `okta_new_device_enrolled_on_account_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: Tune the risk score as needed based on your organization. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=system.email.new_device_notification.sent_message +tags: + analytic_story: + - Suspicious Okta Activity + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1078 + - T1078.001 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - displayMessage + - user + - eventType + - client.userAgent.rawUserAgent + - client.userAgent.browser + - client.geographicalContext.city + - client.geographicalContext.country + security_domain: access + confidence: 60 + impact: 40 + risk_score: 24 + context: [] + message: $user$ has added a new device to their account. + observable: + - name: user + type: User + role: + - Victim + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_suspicious_activity_reported.yml b/detections/experimental/application/okta_suspicious_activity_reported.yml new file mode 100644 index 0000000000..4556d935fa --- /dev/null +++ b/detections/experimental/application/okta_suspicious_activity_reported.yml @@ -0,0 +1,55 @@ +name: Okta Suspicious Activity Reported +id: bfc840f5-c9c6-454c-aa13-b46fd0bf1e79 +version: 1 +date: '2022-09-21' +author: Michael Haag, Splunk +type: TTP +datamodel: [] +description: The following event is generated when an associate receives an email from Okta asking if a login attempt was suspicious or not. If the associate identifies it as suspicious an event is generated and should be reviewed. +search: '`okta` eventType=user.account.report_suspicious_activity_by_enduser + | stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) by user eventType client.userAgent.rawUserAgent client.userAgent.browser client.geographicalContext.city client.geographicalContext.country + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `okta_suspicious_activity_reported_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. It also requires that suspicious activity reporting is enabled and associates are trained to submit. +known_false_positives: False positives should be limited as this is a high fidelity marker. +references: + - https://help.okta.com/en-us/Content/Topics/Security/suspicious-activity-reporting.htm +tags: + analytic_story: + - Suspicious Okta Activity + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1078 + - T1078.001 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - displayMessage + - user + - eventType + - client.userAgent.rawUserAgent + - client.userAgent.browser + - client.geographicalContext.city + - client.geographicalContext.country + security_domain: access + confidence: 50 + impact: 50 + risk_score: 25 + context: [] + message: The following $user$ has reported a suspicious login activity. + observable: + - name: user + type: User + role: + - Victim + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_threatinsight_threat_detected.yml b/detections/experimental/application/okta_threatinsight_threat_detected.yml new file mode 100644 index 0000000000..8a57d66c36 --- /dev/null +++ b/detections/experimental/application/okta_threatinsight_threat_detected.yml @@ -0,0 +1,60 @@ +name: Okta ThreatInsight Threat Detected +id: 140504ae-5fe2-4d65-b2bc-a211813fbca6 +version: 1 +date: '2022-09-21' +author: Michael Haag, Splunk +type: Anomaly +datamodel: [] +description: The following anomaly relies on the Okta ThreatInsight identification of a threat. Use this to drive risk up by src_ip or add additional fields to track. Identification may include password spraying, login failures and Login failures with high unknown users count. +search: '`okta` eventType IN (security.threat.detected, security.internal.threat.detected) + | rename client.geographicalContext.country as country, client.geographicalContext.state as state, client.geographicalContext.city as city + | stats values(src_ip) count by signature eventType displayMessage client.device city state country user_agent outcome.reason outcome.result severity + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `okta_threatinsight_threat_detected_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=security.threat.detected +tags: + analytic_story: + - Suspicious Okta Activity + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1078 + - T1078.001 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - signature + - eventType + - displayMessage + - client.device + - city + - state + - country + - user_agent + - outcome.reason + - outcome.result + - severity + security_domain: access + confidence: 50 + impact: 50 + risk_score: 25 + context: [] + message: The following $src_ip$ has been conisidered a threat by Okta ThreatInsight. + observable: + - name: src_ip + type: IP Address + role: + - Attacker + kill_chain_phases: + - Exploitation diff --git a/detections/experimental/application/okta_two_or_more_rejected_okta_pushes.yml b/detections/experimental/application/okta_two_or_more_rejected_okta_pushes.yml new file mode 100644 index 0000000000..c0d6910f42 --- /dev/null +++ b/detections/experimental/application/okta_two_or_more_rejected_okta_pushes.yml @@ -0,0 +1,56 @@ +name: Okta Two or More Rejected Okta Pushes +id: d93f785e-4c2c-4262-b8c7-12b77a13fd39 +version: 1 +date: '2022-09-27' +author: Michael Haag, Splunk +type: TTP +datamodel: [] +description: The following analytic identifies an account that has rejected more than 2 Push notifications in a 10 minute window. + Modify this query for your environment by upping the count or time window. +search: '`okta` outcome.reason="User rejected Okta push verify" OR (debugContext.debugData.factor="OKTA_VERIFY_PUSH" outcome.result=FAILURE legacyEventType="core.user.factor.attempt_fail" "target{}.detailEntry.methodTypeUsed"="Get a push notification") + | bin _time as bin_time span=10m + | eval user=coalesce(actor.alternateId,user), user=mvindex(split(user, "@"), 0), event_time = _time + | stats earliest(event_time) as event_time, min(_time) as firsttime max(_time) as lasttime values(client.ipAddress) as client.ipAddress, values(outcome.reason) as outcome, values(src_ip) AS src_ip, values(client.userAgent.rawUserAgent) as user_agent, values(eventType) as eventType, values(outcome.result) as action, values(legacyEventType) as legacyEventType values(index) as idx, values(sourcetype) as st count by bin_time user host + | rename bin_time as timeWindow + | convert ctime(*timeWindow) ctime(firsttime) ctime(lasttime) + | where count >= 2 + | `okta_two_or_more_rejected_okta_pushes_filter`' +how_to_implement: This analytic is specific to Okta and requires Okta logs to be + ingested. +known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed. Drop to anomaly until tuning is complete. +references: + - https://developer.okta.com/docs/reference/api/event-types/?q=user.acount.lock +tags: + analytic_story: + - Suspicious Okta Activity + - Okta MFA Exhaustion + asset_type: Infrastructure + cis20: + - CIS 16 + mitre_attack_id: + - T1110 + nist: + - DE.CM + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - src_user + - src_ip + - eventType + - status + security_domain: access + confidence: 80 + impact: 80 + risk_score: 64 + context: [] + message: $src_user$ account has rejected multiple Okta pushes. + observable: + - name: src_user + type: User + role: + - Attacker + kill_chain_phases: + - Exploitation diff --git a/stories/okta_mfa_exhaustion.yml b/stories/okta_mfa_exhaustion.yml new file mode 100644 index 0000000000..8a327e6b40 --- /dev/null +++ b/stories/okta_mfa_exhaustion.yml @@ -0,0 +1,20 @@ +name: Okta MFA Exhaustion +id: 7c6e508d-4b4d-42c8-82de-5ff4ea3b0cb3 +version: 1 +date: '2022-09-27' +author: Michael Haag, Splunk +description: A social engineering technique called 'MFA Fatigue', aka 'MFA push spam' or 'MFA Exhaustion', is growing more popular with threat actors as it does not require malware or phishing infrastructure and has proven to be successful in attacks. +narrative: An MFA Fatigue attack is when a threat actor runs a script that attempts to log in with stolen credentials over and over, causing what feels like an endless stream of MFA push requests to be sent to the account's owner's mobile device. + The goal is to keep this up, day and night, to break down the target's cybersecurity posture and inflict a sense of "fatigue" regarding these MFA prompts. +references: + - https://www.bleepingcomputer.com/news/security/mfa-fatigue-hackers-new-favorite-tactic-in-high-profile-breaches/ + - https://www.csoonline.com/article/3674156/multi-factor-authentication-fatigue-attacks-are-on-the-rise-how-to-defend-against-them.html +tags: + analytic_story: Okta MFA Exhaustion + category: + - Adversary Tactics + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + usecase: Advanced Threat Detection From d359e51e9edfb27fd1eae2529624f5f8a9d0cc29 Mon Sep 17 00:00:00 2001 From: Michael Haag <5632822+MHaggis@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:08:47 -0600 Subject: [PATCH 2/3] Create okta_risk_threshold_exceeded.yml --- .../okta_risk_threshold_exceeded.yml | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 detections/application/okta_risk_threshold_exceeded.yml diff --git a/detections/application/okta_risk_threshold_exceeded.yml b/detections/application/okta_risk_threshold_exceeded.yml new file mode 100644 index 0000000000..c0f54c5a2e --- /dev/null +++ b/detections/application/okta_risk_threshold_exceeded.yml @@ -0,0 +1,64 @@ +name: Okta Risk Threshold Exceeded +id: d8b967dd-657f-4d88-93b5-c588bcd7218c +version: 1 +date: '2022-09-29' +author: Michael Haag, Splunk +type: Correlation +datamodel: +- Risk +description: The following correlation will take risk associated with the content from "Suspicious Okta Activity" and "Okta MFA Exhaustion" analytic stories and tally it up. Once it hits a threshold of 100 (may be changed), it will trigger an anomaly. As needed, reduce or raise the risk scores assocaited with the anomaly and TTP analytics tagged to these two stories. +search: '| tstats `summariesonly` sum(All_Risk.calculated_risk_score) as risk_score, count(All_Risk.calculated_risk_score) as risk_event_count,values(All_Risk.annotations.mitre_attack.mitre_tactic_id) as annotations.mitre_attack.mitre_tactic_id, dc(All_Risk.annotations.mitre_attack.mitre_tactic_id) as mitre_tactic_id_count, values(All_Risk.annotations.mitre_attack.mitre_technique_id) as annotations.mitre_attack.mitre_technique_id, dc(All_Risk.annotations.mitre_attack.mitre_technique_id) as mitre_technique_id_count, values(All_Risk.tag) as tag, values(source) as source, dc(source) as source_count from datamodel=Risk.All_Risk by All_Risk.risk_object,All_Risk.risk_object_type All_Risk.analyticstories + | `drop_dm_object_name("All_Risk")` + | eval "annotations.mitre_attack"="annotations.mitre_attack.mitre_technique_id", risk_threshold=100 + | where All_Risk.analyticstories IN ("Suspicious Okta Activity", "Okta MFA Exhaustion") risk_score > $risk_threshold$ + | `get_risk_severity(risk_score)` + | `okta_risk_threshold_exceeded_filter`' +how_to_implement: Ensure "Suspicious Okta Activity" and "Okta MFA Exhaustion" analytic stories are enabled. TTP may be set to Notables for point detections, anomaly should not be notables but risk generators. The correlation relies on risk before generating a notable. Modify the value as needed. Default threshold is 100. This value may need to be increased based on activity in your environment. +known_false_positives: False positives will be limited to the amount of events generated by the analytics tied to the stories. Analytics will need to be tesetd and tuned, risk score reduced, as needed based on organization. +references: + - https://developer.okta.com/docs/reference/api/event-types + - https://sec.okta.com/everythingisyes +tags: + analytic_story: + - Suspicious Okta Activity + - Okta MFA Exhaustion + asset_type: Infrastructure + cis20: + - CIS 3 + - CIS 5 + - CIS 16 + confidence: 80 + context: + - Other:Brute Force + - Scope:External + - Source:Correlation + dataset: [] + impact: 70 + kill_chain_phases: + - Reconnaissance + - Exploitation + message: Risk threshold exceeded for $risk_object_type$=$risk_object$ related to Okta events. + mitre_attack_id: + - T1078 + - T1110 + nist: + - DE.CM + observable: + - name: risk_object + type: Other + role: + - Victim + - name: risk_object_type + type: Other + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - All_Risk.risk_object + - All_Risk.risk_object_type + - All_Risk.analyticstories + risk_score: 56 + security_domain: access From c8c64150bd7915967378a7dc0861ad86c8490c76 Mon Sep 17 00:00:00 2001 From: Michael Haag <5632822+MHaggis@users.noreply.github.com> Date: Mon, 3 Oct 2022 09:20:17 -0600 Subject: [PATCH 3/3] updates --- detections/application/okta_risk_threshold_exceeded.yml | 2 +- .../experimental/application/okta_account_locked_out.yml | 2 +- .../experimental/application/okta_new_api_token_created.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/detections/application/okta_risk_threshold_exceeded.yml b/detections/application/okta_risk_threshold_exceeded.yml index c0f54c5a2e..7c16a5ce42 100644 --- a/detections/application/okta_risk_threshold_exceeded.yml +++ b/detections/application/okta_risk_threshold_exceeded.yml @@ -6,7 +6,7 @@ author: Michael Haag, Splunk type: Correlation datamodel: - Risk -description: The following correlation will take risk associated with the content from "Suspicious Okta Activity" and "Okta MFA Exhaustion" analytic stories and tally it up. Once it hits a threshold of 100 (may be changed), it will trigger an anomaly. As needed, reduce or raise the risk scores assocaited with the anomaly and TTP analytics tagged to these two stories. +description: The following correlation will take risk associated with the content from "Suspicious Okta Activity" and "Okta MFA Exhaustion" analytic stories and tally it up. Once it hits the threshold of 100 (may be changed), it will trigger an anomaly. As needed, reduce or raise the risk scores assocaited with the anomaly and TTP analytics tagged to these two stories. search: '| tstats `summariesonly` sum(All_Risk.calculated_risk_score) as risk_score, count(All_Risk.calculated_risk_score) as risk_event_count,values(All_Risk.annotations.mitre_attack.mitre_tactic_id) as annotations.mitre_attack.mitre_tactic_id, dc(All_Risk.annotations.mitre_attack.mitre_tactic_id) as mitre_tactic_id_count, values(All_Risk.annotations.mitre_attack.mitre_technique_id) as annotations.mitre_attack.mitre_technique_id, dc(All_Risk.annotations.mitre_attack.mitre_technique_id) as mitre_technique_id_count, values(All_Risk.tag) as tag, values(source) as source, dc(source) as source_count from datamodel=Risk.All_Risk by All_Risk.risk_object,All_Risk.risk_object_type All_Risk.analyticstories | `drop_dm_object_name("All_Risk")` | eval "annotations.mitre_attack"="annotations.mitre_attack.mitre_technique_id", risk_threshold=100 diff --git a/detections/experimental/application/okta_account_locked_out.yml b/detections/experimental/application/okta_account_locked_out.yml index c3cdd77d34..c9a43cd05f 100644 --- a/detections/experimental/application/okta_account_locked_out.yml +++ b/detections/experimental/application/okta_account_locked_out.yml @@ -5,7 +5,7 @@ date: '2022-09-21' author: Michael Haag, Splunk type: Anomaly datamodel: [] -description: The following analytic utilizes the user.acount.lock event to identify associates who are locked out of Okta. An adversary, attempting to brute force or password spray account names, may lock accounts out depending on the threshold. +description: The following analytic utilizes the user.acount.lock event to identify associates who are locked out of Okta. An adversary attempting to brute force or password spray account names may lock accounts out depending on the threshold. search: '`okta` eventType=user.account.lock | stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) by src_user src_ip eventType status | where count >=3 diff --git a/detections/experimental/application/okta_new_api_token_created.yml b/detections/experimental/application/okta_new_api_token_created.yml index 7bdbbd1d28..c05b79b71f 100644 --- a/detections/experimental/application/okta_new_api_token_created.yml +++ b/detections/experimental/application/okta_new_api_token_created.yml @@ -45,9 +45,9 @@ tags: - outcome.result - severity security_domain: access - confidence: 50 + confidence: 80 impact: 80 - risk_score: 40 + risk_score: 64 context: [] message: $src_user$ has created a new API token within Okta. observable: