Detection rules › Kusto

User Session Impersonation(Okta)

Status
available
Severity
medium
Time window
6h
Source
github.com/Azure/Azure-Sentinel

This query detects instances of user session impersonation, where an attacker successfully initiates a session impersonation event. The query extracts detailed information about the target user and the actor involved in the impersonation, providing insights into potential privilege escalation activities.

MITRE ATT&CK coverage

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule body

id: 35846296-4052-4de2-8098-beb6bb5f2203
name: User Session Impersonation(Okta)
description: |
  This query detects instances of user session impersonation, where an attacker successfully initiates a session impersonation event. The query extracts detailed information about the target user and the actor involved in the impersonation, providing insights into potential privilege escalation activities.
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: OktaSSO
    dataTypes:
      - Okta_CL
  - connectorId: OktaSSOv2
    dataTypes:
      - OktaSSO
queryFrequency: 6h
queryPeriod: 6h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - PrivilegeEscalation
relevantTechniques:
  - T1134
  - T1134.003
query: |
  OktaSSO
  | where eventType_s == "user.session.impersonation.initiate" and outcome_result_s == "SUCCESS"
  // Expand the JSON array in 'target_s' field to extract detailed information about the event
  | mv-expand parsed_json = todynamic(target_s) // Unpack and understand the details from the 'target_s' JSON array
  // Enhance visibility by extending columns with extracted details for better analysis
  | extend TargetUser_id = tostring(parsed_json.id), 
           TargetUser_type = tostring(parsed_json.type), 
           TargetUser_alternateId = tostring(parsed_json.alternateId), 
           TargetUser_displayName = tostring(parsed_json.displayName), 
           Target_detailEntry = tostring(parsed_json.detailEntry)
  // Filter out events with unknown target user IDs to focus on valid impersonation attempts
  | where isnotempty(TargetUser_alternateId) and TargetUser_alternateId != "unknown"
  // Project event details to gain insights into the security context, including actor and target user information
  | project TimeGenerated, actor_alternateId_s, actor_displayName_s, TargetUser_alternateId, TargetUser_displayName, TargetUser_type, TargetUser_id, eventType_s, outcome_result_s
  | extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountName
      - identifier: UPNSuffix
        columnName: AccountUPNSuffix
customDetails:
  ActorDisplayName: actor_displayName_s
  TargetUserAltId: TargetUser_alternateId
  TargetUserName: TargetUser_displayName
  TargetUserType: TargetUser_type
  EventType: eventType_s
alertDetailsOverride:
  alertDisplayNameFormat: 'Okta session impersonation by {{actor_displayName_s}} for {{TargetUser_displayName}}'
  alertDescriptionFormat: 'Okta user session impersonation succeeded. Actor {{actor_alternateId_s}} impersonated target {{TargetUser_alternateId}} during {{eventType_s}}.'
version: 1.1.1
kind: Scheduled

Stages and Predicates

Stage 1: source

OktaSSO

Stage 2: where

| where eventType_s == "user.session.impersonation.initiate" and outcome_result_s == "SUCCESS"

Stage 3: mv-expand

| mv-expand parsed_json = todynamic(target_s)

Stage 4: extend

| extend TargetUser_id = tostring(parsed_json.id), 
         TargetUser_type = tostring(parsed_json.type), 
         TargetUser_alternateId = tostring(parsed_json.alternateId), 
         TargetUser_displayName = tostring(parsed_json.displayName), 
         Target_detailEntry = tostring(parsed_json.detailEntry)

Stage 5: where

| where isnotempty(TargetUser_alternateId) and TargetUser_alternateId != "unknown"

Stage 6: project

| project TimeGenerated, actor_alternateId_s, actor_displayName_s, TargetUser_alternateId, TargetUser_displayName, TargetUser_type, TargetUser_id, eventType_s, outcome_result_s

Stage 7: extend

| extend AccountName = tostring(split(actor_alternateId_s, "@")[0]), AccountUPNSuffix = tostring(split(actor_alternateId_s, "@")[1])

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
TargetUser_alternateIdproject
TargetUser_displayNameproject
TargetUser_idproject
TargetUser_typeproject
TimeGeneratedproject
actor_alternateId_sproject
actor_displayName_sproject
eventType_sproject
outcome_result_sproject
AccountNameextend
AccountUPNSuffixextend