Zscaler - Shared ZPA session
| Id | 40a98355-0e52-479f-8c91-4ab659cba878 |
| Rulename | Zscaler - Shared ZPA session |
| Description | Detects shared ZPA session. |
| Severity | High |
| Tactics | InitialAccess |
| Techniques | T1078 T1133 |
| Required data connectors | CustomLogsAma |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 24h |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml |
| Version | 1.0.2 |
| Arm template | 40a98355-0e52-479f-8c91-4ab659cba878.json |
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
description: |
'Detects shared ZPA session.'
kind: Scheduled
tactics:
- InitialAccess
requiredDataConnectors:
- connectorId: CustomLogsAma
datatypes:
- ZPA_CL
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml
severity: High
name: Zscaler - Shared ZPA session
triggerThreshold: 0
queryPeriod: 24h
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
relevantTechniques:
- T1078
- T1133
id: 40a98355-0e52-479f-8c91-4ab659cba878
queryFrequency: 1h
status: Available
triggerOperator: gt
version: 1.0.2
entityMappings:
- entityType: Account
fieldMappings:
- columnName: AccountCustomEntity
identifier: Name
- entityType: IP
fieldMappings:
- columnName: IPCustomEntity
identifier: Address