Recommendations on SSO monitoring in light of the recent Okta breach
The news that hacking group Lapsus$ gained unauthorized access to Single Sign-On (SSO) provider Okta through a third-party support account sent chills through information security professionals everywhere. Organizations have adopted SSO identity providers to enable a modern workforce that is increasingly reliant on secure access to cloud-hosted applications to perform critical business functions.
Every organization should understand the risks associated with moving critical authentication services to 3rd party providers and ensure sufficient controls are implemented to minimize the risk to an acceptable level.
We have a few other thoughts on this matter, hold on while we find a soapbox…
The message we want to communicate is clear: If your organization uses a cloud-hosted SSO provider, you must have a monitoring, detection and response strategy tailored to your SSO infrastructure.
Look, we get it. The Sumo Logic Threat Labs and Global Operations Center (GOC) teams have been in your shoes before. We understand what it’s like to be caught without the right logs, struggled to interpret a new log source and spent countless hours pondering how to distill the nuanced signals of an intrusion. At Sumo Logic, one of our core values is “In it with our customers.” We will take it a step further and add “In it with our customers and the security community.” You need a strategy, and at the risk of sounding cliche, “the best time to start was yesterday, the next best time is now.”
The goal of this blog is to provide the building blocks for developing a strategy for monitoring, detecting and responding to activity within your SSO infrastructure. Let’s go!
First things first
If you are using Okta, OneLogin, Ping Identity, Microsoft Azure Active Directory (AD) or any other SSO identity provider and are not sending the logs to a SIEM or log management platform, stop reading this. Go and enable logging (make sure you double check the log levels) and forward them to your SIEM or log management system immediately.
Most identity providers will retain logs for some period of time but forwarding these critical events to a secure, long-term storage solution, like Sumo Logic Cloud SIEM or other relevant platforms, is highly recommended.
General SSO configuration hygiene
- Enforce Multi-Factor Authentication (MFA) as part of the authentication process; FIDO hard tokens are the most secure, mobile push notifications are the next best option but are increasingly under attack. SMS codes are considered the least secure but are better than nothing at all.
- Review additional security features that can be enabled (some at no cost, others require a subscription) to provide additional layers of security, such as Okta’s ThreatInsight or Azure Active Directory (AD) Identity Protection.
- If your SSO provider offers a built-in setting to disable support access, you should disable access, only enabling it when support is required.
- Validate that logging is enabled and set to the appropriate log level. (Yes, for some SSO vendors logging can be configured at various levels or verbosity)
- Send logs to a SIEM or log management tool (did we emphasize this enough yet?). Ensure log retention meets regulator or organizational requirements.
Getting real on detections: you need a strategy
Before we dive into some of the attack paths we’ve observed and some useful and clever searches that can be used to monitor and investigate SSO logs, let's first discuss how an organization can actually detect a successful attack against its SSO infrastructure.
The first thing that should be acknowledged is this: there is no “smoking gun” search, alert or single detection that indicates an account has been compromised. Visibility into all things (increasingly cloud) and understanding how to baseline behavior and surface anomalies is critical for defenders.
To oversimplify our approach, we risk rate notable activity by each entity within a time window. This allows us to look for “clusters” of notable events that, when considered in aggregate, are more likely to identify malicious activity.
For example, observing a single SSO account with a password reset is a notable event, but when considered on its own, does not necessarily suggest a compromise has occurred. However, if we observe the same SSO account with anomalous MFA push notifications, a password reset, an MFA reset and some unusual SSO application access, well that is certainly more interesting.
Tip: Some events happen so infrequently, and with the potential to have significant security ramifications if missed, that we suggest setting up alerts or notifications to a group or distribution list of key stakeholders via email, Slack, Microsoft Teams or directly through your SIEM for immediate awareness. Notifying a group of stakeholders reduces the likelihood of a potentially critical event going unnoticed.
Some examples are below:
- Account granted SSO Administrator privileges
- External support access to SSO environment
- Password or MFA reset activity by unexpected accounts
Example attack paths
Below, we’ll attempt to walk through some of the attack paths an attacker might take to attack your organization via SSO. Remember that the below searches are best used for general SSO security monitoring, investigations or feeding an entity risk score for risk aggregation, like Sumo’s Cloud SIEM.
The searches we provide throughout the blog are based on Okta logs but can be easily updated for use against any SSO provider log.
Supply chain
An attacker that manages to compromise any SSO provider directly and subsequently uses that to access or manipulate customer environments would fall under a supply chain attack. Defenders should monitor for unusual or unexpected access from the SSO provider.
Unexpected SSO provider service access
In the example below, we’ll use the Continuous Intelligence Platform™ (CIP) to search for any activity from Okta accounts that should be further investigated.
| json field=_raw "eventType"
| json field=_raw "displayMessage"
| json field=_raw "outcome.result" as outcome
| json field=_raw "actor.type"
| json field=_raw "actor.alternateId" as act_id
| json field=_raw "actor.displayName"
| json field=_raw "target[0].alternateId" as target_id
| json field=_raw "target[0].displayName" as target_Name
| where act_id != "system@okta.com"
| count eventType,displayMessage,outcome,act_id,target_id
The next search (which we would advise be set up to generate an alert when seen) indicates that a session impersonation event has occurred. This should only occur if Okta administrative access has been requested by an organization.
| json field=_raw "actor.alternateId" as user
| json field=_raw "outcome.result" as result
| json field=_raw "outcome.reason" as outcome
| json field=_raw "eventType" as event
| json field=_raw "client.userAgent.rawUserAgent" as user_agent
| json field=_raw "client.userAgent.os" as os
| json field=_raw "client.ipAddress" as srcIP
Anomalous password resets
An attacker might also reset user passwords or reset MFA. Looking for instances where unusual accounts are resetting passwords or MFA might warrant further analysis.
| json field=_raw "eventType"
| json field=_raw "published" as time
| json field=_raw "displayMessage"
| json field=_raw "outcome.result" as outcome
| json field=_raw "actor.type"
| json field=_raw "actor.alternateId" as act_id
| json field=_raw "actor.displayName"
| json field=_raw "target[0].alternateId" as target_id
| json field=_raw "target[0].displayName" as target_Name
| where act_id != target_id
//| where !(act_id matches "<expected user>" OR act_id matches "*expected user>*")
| count time,eventType,displayMessage,outcome,act_id,target_id
Credential theft
The attacks you are most likely to see are attacks against employee credentials, typically in the form of phishing, password spray attacks and MFA fatigue attacks.
Password spray attacks
Password spray attacks can take many forms—and security teams should keep an eye for the signs of an ongoing password spray attack.
General awareness - deviations in failed logins
It’s not a bad idea to keep an eye on spikes or baseline deviations in failed logins to your SSO provider. Establish a baseline of unique accounts with failed logins to your SSO and look for outliers.
This may help identify low and slow password spray attacks and provides a decent 10,000-foot view of attacks or probes against your SSO.
High volume password spray
One of our favorite ways to identify active password spray attacks is to look for a spike in SSO failed logins sourcing from the same ASN. Attackers can change the source of their password spray easily, so building your search around a source IP is too narrow. We’ve found grouping by the source ASN and putting a 30 or 60-minute time window around it is the sweet spot.
| json field=_raw "actor.alternateId" as user
| json field=_raw "eventType" as event
| json field=_raw "client.userAgent.rawUserAgent" as user_agent
| json field=_raw "client.userAgent.os" as os
| json field=_raw "client.ipAddress" as srcIP
| timeslice 30m
| lookup asn, organization from asn://default on ip=srcIP
| lookup country_name from geo://location on ip=srcIP
| values(user) as users,values(user_agent) as UA, count_distinct(user) as dist_users by organization,ASN,_timeslice,users,UA,country_name
| where dist_users > 10
Another way to look at authentication failures:
| json field=_raw "request.ipChain[0].ip" as request_ip nodrop
| json field=_raw "request.ipChain[0].geographicalContext.country" as request_country nodrop
| json field=_raw "request.ipChain[0].geographicalContext.state" as request_state nodrop
| json field=_raw "target[0].type" as target_0_type nodrop
| json field=_raw "target[*].alternateId" as target_altid nodrop
| json field=_raw "target[0].alternateId" as target0_altid nodrop
| json field=_raw "target[1].alternateId" as target1_altid nodrop
| json field=_raw "actor.alternateId" nodrop
| json field=_raw "client.ipAddress" nodrop
| json field=_raw "outcome.result" as result nodrop
| json field=_raw "securityContext.asNumber" as asn nodrop
| json field=_raw "securityContext.asOrg" as asn_org nodrop
| json field=_raw "securityContext.isp" as isp nodrop
| json field=_raw "client.userAgent.rawUserAgent" as user_agent nodrop
//| where !(asn_org matches “*[Your Organizations ASN]*” )
| timeslice 30m
| values(target_altid) as users,values(asn_org) as asn_org,values(request_country) as country,count_distinct(target_altid) as target_count, count group by request_ip,user_agent,_timeslice
| where target_count > 10
Expanding the search to look for spikes in failed logins over a short time window (10 minutes) can also prove useful but can sometimes generate false positives. Think Monday morning when everyone is first logging in or after a holiday break and no one can remember their password.
MFA push notification fatigue
Adding an additional layer of security on top of SSO is recommended, and the most common method for doing this is in the form of push notifications. Once valid credentials have been provided to the SSO platform, an MFA push notification will be sent to a pre-enrolled device that requires accepting or acknowledging the attempt to complete the login process.
Once an attacker has a username and password, they can attempt to initiate a logon with the hope that the victim unknowingly or unintentionally acknowledges the push notification. Believe us when we tell you that this happens more often than you think!
To increase their chance of success, attackers will flood or spam victims with push notifications. Okta published a great blog on this attack technique in early March 2022.
We’ve adapted their detection for use in Sumo’s CIP:
| json field=_raw "outcome.result" as result
| json field=_raw "actor.alternateId" as user
| timeslice 10m
| if(result="SUCCESS",1,0) as success| if(result="FAILURE",1,0) as failure
| count as total_pushes,sum(success) as success, sum(failure) as failure by user,_timeslice
| failure/total_pushes as push_fail_ratio
| "No Finding" as finding
| if(failure=total_pushes AND total_pushes>1,"Authentication attempts not successful because multiple pushes denied",finding) as finding
| if(total_pushes=0,"Multiple pushes sent and ignored",finding) as finding
| if(success>0 AND total_pushes>3,"Multiple pushes sent, eventual successful authentication!",finding) as finding
| if(push_fail_ratio>.1,"High push fail Ratio with successful login detected",finding) as finding
| where finding = "High push fail Ratio with successful login detected" and total_pushes > 1
This search will identify instances where an account has been observed with a high number of push notifications sent with multiple failures with at least one successful login.
Post SSO compromise activity
Once an attacker steals credentials and successfully gets a victim to accept a push notification, they have some form of access to the organization and its data. We’ve observed attackers performing a variety of actions following initial access, which we will discuss below.
Please note that any results that may return from the below searches do not indicate a compromise has occurred and should be considered in aggregate with other events of interest associated with the account in question.
Interesting MFA and password reset activity
If an attacker has managed to compromise an SSO account, they might reset the account password and update and take control of the victim’s MFA. The below CIP search is also looking at Okta data and identifying any accounts that have had both an MFA update and password reset event within a specified time window.
| json field=_raw "eventType" as action
| if(action matches"*reset_password*",1,0) as reset_password
| if(action matches"*user.mfa.factor.update*",1,0) as user_mfa_factor_update
| json field=_raw "actor.alternateId" as user
| json field=_raw "target[*].alternateId" as target_user //identifies target, rather than system@okta.com
| count, sum(user_mfa_factor_update) as user_mfa_factor_update, sum(reset_password) as reset_password by target_user
| where user_mfa_factor_update>1 and reset_password>1
Unusual SSO app access
One of the behaviors that we often observe following initial access is the attacker exploring all of the applications the compromised account has access to. A user may have access to dozens of published applications, but usually, only access a small number of those apps daily.
The behavior of normal user application access looks very different than an attacker who has just gained access to a victim’s application portal SSO. Imagine the attacker drooling when they see SalesForce, GitHub, Confluence, Slack or PowerBI applications available for access! These applications are a goldmine and you can bet that an attacker will attempt to access as many of these applications as possible to discover what data they can steal.
User application access deviation
Let’s look for accounts that trigger a deviation for the number of distinct applications that are being accessed by an account. If a legitimate user normally accesses five apps a day, but we observe the account accessing 20 apps, that might be something worth noting.
Unauthorized app access attempts
An attacker that is engaging in discovery activity using compromised SSO credentials will likely attempt to access applications that the account does not have the authorization to access. These violations will often have an associated log event, which can be useful for defenders attempting to identify suspicious activity. We can use another CIP search to identify accounts that have attempted to access multiple applications that the account is not authorized to access.
| json field=_raw "actor.alternateId" as user
| json field=_raw "eventType" as event
| json field=_raw "target[0].displayName" as appName
| timeslice 3d
| values(appName) as appNames, values(event) as event_type, count_distinct(appName) as unique_count by user,_timeslice,appNames,event_type
| where unique_count >=2
Summary
Sumo Logic CIP makes easy work of slicing and dicing your SSO log data to identify potential signs of compromised credentials. Furthermore, Sumo Logic Cloud SIEM provides out-of-the-box security rules for normalized authentication log data and additional rules specific to SSO providers. Signals generated from these rules apply risk to entities, and Cloud SIEM automatically creates Insights if risk thresholds are exceeded. This provides customers with a powerful security solution they can easily adapt and custom tailor to their specific environment.
The searches shared above can be used to create dashboards for daily review, trigger email alerts based on various parameters to notify your security team of activity of interest, or best of all, send an event to Sumo Logic Cloud SIEM to contribute to an entity risk model.
To see for yourself, request a demo of Sumo Logic Cloud SIEM today or reach out directly to Sumo Logic.
About us
Sumo Logic Threat Labs and Sumo Logic Global Operations Center (GOC) are two distinct organizations within Sumo Logic partnering to safeguard Sumo Logic's customers, their data, and their organizations from emerging threats, inject security DNA throughout Sumo Logic, and contribute to the broader security community. We do this by monitoring threat activity to produce and distribute actionable intelligence, detection content and security guidance.
Complete visibility for DevSecOps
Reduce downtime and move from reactive to proactive monitoring.