Detection rules › Kusto

Zscaler - Shared ZPA session

Status
available
Severity
high
Time window
1d
Group by
DstUserName, NetworkSessionId, SrcIpAddr
Source
github.com/Azure/Azure-Sentinel

'Detects shared ZPA session.'

MITRE ATT&CK coverage

Rule body kusto

id: 40a98355-0e52-479f-8c91-4ab659cba878
name: Zscaler - Shared ZPA session
description: |
  'Detects shared ZPA session.'
severity: High
status: Available
requiredDataConnectors:
  - connectorId: CustomLogsAma
    datatypes:
      - ZPA_CL
queryFrequency: 1h
queryPeriod: 24h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1078
  - T1133
query: |
  let open_sessions =
  ZPAEvent
  | where DvcAction == 'open'
  | summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId
  | sort by timestampstart asc;
  let closed_sessions =
  ZPAEvent
  | where TimeGenerated > ago(1h)
  | where DvcAction == 'close'
  | summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId
  | sort by timestampend asc;
  open_sessions
  | join (closed_sessions) on DstUserName
  | sort by DstUserName, timestampstart
  | extend prev_session_closetime = prev(timestampend,1)
  | extend prev_session_starttime = prev(timestampstart,1)
  | extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)
  | extend prev_sessionuser = prev(DstUserName, 1) 
  | where DstUserName == prev_sessionuser
  | where SrcIpAddr != PreviousSrcIpAddr
  | where prev_session_closetime > timestampstart
  | project DstUserName, SrcIpAddr, PreviousSrcIpAddr
  | extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountCustomEntity
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
version: 1.0.2
kind: Scheduled

Stages and Predicates

Let binding: closed_sessions

let closed_sessions = ZPAEvent
| where TimeGenerated > ago(1h)
| where DvcAction == 'close'
| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId
| sort by timestampend asc;

The stages below define let open_sessions (the rule's main pipeline source).

Stage 1: source

ZPAEvent

Stage 2: where

| where DvcAction == 'open'

Stage 3: summarize

| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId

Stage 4: sort

| sort by timestampstart asc

The stages below run on open_sessions (the outer pipeline).

Stage 5: join

open_sessions
| join (closed_sessions) on DstUserName

Stage 6: sort

| sort by DstUserName, timestampstart

Stage 7: extend (4 consecutive steps)

| extend prev_session_closetime = prev(timestampend,1)
| extend prev_session_starttime = prev(timestampstart,1)
| extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)
| extend prev_sessionuser = prev(DstUserName, 1)

Stage 8: where

| where DstUserName == prev_sessionuser

Stage 9: where

| where SrcIpAddr != PreviousSrcIpAddr

Stage 10: where

| where prev_session_closetime > timestampstart

Stage 11: project

| project DstUserName, SrcIpAddr, PreviousSrcIpAddr

Stage 12: extend

| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
DstUserNameeq
  • prev_sessionuser transforms: cased
DvcActioneq
  • close transforms: cased
  • open transforms: cased
SrcIpAddrne
  • PreviousSrcIpAddr transforms: cased
prev_session_closetimegt
  • timestampstart transforms: cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
DstUserNameproject
PreviousSrcIpAddrproject
SrcIpAddrproject
AccountCustomEntityextend
IPCustomEntityextend