LoFP LoFP / 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.

Sample rules

Okta Two or More Rejected Okta Pushes

Description

DEPRECATION NOTE - This search has been deprecated and replaced with Okta Multiple Failed MFA Requests For User. 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.

Detection logic

`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`

Okta Account Locked Out

Description

DEPRECATION NOTE - This search has been deprecated and replaced with Okta Multiple Accounts Locked Out. 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.

Detection logic

`okta` eventType=user.account.lock 
| stats count min(_time) as firstTime max(_time) as lastTime values(displayMessage) values(src_user) as user by src_ip eventType status 
| where count >=3 
| `security_content_ctime(firstTime)` 
| `security_content_ctime(lastTime)`
| `okta_account_locked_out_filter`

Okta MFA Exhaustion Hunt

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.

Detection logic

`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 user,_time 
| stats latest(_time) as lasttime earliest(_time) as firsttime sum(successes) as successes sum(failures) as failures sum(pushes) as pushes by 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) 
| `okta_mfa_exhaustion_hunt_filter`

Okta New API Token Created

Description

The following analytic identifies when a new API token is created within an Okta tenant. An adversary may create a new API token to maintain persistence within the environment. Monitoring for new API tokens can help detect potential account takeover attempts or unauthorized access to Okta accounts.

Detection logic

 
| tstats `security_content_summariesonly` count max(_time) as lastTime, min(_time) as firstTime from datamodel=Change where All_Changes.action=created AND All_Changes.command=system.api_token.create by _time span=5m All_Changes.user All_Changes.result All_Changes.command sourcetype All_Changes.src All_Changes.action All_Changes.object_category 
| `drop_dm_object_name("All_Changes")` 
| `security_content_ctime(firstTime)` 
| `security_content_ctime(lastTime)` 
| `okta_new_api_token_created_filter`