Okta and Splunk Combine to Detect Common Attacks

Brett Winterford and Defensive Cyber Operations

In an ideal world, every security function would have a Detection Engineering team.

Regrettably, even organizations that are stewards of highly sensitive data often can’t afford (or don’t prioritize) the capabilities required for effective security monitoring. There can be a misconception that cloud service providers are doing the monitoring for them.

It's a challenge that Okta Security wants to help address. Whenever we write a detection for our own purposes (we use Okta, too!), there’s an untapped opportunity to use those detections to help other Okta customers prevent or respond to security incidents that stem from common credential-based attacks.

So we’ve decided to publish our detection logic. Right here! (Scroll down!)

Publishing raw detection logic will suit many of our customers. But we recognize that publishing them here won’t reach everybody, and it still puts the onus on customers to tune or adapt the detections.

That’s where mutual friends come in handy.

Over the past few months, Okta’s Defensive Cyber Operations team has shared bespoke detection logic with security analytics/SIEM providers, requesting the logic be baked into their content libraries “out of the box.”

The first of those discussions has already borne fruit with Splunk, the security analytics platform chosen most often by Okta customers, thanks to the assistance of James Brodsky, Splunk’s GVP for Security Strategy and Splunk Senior Threat Researcher Michael Haag.

As of Splunk Enterprise Security Content Update (ESCU) v3.62.0, security teams that ingest Okta System Log events into the Splunk platform can run and modify an initial set of bespoke detections in Splunk® Enterprise Security developed by Okta’s Defensive Cyber Operations team. James and Michael have tweaked these raw detections to make them more legible and applicable to a broader number of our mutual customers.

The Splunk update enhances their pre-existing analytic stories for Okta, and includes new approaches to detecting:

  • Session Hijacking via phishing for initial access
  • Post-compromise activity by threat actors abusing a stolen session token
  • Abuse of Push MFA (including “MFA Fatigue” attacks)
  • Credential Stuffing
  • Password Spray attacks

All of these detections are relevant to Okta Identity Engine (not the Classic Engine).

The logic for each is presented below:


Okta Phishing Detection with FastPass Origin Check

ID

T1556

Tactic

Phishing

Description

Okta provides a platform detection for when a user enrolled in FastPass fails to authenticate via a real-time AiTM phishing proxy. More info here.

Okta System Log Query

eventType eq "user.authentication.auth_via_mfa" AND result eq "FAILURE" AND outcome.reason eq "FastPass declined phishing attempt"

Splunk Analytic

F4ca0057-cbf3-44f8-82ea-4e330ee901d3


Suspicious Use of an Okta Session Cookie

ID

T1539

Tactic

Steal Web Session Cookie

Authors

Scott Dermott and Felicity Robson (Okta)

Description

A detection opportunity arises when an adversary attempts to reuse a stolen web session cookie.

The following analytic looks for one or more policy evaluation events in which multiple client values (IP, User Agent, etc.) change associated to the same Device Token for a specific user. 

The query below: 

  • Retrieves policy evaluation events from successful authentication events.
  • Aggregates/Groups by Device Token and User, providing the first policy evaluation event in the search window.
  • Evaluates whether there is more than one IP and whether there is more than one OS or browser for each combination of User/Device Token.

Query

index=main sourcetype=OktaIM2:log eventType IN (policy.evaluate_sign_on) outcome.result IN (ALLOW, SUCCESS)    | stats earliest(_time) as _time values(client.ipAddress) as src_ip values(client.userAgent.rawUserAgent) as user_agent values(client.userAgent.os) as userAgentOS_list values(client.userAgent.browser) as userAgentBrowser_list values(device.os_platform) as okta_device_os dc(client.userAgent.browser) as dc_userAgentBrowser dc(client.userAgent.os) as dc_userAgentOS dc(client.ipAddress) as dc_src_ip values(outcome.reason) as reason by debugContext.debugData.dtHash actor.alternateId

    ``` If we see different Operating Systems or Browsers from a UserAccount using with the same DTHash ```

    | where dc_src_ip>1 AND (dc_userAgentOS>1 OR dc_userAgentBrowser>1)

Splunk Analytic

71ad47d1-d6bd-4e0a-b35c-020ad9a6959e 


Multiple Failed Requests to Access Okta Applications

ID

T1550.004, T1538

Tactic

Steal Web Session Cookie

Authors

John Murphy (Okta)

Description

A detection opportunity arises when an adversary attempts to reuse a stolen web session cookie in an org with well-configured authentication policies. 

The following analytic looks for multiple attempts to open app chiclets with no successful response to an authentication challenge.

The query below: 

  • Retrieves policy evaluation and SSO details in events that contain the Application requested
  • Formats target fields so we can aggregate specifically on Applications (AppInstances)
  • Groups by User, Session and IP
  • Creates a ratio of successful SSO events to total MFA challenges related to Application Sign On Policies
  • Alerts when more than half of app sign on events are unsuccessful, and challenges were unsatisfied for more than three apps.

Query

index=main sourcetype=oktaim2:log target{}.type=AppInstance (eventType=policy.evaluate_sign_on outcome.result=CHALLENGE) OR (eventType=user.authentication.sso outcome.result=SUCCESS) 

    | eval targets=mvzip('target{}.type', 'target{}.displayName', ": ")

    | eval targets=mvfilter(targets LIKE "AppInstance%")

    ```Stats per user/session/ip/target app```

    | stats count min(_time) as _time values(outcome.result) as outcome.result dc(eval(if(eventType="policy.evaluate_sign_on",targets,NULL))) as total_challenges sum(eval(if(eventType="user.authentication.sso",1,0))) as total_successes 

    by authenticationContext.externalSessionId targets actor.alternateId client.ipAddress

    ```Exclude apps that don't require a challenge```

    | search total_challenges > 0

    ```Group events by session/actor/ip```

    | stats min(_time) as _time values(*) as * sum(total_challenges) as total_challenges sum(total_successes) as total_successes values(eval(if('outcome.result'="SUCCESS",targets,NULL))) as success_apps values(eval(if('outcome.result'!="SUCCESS",targets,NULL))) as no_success_apps by authenticationContext.externalSessionId actor.alternateId client.ipAddress

    | fillnull

    | eval ratio=round(total_successes/total_challenges,2), severity="HIGH", mitre_technique_id="T1538", description='actor.alternateId'. " from " . 'client.ipAddress' . " seen opening " . total_challenges . " chiclets/apps with " . total_successes . " challenges successfully passed"

    | fields - count, targets

    ```Assuming a majority of apps have good sign-on policies, if we see three apps with ignored challenges, that's worth investigating```

    | search ratio < 0.5 total_challenges > 2

Splunk Analytic

1c21fed1-7000-4a2e-9105-5aaafa437247 


Mismatch Between Source and Response for Verify Push Request

ID

T1621

Tactic

Multi-Factor Authentication Request Generation

Authors

John Murphy and Jordan Ruocco (Okta)

Description

A detection opportunity arises when an adversary that has stolen a user password attempts to trick a user into accepting a Okta Verify Push request.

The following analytic identifies variations in client-based values for source and response events to identify suspicious request behavior. The detection is enhanced if the org is evaluating behavior conditions in sign-on policies using Okta Behavior Detection.

The query below: 

  • Groups by SessionID and retrieves any system.push.send_factor_verify_push events (the source of the push) and user.authentication.auth_via_mfa events where the factor is OKTA_VERIFY_PUSH - (the user response to the push)
  • Counts the total number of push events, successful authentication events, and any push sources where the client is a new device.
  • Creates a ratio of successful sign-ins to pushes. 
  • If the ratio (currently tuned aggressively) indicates push spam, or if a user has rejected a push, the detection proceeds to evaluate whether there is more than one IP address used during the session (session roaming) and the presence of both a new IP and new device during the session.

Query

index=main sourcetype=OktaIM2:log eventType IN (system.push.send_factor_verify_push) OR (eventType IN (user.authentication.auth_via_mfa) debugContext.debugData.factor="OKTA_VERIFY_PUSH")

| eval groupby='authenticationContext.externalSessionId'

    ``` Each push is sent to each registered push device, so we should group pushes around the same time as a single event for the purpose of this use-case ``` 

| eval group_push_time=_time 

| bin span=2s group_push_time 

| fillnull value=NULL 

| stats min(_time) as _time by authenticationContext.externalSessionId eventType debugContext.debugData.factor outcome.result actor.alternateId client.device client.ipAddress client.userAgent.rawUserAgent debugContext.debugData.behaviors group_push_time groupby

| iplocation client.ipAddress

| fields - lat, lon, group_push_time

    ```Get counts for number of push events, successful authentication events, and any push sources where the client is a new device ``` 

| stats min(_time) as _time dc(client.ipAddress) as dc_ip 

    sum(eval(if(eventType="system.push.send_factor_verify_push" AND 'outcome.result'="SUCCESS",1,0))) as total_pushes 

    sum(eval(if(eventType="user.authentication.auth_via_mfa" AND 'outcome.result'="SUCCESS",1,0))) as total_successes 

    sum(eval(if(eventType="user.authentication.auth_via_mfa" AND 'outcome.result'="FAILURE",1,0))) as total_rejected 

    sum(eval(if(eventType="system.push.send_factor_verify_push" AND 'debugContext.debugData.behaviors' LIKE "%New Device=POSITIVE%",1,0))) as suspect_device_from_source 

    sum(eval(if(eventType="system.push.send_factor_verify_push" AND 'debugContext.debugData.behaviors' LIKE "%New IP=POSITIVE%",1,0))) as suspect_ip_from_source 

    values(eval(if(eventType="system.push.send_factor_verify_push",'client.ipAddress',""))) as src 

    values(eval(if(eventType="user.authentication.auth_via_mfa",'client.ipAddress',""))) as dest 

    values(*) as * by groupby 

| eval ratio = round(total_successes/total_pushes,2)

    ```Create a ratio of successful sign ins to pushes. If the push and response come from the same IP, it's likely legit. Note that the current ratio is quite aggressive. Aside from tuning the ratio you could add other conditions, for example: dc Country > 1, other behaviors (NEW Geo-Location=POSITIVE), device.managed=false, client.os!={SOE_OS}```

| search ((ratio < 0.5 AND total_pushes > 2) OR (total_rejected > 0)) AND dc_ip > 1 AND suspect_device_from_source > 0 AND suspect_ip_from_source > 0

Splunk Analytic

8085b79b-9b85-4e67-ad63-351c9e9a5e9a


ThreatInsight Alert: Login Failure with High Unknown Users

ID

T1110.004

Tactic

Brute Force: Credential Stuffing

Description

Okta provides a platform detection for multiple login failures with high unknown user counts from the same IP across one or more Okta orgs. More info here.

Okta System Log Query

eventType eq "security.threat.detected" AND outcome.reason co "Login failures with high unknown users count"

Splunk Analytic

632663b0-4562-4aad-abe9-9f621a049738


ThreatInsight Alert: Suspected Password Spray Attack 

ID

T1110.003

Tactic

Brute Force: Password Spray

Description

Okta provides a platform detection for failed password events across multiple user accounts. More info here.

Okta System Log Query

eventType eq "security.threat.detected" AND outcome.reason co "Password Spray"

Splunk Analytic

25dbad05-6682-4dd5-9ce9-8adecf0d9ae2 

 

Magic like this happens when best-in-class providers of security tools share knowledge, without any agenda outside of protecting our mutual customers. 

A huge thanks to the authors and contributors in this initial effort:

  • James Brodsky (Splunk)
  • Scott Dermott (Okta)
  • Michael Haag (Splunk)
  • John Murphy (Okta) 
  • Felicity Robson (Okta)
  • Jordan Ruocco (Okta)

To learn more, Splunk and Okta are hosting a joint session at .conf23, the annual Splunk conference, scheduled for July 17-20, 2023 in Las Vegas.

Brett Winterford
Regional CSO, Okta APJ

Brett Winterford is the regional Chief Security Officer for Okta in the Asia Pacific and Japan. 
He advises business and technology leaders on evolving threats and helps them harness advances in identity technology to drive business outcomes and mitigate risk.
Prior to Okta, Brett held a senior security leadership role at Symantec, and helmed security research, awareness and education at Commonwealth Bank.
Brett is also an award-winning journalist, having long ago been the editor-in-chief of iTnews Australia and a contributor to ZDNet, the Australian Financial Review and the Sydney Morning Herald. Most recently, he was the founding editor of the Srsly Risky Biz newsletter, a companion to the Risky Business podcast, providing the cybersecurity, policy, defense and intelligence communities with a weekly brief of the news that shapes cyber policy. 

Defensive Cyber Operations

The Defensive Cyber Operations (DCO) team is responsible for detecting and responding to cyber threats that impact Okta or our customers via the Okta platform. Our intelligence-driven capability identifies the adversaries most likely to impact Okta and our customers, and prioritises our defensive capabilities based on the threats most likely to be realised.