Okta Logs Decoded: Unveiling Identity Threats Through Threat Hunting

In the ever-evolving world of cybersecurity, staying steps ahead of potential threats is paramount. With identity becoming a key for an organization’s security program, we increasingly rely on Identity providers (IdP) like Okta for identity and access management, and for federating access to cloud services, systems, and critical SaaS applications. Therefore, the logs produced by these systems become a critical source of information that can help you detect and eliminate threats before they wreak havoc.

This blog post is your compass across a wide range of available Okta logs. Whether you’re a seasoned security professional or just getting started in the field, this step-by-step guide will empower you to turn raw data into actionable insights. We’ll explore:

  • Each Okta audit log, learning how to analyze and extract critical information from
  • How to uncover hidden threats, analyze their patterns, and respond effectively. From detection of brute force and MFA fatigue attempts to impossible traveler and privilege escalation techniques
  • A set of free tools the Rezonate team has provided you to collect, analyze, hunt, and detect identity threats faster and easier.

Understanding Okta Audit Logs

Okta’s System Log API records various system events related to an organization, providing an audit trail that can be used to understand platform activity and diagnose problems. The System Log API gives near real-time, read-only access, capturing a wide range of data types and the exact structure of each change. That being said, some data points are agnostic and appear in each log record.

Here is the log structure scheme, as defined in the Okta Documentation:

Event Structure Schema (Okta docs)

Every property in this log could be useful in certain use cases, but we highlighted some properties that you should focus on for most investigations and hunting scenarios:

UUIDUnique identifier for the event
PublishedEvent time
Event TypeDescribe the type of the event, from a list of ~850 event types
ActorDescribe the entity (user, app, client, etc.) that acts. It includes details like ID, type of actor, alternative ID (which is the user’s email address), and display name
ClientDescribes the client that issues the request that triggers an event. It provides contextual information about the user, such as HTTP user agent, geographical context, IP address, device type​​ , and network zone.
TargetDescribes the entity that an actor acts on, such as an app user or a sign-in token. It also includes details like ID, type, alternative ID, and display name.
Note that in some events, there could be more than one Target object, in these cases, it’s best to find the relevant target based on its type (AppInstance, AppUser, etc..)
Authentication ContextProvides context about the credentials provider and authentication type of the connection. Includes the externalSessionId which is the Session ID of the operating user.
Security ContextInclude context regarding the IP Address of the client. Useful data points within this object are isp (Internet Provider that the request was sent from) and asOrg (the organization that is associated with the asn)
Debug ContextInclude detailed, per event, context with additional information such as device hash (DtHash) or ThreatSuspected 
OutcomeInclude the result for the event (such as Login request), in the Result field and the reason for this result in the Reason field.

Accessing Okta Audit Logs

Okta keeps the data accessible for customers with a retention of 90 days, and during this period there are primarily two ways to access it:

1. Okta Admin Console

Via the Okta Admin Console, Administrative roles, enabled for management of policies, users, groups, and “Audit Log” reports, can use the interface by clicking “System Log” in the reporting menu:

Alternatively, the web interface can be accessed directly through the following URL
(replace OKTA_DOMAIN with your unique okta domain name)

https://{OKTA_DOMAIN}-admin.okta.com/report/system_log_2

Through the web interface, we can apply different filters on the event time or any of its properties, and see the results, and several statistics, directly from the console.

For example, in the query below we can see all of the activity against one specific application in the tenant – In this case, it’s AWS Client VPN. You can also see the different actors that performed the operations involving this target application.

Query results – Okta Admin Console

On top of the basic Search panel it is also possible to add combinations of filters for more specific criteria. In the example below, we are looking for all events performed by a specific user, against a specific application, which resulted in ALLOW. This can be achieved by clicking the “Advanced Filters”.

Advanced filters, Okta Query Log

After applying filters, it’s possible to either examine the details of each event or to export the filtered logs to a CSV file (by clicking on the Download CSV button). Note that this feature is limited to 200,000 results, so for bigger exports, the Okta System Log API is preferred.

2. Okta Admin Console

The Okta System Log API is the programmatic counterpart of the System Log UI, and it offers the ability to execute more advanced queries and filters against the Okta logs. Operating through this interface requires either OAuth integration with the okta.logs.read scope or Read-only API Key.

Here is an example of an API call, selecting all events of a specific type (user.session.end):

GET /api/v1/logs?filter=eventType eq "user.session.end" HTTP/1.1
Host: {OKTA_DOMAIN}
Accept: application/json
Content-Type: application/json
Authorization: SSWS {{apikey}}

The most common use case of operating through the API Interface would be to export batch data in real-time to another system, such as streaming logs into a SIEM or any other security product, to monitor and conduct introspection and audit​.  
One of the biggest advantages of exporting the data with the System Log API is to correlate the collected logs with other data sources, adding critical context and completeness of data making the advanced investigation a lot easier.

Rezonate real-time correlated information for users’ activities

3. Exporting The Logs

As mentioned, there is more than one way to get your hands on the relevant Okta logs and perform your threat-hunting actions on them. Exporting through the Admin Console is easy, yet size-limited while exporting the data through the API could be more tricky for beginners. To get around this limit, we have created a basic tool that allows you to export Okta logs into a file, based on a time frame. It can be downloaded directly from the Rezonate github repository.

Let the Hunt Begin

After we have exported the logs through one of the methods, we can get to work and start analyzing the data to start identifying potential risks and threats. For the hunting process, you can use any data analytics solution or database based on your  preferences, as long as it supports filtering and grouping of data.

In this section, we will guide you through some of the top-relevant threat scenarios to look out for, explaining them, marking the relevant Okta events, aligning to the specific MITRE ATT&CK technique, and including our own query in PostgreSQL query syntax.

Important to highlight that some of the hunting queries may have false positives, depending on the environment, and may need some adjustments to reduce noisy results.

Scenario 1 – Brute Force on an Okta User

A brute force attack on an Okta user involves an attacker repeatedly trying different passwords in an attempt to eventually guess correctly and gain unauthorized access. To hunt for any occurrence of this scenario, you can search for an actor that performed more than X failed login attempts on at least Y target user, failing or ending up with a successful login. In cases of failure, the activity may result in a user’s lockage, or Okta blocking the client IP. The same logic can be applied to two different types of events:

  • user.session.start – Search for traditional Brute Force attack
  • user.authentication.auth_via_richclient – Search for Brute Force attack that uses legacy authentication protocols. Legacy authentication does not support MFA and is thus being used to guess passwords on a large scale
Relevant Okta Eventsuser.session.start
user.authentication.auth_via_richclient
Query— Get users who failed to login from the same IP address at least 5 times
select count(id), “clientIpAddress”, “actorAlternateId”, min(time) as “firstEvent”, max(time) as “lastEvent”
from okta_logs
where “eventType” =’user.session.start’ and “actionResult”=’FAILURE’ and “resultReason” in (‘INVALID_CREDENTIALS’, ‘LOCKED_OUT’)
and “time” > now() -interval ‘1 day’
group by “clientIpAddress”, “actorAlternateId”
having count(id) >= 5
order by count desc

— For Each result, check if the source IP address managed to login to the target user AFTER the “lastEvent” time
MITRE TechniqueCredential Access | Brute Force | ATT&CK T1110

It’s also worth mentioning that based on the tenant  behavioral configuration Okta can also enrich each sign-in attempt with additional fields that add more context such as:

  • Threat Suspected 
  • New Device
  • New IP Address
  • New Geo Location  (Country\City\State)

Including these enrichments in the query can help reduce false positives and focus on the more relevant events.

Scenario 2 – MFA Push Notifications Fatigue

Okta MFA Push Notification Fatigue refers to user exhaustion or annoyance resulting from frequent multi-factor authentication (MFA) push notifications sent by Okta for verification purposes. In this scenario, we assume that an adversary has already compromised user credentials and start flooding the legitimate user with Push notifications, with the hope that the user will approve one of them by mistake. To hunt for this threat scenario, you can search for more than X MFA push notifications, within a short period of time, originating from the same IP address.

A successful MFA fatigue will also generate a user.authentication.auth_via_mfa event. This event will be logged after the targeted user was tricked to allow suspicious access.

Relevant Okta Eventssystem.push.send_factor_verify_push
user.authentication.auth_via_mfa
user.mfa.okta_verify.deny_push
Query— Generic
select count(id), “clientIpAddress”, “actorAlternateId”, min(time) as “firstEvent”, max(time) as “lastEvent”
from audit_log_okta_idp_entity
where “eventType” =’system.push.send_factor_verify_push’
and “time” > now() -interval ‘X hour’
group by “clientIpAddress”, “actorAlternateId”
having count(id) >= 5 — configurable number of MFA attempts
order by count desc

— Find FAILED MFA fatigue attempts that were denied by the user
select count(id), “clientIpAddress”, “actorAlternateId”, min(time) as “firstEvent”, max(time) as “lastEvent”
from audit_log_okta_idp_entity
where “eventType” =’user.mfa.okta_verify.deny_push’
and “time” > now() -interval ’24 days’
group by “clientIpAddress”, “actorAlternateId”
having count(id) >= 5
order by count desc
MITRE TechniqueCredential Access | Multi-Factor Authentication Request Generation | ATT&CK T1621

Scenario 3 – Okta ThreatInsight Detection

Okta ThreatInsight is a security module that aggregates sign-in activities meta-data across the Okta customer base to analyze and detect potentially malicious IP addresses and prevent credential-based attacks. It is also a great starting point to find an initial indication for identifying targeted attacks against specific identities in the organization’s directory.

Relevant Okta Eventssecurity.threat.detected
Queryselect min(time) as “first_event”, max(time) as “last_event”, “actorName”, “actorType”, “actorAlternateId”, “eventType”, “threatDetections”
from audit_log_okta_idp_entity aloie
where “eventType” =’security.threat.detected’
group by “actorName”, “actorType”, “actorAlternateId”, “eventType”, “threatDetections”
MITRE TechniqueCredential Access | Brute Force | ATT&CK T1110

Scenario 4 – Okta Session Hijacking

A Session Hijacking attack refers to a situation in which an attacker was able to get his hand on the browser cookies of an authenticated Okta user. This risk is mostly involving targeted attacks and includes either malware infection on the user endpoint or a man-in-a-middle (MITM) attack that hijacks the user’s traffic. (read more in this Okta Article). Okta’s dtHash serves as a useful tool for identifying stolen Okta sessions.

Okta’s dtHash, also known as the “de-identified token hash,” is a cryptographic hash function utilized to safeguard user identifiers within Okta sessions. Its purpose is to mitigate the risk of sensitive user information being compromised in the event of a data breach or unauthorized access to Okta’s portal or applications. For our hunting, we will search for a stolen Okta user’s session that is being utilized in a different geographical location. We will detect it by searching for a dtHash that has been used from multiple geo-locations.

Important Note – To enhance the effectiveness of detection, the session length limit plays a vital role. Okta recommends customers set a session length limit of 2 hours. It is worth noting that increasing the length limit raises the possibility of encountering false positives in the detection process.

Relevant Okta EventsEvery Okta event
Queryselect count(distinct “clientCountry”), “actorAlternateId”, “dtHash” from audit_log_okta_idp_entity
where “dtHash” is not null
group by “actorAlternateId”,”dtHash”
having count(distinct “clientCountry”) >1
MITRE TechniqueCollection | Browser Session Hijacking | ATT&CK T1185 

Scenario 5 – Okta Privilege Escalation via Impersonation

In this threat scenario, an Okta application administrator could impersonate another user by modifying an existing application assignment, specifically by editing the ‘User Name’ field used by Okta to identify users in the destination application. This manipulation allows the administrator to authenticate themselves as a different user in any federated application, presenting a risk of privilege escalation, especially in critical SaaS applications like AWS IAM Identity Center.

Relevant Okta EventsApplication.user_membership.change_username
Queryselect * from audit_log_okta_idp_entity aloie where “eventType” =’application.user_membership.change_username’
— For each result, check the target application. If the target application is relevant for this detection, the target AppUser is the field that we need to validate. An impersonation configuration was set if there’s a mismatch between the targetName and the targetAlternateId.
MITRE TechniquePersistence | Account Manipulation | ATT&CK T1098

Scenario 6 – Phishing Attempt (Blocked by FastPass)

FastPass is Okta’s passwordless solution designed to minimize friction for the end-user during the login process while protecting against real-time phishing attacks. By adding additional layers of context to the login process (such as managed device information) it allows Okta to identify potentially suspicious authentication flows and it automatically blocks them, generating an indicative log in the audit. We can use this event result to identify potentially compromised credentials of Okta identities.

Relevant Okta EventsUser.authentication.auth_via_mfa
Queryselect * from audit_log_okta_idp_entity aloie where “eventType” =’user.authentication.auth_via_mfa’ and “actionResult” =’FAILURE’ and “actionResult” = ‘FastPass declined phishing attempt’
MITRE TechniqueInitial Access | Phishing | ATT&CK T1566

Scenario 7 – Okta Impossible Traveler

Within the realm of threat hunting, the concept of the “impossible traveler” denotes a detection method employed to uncover compromised identities. Specifically, it involves identifying instances where an identity records successful login events from two distinct geographical locations within a brief time span, which may suggest a compromise.

To identify potentially compromised identities, conduct a search for users who have experienced successful sign-in events from different geographical locations within a short timeframe. It is recommended to exclude VPN and proxy addresses from the analysis to focus on genuine geographic variations and to avoid false positives.

If pre-configured properly, you can also use  Okta’s velocity within the triage process to elevate the suspicion level of a particular sign-in location over others. 

Relevant Okta EventsUser.session.start
Queryselect count(distinct “clientCountry”), “actorAlternateId” from audit_log_okta_idp_entity aloie where “eventType” =’user.session.start’
and “time” > now() -interval ‘1day’
group by “actorAlternateId”
having count(distinct “clientCountry”) > 1
MITRE TechniqueInitial Access | Valid Accounts | ATT&CK T1078

Scenario 8 – Cleartext Credentials Transfer Using SCIM 

The SCIM (System for Cross-domain Identity Management) protocol is a standardized method for managing user identities and provisioning them across different systems and applications. It simplifies user management by providing a common framework for creating, updating, and deleting user accounts, as well as managing user attributes and group memberships, across various platforms. One of Okta’s features allows setting a sync workflow, pushing any password changes to a target SCIM application. Configuring this requires Admin privileges to the Okta Console, so most likely to be a legitimate operation, yet, on rare occasions could be part of a hostile password-stealing attack by an insider.

To detect this, we can search for the credentials export activity, and check that all of the target applications are legitimate and intended.

Relevant Okta Eventsapp.user_management.push_okta_password_update
Queryselect * from audit_log_okta_idp_entity where “eventType” =’app.user_management.push_okta_password_update’
MITRE TechniqueCredential Access | Exploitation for Credential Access | ATT&CK T1212

Scenario 9 – Application Access Brute Force

When an attacker gains access to a compromised Okta user, they may attempt to use Okta’s portal to connect to various trusted applications. However, the attacker’s attempts to access multiple apps can be denied by authentication policy requirements that have not been satisfied, such as the absence of MFA. An attacker may try to access different applications one by one, until finding those that allow him to operate without additional factors or conditions.

To identify this behavior we will search for a user who has experienced multiple failed access attempts to different applications within a short time frame. This could raise a red flag and require a follow-up investigation of the user’s activity.

Relevant Okta Eventsapplication.policy.sign_on.deny_accesst
Queryselect count(targets.”targetId”), logs.”actorAlternateId”, logs.”clientIpAddress”, logs.”actorAlternateId”
from audit_log_okta_idp_entity logs, audit_log_target_okta_idp_entity targets
where “eventType”=’application.policy.sign_on.deny_access’
and targets.”auditLogId” = logs.”id”
and targets.”targetType” = ‘AppInstance’
and “time” > now() -interval ‘1 month’
group by “clientIpAddress”, “actorAlternateId”
having count(targets.”targetId”) >= 5
order by count desc
MITRE TechniqueCredential Access | Exploitation for Credential Access | ATT&CK T1212

On top of the scenarios mentioned above, there are more interesting events that can be used to hunt for threats in an Okta environment. These events are harder to rely on since they require having a deeper context of the regular activities in the organization to differentiate the legitimate operations from those that may be part of an attack.

For example, an API Token created by an administrative user. It could be malicious or legitimate, and requires triage for a verdict: 

  • Why did the user create this API key?
  • Is it part of any task associated with an active project? If not, 
  • Was it really the user, or is it a persistent action by a hostile actor?
Okta Event TypeDefinitionMITRE ATT&CK
user.session.access_admin_appOkta admin T1078
system.api_token.createAdministrative API Token CreatedT1098.001
user.account.privilege.grantgroup.privilege.grantAdministrative Privileges Assignment N/A
user.mfa.factor.*MFA Changes T1556
system.idp.lifecycle.create system.agent.ad.createAddition of external IdPT1556
policy.rule.*
policy.lifecycle.*
application.policy.*
Authentication Policy Changes.T1556
network_zone.rule.disabled
zone.*
Changes to Network ZonesT1556
user.account.report_suspicious_activity_by_enduserSuspicious Activity ReportedN/A
user.mfa.attempt_bypassAttempt to Bypass MFAN/A
security.request.blockedAccess from a Known-Bad IP was Blocked N/A
user.session.impersonation.initiateOkta Impersonation Session StartedN/A

To see how Rezonate can help detect risks and threats across your Okta infrastructure, contact us for more information or request a free demo.


Like this article? Follow us on LinkedIn.

Rezonate was recognized as a 2023 Gartner® Cool Vendor™ in Identity-First Security.  Learn More.