From 8a857db36cd3bb98038c8feb7a18bdb03541912a Mon Sep 17 00:00:00 2001 From: Alon Karmona Date: Tue, 20 Oct 2026 14:49:40 +0300 Subject: [PATCH] Migrate Zscaler Private Access (ZPA) (3.2.2) to Defender XDR Custom Detections (V3.1) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9f05623b-293a-427c-a28f-23d9b3fcc32c --- .../ZscalerSharedZPASession.yaml | 15 +- .../ZscalerUnexpectedCountEventResult.yaml | 15 +- .../ZscalerUnexpectedCountries.yaml | 15 +- .../ZscalerUnexpectedUpdateOperation.yaml | 23 +- .../ZscalerZPAConnectionsByDormantUser.yaml | 15 +- .../ZscalerZPAConnectionsByNewUser.yaml | 15 +- .../ZscalerZPAConnectionsFromNewCountry.yaml | 15 +- .../ZscalerZPAConnectionsFromNewIP.yaml | 15 +- ...ZPAConnectionsOutsideOperationalHours.yaml | 15 +- .../ZscalerZPAUnexpectedSessionDuration.yaml | 15 +- ...Solution_Zscaler Private Access (ZPA).json | 19 +- .../Package/3.2.2.zip | Bin 0 -> 25515 bytes .../Package/createUiDefinition.json | 50 +- .../Package/mainTemplate.json | 2248 ++++++++++++++++- .../Package/testParameters.json | 35 + .../ReleaseNotes.md | 1 + .../SolutionMetadata.json | 2 + .../ZscalerSharedZPASession.yaml | 125 + .../ZscalerUnexpectedCountEventResult.yaml | 139 + .../ZscalerUnexpectedCountries.yaml | 127 + .../ZscalerUnexpectedUpdateOperation.yaml | 129 + .../ZscalerZPAConnectionsByDormantUser.yaml | 117 + .../ZscalerZPAConnectionsByNewUser.yaml | 116 + .../ZscalerZPAConnectionsFromNewCountry.yaml | 119 + .../ZscalerZPAConnectionsFromNewIP.yaml | 109 + ...ZPAConnectionsOutsideOperationalHours.yaml | 139 + .../ZscalerZPAUnexpectedSessionDuration.yaml | 123 + 27 files changed, 3632 insertions(+), 124 deletions(-) create mode 100644 Solutions/Zscaler Private Access (ZPA)/Package/3.2.2.zip create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerSharedZPASession.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountEventResult.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountries.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedUpdateOperation.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByDormantUser.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByNewUser.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewCountry.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewIP.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsOutsideOperationalHours.yaml create mode 100644 Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAUnexpectedSessionDuration.yaml diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml index 1f1294768a4..67491175ffa 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerSharedZPASession.yaml @@ -6,7 +6,7 @@ severity: High status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 24h @@ -18,6 +18,19 @@ relevantTechniques: - T1078 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let open_sessions = ZPAEvent | where DvcAction == 'open' diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountEventResult.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountEventResult.yaml index 2f499ce68dc..d75886c07c2 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountEventResult.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountEventResult.yaml @@ -6,7 +6,7 @@ severity: High status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 1h @@ -18,6 +18,19 @@ relevantTechniques: - T1078 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let threshold = 1000; ZPAEvent | where EventResult has "REJECTED_BY_POLICY" diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountries.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountries.yaml index 1abbb9035db..2daee69c638 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountries.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedCountries.yaml @@ -6,7 +6,7 @@ severity: High status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 1h @@ -18,6 +18,19 @@ relevantTechniques: - T1190 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections ZPAEvent | where DvcAction == 'open' diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedUpdateOperation.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedUpdateOperation.yaml index 129e12a53d1..d97ed5b6195 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedUpdateOperation.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerUnexpectedUpdateOperation.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 1h @@ -18,6 +18,19 @@ relevantTechniques: - T1190 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; ZPAEvent | where isnotempty(AuditOperationType) | extend ExpectedVersion1 = extract(@'(expectedVersion":")([0-9]+)\.([0-9]+\.[0-9]+)', 2, AuditOldValue) @@ -33,5 +46,13 @@ entityMappings: fieldMappings: - identifier: ProcessId columnName: ProcessCustomEntity + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: DvcHostname + - entityType: IP + fieldMappings: + - identifier: Address + columnName: SrcIpAddr version: 1.0.2 kind: Scheduled diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByDormantUser.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByDormantUser.yaml index a3b966dde11..714dd50cb99 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByDormantUser.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByDormantUser.yaml @@ -6,7 +6,7 @@ severity: High status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 14d @@ -17,6 +17,19 @@ tactics: relevantTechniques: - T1078 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let dt_lastlogintime = 14d; let activeUsers = ZPAEvent diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByNewUser.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByNewUser.yaml index fd931f85280..d38e51c5765 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByNewUser.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsByNewUser.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 14d @@ -17,6 +17,19 @@ tactics: relevantTechniques: - T1078 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let listUsers = ZPAEvent | where TimeGenerated > ago(14d) diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewCountry.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewCountry.yaml index 84efacd61bb..565beda3830 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewCountry.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewCountry.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 14d @@ -18,6 +18,19 @@ relevantTechniques: - T1190 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let listCountries = ZPAEvent | where TimeGenerated > ago(14d) diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewIP.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewIP.yaml index c19e4be3f7a..3e5ec60e863 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewIP.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsFromNewIP.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 14d @@ -18,6 +18,19 @@ relevantTechniques: - T1078 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let listIPs = ZPAEvent | where TimeGenerated > ago(14d) diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsOutsideOperationalHours.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsOutsideOperationalHours.yaml index 71ac17e144f..deaa9b14efc 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsOutsideOperationalHours.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAConnectionsOutsideOperationalHours.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 1h @@ -18,6 +18,19 @@ relevantTechniques: - T1190 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; ZPAEvent | where DvcAction == 'open' | where datetime_part("Hour", todatetime(LogTimestamp)) between (datetime_part("Hour", todatetime('19:01:00.7654321')) .. datetime_part("Hour", todatetime('08:01:00.7654321'))) diff --git a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAUnexpectedSessionDuration.yaml b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAUnexpectedSessionDuration.yaml index 493b47c37d6..8fc411f2360 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAUnexpectedSessionDuration.yaml +++ b/Solutions/Zscaler Private Access (ZPA)/Analytic Rules/ZscalerZPAUnexpectedSessionDuration.yaml @@ -6,7 +6,7 @@ severity: Medium status: Available requiredDataConnectors: - connectorId: CustomLogsAma - datatypes: + dataTypes: - ZPA_CL queryFrequency: 1h queryPeriod: 24h @@ -18,6 +18,19 @@ relevantTechniques: - T1078 - T1133 query: | + let ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; let dt_lookBack = 24h; let time_treshhold = timespan(08:00:00); let open_sessions = diff --git a/Solutions/Zscaler Private Access (ZPA)/Data/Solution_Zscaler Private Access (ZPA).json b/Solutions/Zscaler Private Access (ZPA)/Data/Solution_Zscaler Private Access (ZPA).json index 2d919df5f32..5a0876104ab 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Data/Solution_Zscaler Private Access (ZPA).json +++ b/Solutions/Zscaler Private Access (ZPA)/Data/Solution_Zscaler Private Access (ZPA).json @@ -38,6 +38,19 @@ ], "Metadata": "SolutionMetadata.json", "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Zscaler Private Access (ZPA)", - "Version": "3.0.1", - "TemplateSpec": true -} \ No newline at end of file + "Version": "3.2.2", + "TemplateSpec": false, + "XDR Detections": [ + "XDR Detections/ZscalerSharedZPASession.yaml", + "XDR Detections/ZscalerUnexpectedCountEventResult.yaml", + "XDR Detections/ZscalerUnexpectedCountries.yaml", + "XDR Detections/ZscalerUnexpectedUpdateOperation.yaml", + "XDR Detections/ZscalerZPAConnectionsByDormantUser.yaml", + "XDR Detections/ZscalerZPAConnectionsByNewUser.yaml", + "XDR Detections/ZscalerZPAConnectionsFromNewCountry.yaml", + "XDR Detections/ZscalerZPAConnectionsFromNewIP.yaml", + "XDR Detections/ZscalerZPAConnectionsOutsideOperationalHours.yaml", + "XDR Detections/ZscalerZPAUnexpectedSessionDuration.yaml" + ], + "XDR Workbooks": [] +} diff --git a/Solutions/Zscaler Private Access (ZPA)/Package/3.2.2.zip b/Solutions/Zscaler Private Access (ZPA)/Package/3.2.2.zip new file mode 100644 index 0000000000000000000000000000000000000000..851fc11ecf507cf5bbc5a31ec648166cc8064d4e GIT binary patch literal 25515 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 literal 0 HcmV?d00001 diff --git a/Solutions/Zscaler Private Access (ZPA)/Package/createUiDefinition.json b/Solutions/Zscaler Private Access (ZPA)/Package/createUiDefinition.json index 7e8a50b88e0..ac304b00d1f 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Package/createUiDefinition.json +++ b/Solutions/Zscaler Private Access (ZPA)/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Zscaler%20Private%20Access%20%28ZPA%29/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Zscaler Private Access (ZPA)](https://www.zscaler.com/) solution provides the capability to ingest [Zscaler Private Access events](https://help.zscaler.com/zpa/what-zscaler-private-access) into Microsoft Sentinel.\n\n This solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation. \n\n **NOTE**: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on **Aug 31, 2024.** Using MMA and AMA on same machine can cause log duplication and extra ingestion cost [more details](https://learn.microsoft.com/azure/sentinel/ama-migrate?WT.mc_id=Portal-fx).\n\n**Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 10, **Hunting Queries:** 10\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Zscaler%20Private%20Access%20%28ZPA%29/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Zscaler Private Access (ZPA)](https://www.zscaler.com/) solution provides the capability to ingest [Zscaler Private Access events](https://help.zscaler.com/zpa/what-zscaler-private-access) into Microsoft Sentinel.\n\n This solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation. \n\n **NOTE**: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on **Aug 31, 2024.** Using MMA and AMA on same machine can cause log duplication and extra ingestion cost [more details](https://learn.microsoft.com/azure/sentinel/ama-migrate?WT.mc_id=Portal-fx).\n\n**Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 10, **XDR Detections:** 10, **Hunting Queries:** 10\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -51,6 +51,47 @@ } ], "steps": [ + { + "name": "contentSelection", + "label": "Content selection", + "elements": [ + { + "name": "DeployAnalyticsRule", + "type": "Microsoft.Common.CheckBox", + "label": "DeployAnalyticsRule", + "defaultValue": true, + "toolTip": "Deploy the Microsoft Sentinel analytic rules carried by this solution (ContentKind AnalyticsRule and its AnalyticsRuleTemplate registration face)." + }, + { + "name": "DeployWorkbook", + "type": "Microsoft.Common.CheckBox", + "label": "DeployWorkbook", + "defaultValue": true, + "toolTip": "Deploy the Microsoft Sentinel workbook content and its Content Hub registration carried by this solution (ContentKind Workbook and WorkbookTemplate)." + }, + { + "name": "DeployCustomDetection", + "type": "Microsoft.Common.CheckBox", + "label": "DeployCustomDetection", + "defaultValue": false, + "toolTip": "Deploy the XDR-native custom detection resources and their Content Hub registrations (ContentKind CustomDetection and CustomDetectionTemplate). Independent of DeployAnalyticsRule: both kinds can be selected together. Existing analytic-rule instances are not disabled or removed. CD enabled or disabled status is controlled separately from this deployment switch." + }, + { + "name": "DeployHuntingQuery", + "type": "Microsoft.Common.CheckBox", + "label": "DeployHuntingQuery", + "defaultValue": true, + "toolTip": "Deploy the Microsoft Sentinel hunting queries carried by this solution." + }, + { + "name": "DeployParser", + "type": "Microsoft.Common.CheckBox", + "label": "DeployParser", + "defaultValue": true, + "toolTip": "Deploy the parsers and their registrations carried by this solution." + } + ] + }, { "name": "workbooks", "label": "Workbooks", @@ -429,7 +470,12 @@ "outputs": { "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", "location": "[location()]", - "workspace": "[basics('workspace')]" + "workspace": "[basics('workspace')]", + "DeployAnalyticsRule": "[steps('contentSelection').DeployAnalyticsRule]", + "DeployWorkbook": "[steps('contentSelection').DeployWorkbook]", + "DeployCustomDetection": "[steps('contentSelection').DeployCustomDetection]", + "DeployHuntingQuery": "[steps('contentSelection').DeployHuntingQuery]", + "DeployParser": "[steps('contentSelection').DeployParser]" } } } diff --git a/Solutions/Zscaler Private Access (ZPA)/Package/mainTemplate.json b/Solutions/Zscaler Private Access (ZPA)/Package/mainTemplate.json index 6e5b0416548..85a081363c4 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Package/mainTemplate.json +++ b/Solutions/Zscaler Private Access (ZPA)/Package/mainTemplate.json @@ -35,13 +35,48 @@ "metadata": { "description": "Name for the workbook" } + }, + "DeployAnalyticsRule": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel analytic rules carried by this solution (ContentKind AnalyticsRule and its AnalyticsRuleTemplate registration face)." + } + }, + "DeployWorkbook": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel workbook content and its Content Hub registration carried by this solution (ContentKind Workbook and WorkbookTemplate)." + } + }, + "DeployCustomDetection": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Deploy the XDR-native custom detection resources and their Content Hub registrations (ContentKind CustomDetection and CustomDetectionTemplate). Independent of DeployAnalyticsRule: both kinds can be selected together. Existing analytic-rule instances are not disabled or removed. CD enabled or disabled status is controlled separately from this deployment switch." + } + }, + "DeployHuntingQuery": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel hunting queries carried by this solution." + } + }, + "DeployParser": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the parsers and their registrations carried by this solution." + } } }, "variables": { "email": "support@microsoft.com", "_email": "[variables('email')]", "_solutionName": "Zscaler Private Access (ZPA)", - "_solutionVersion": "3.0.4", + "_solutionVersion": "3.2.2", "solutionId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", "_solutionId": "[variables('solutionId')]", "workbookVersion1": "1.0.0", @@ -190,7 +225,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPA Workbook with template version 3.0.4", + "description": "ZscalerZPA Workbook with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion1')]", @@ -267,7 +302,8 @@ "contentProductId": "[variables('_workbookcontentProductId1')]", "id": "[variables('_workbookcontentProductId1')]", "version": "[variables('workbookVersion1')]" - } + }, + "condition": "[parameters('DeployWorkbook')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -278,7 +314,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerAbnormalTotalBytesSize_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerAbnormalTotalBytesSize_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject1').huntingQueryVersion1]", @@ -287,7 +323,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_1", "location": "[parameters('workspace-location')]", "properties": { @@ -352,7 +388,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject1')._huntingQuerycontentId1,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -363,7 +400,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerApplicationByUsers_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerApplicationByUsers_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject2').huntingQueryVersion2]", @@ -372,7 +409,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_2", "location": "[parameters('workspace-location')]", "properties": { @@ -437,7 +474,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject2')._huntingQuerycontentId2,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -448,7 +486,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerConnectionCloseReason_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerConnectionCloseReason_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject3').huntingQueryVersion3]", @@ -457,7 +495,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_3", "location": "[parameters('workspace-location')]", "properties": { @@ -522,7 +560,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject3')._huntingQuerycontentId3,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -533,7 +572,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerIPsByPorts_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerIPsByPorts_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject4').huntingQueryVersion4]", @@ -542,7 +581,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_4", "location": "[parameters('workspace-location')]", "properties": { @@ -607,7 +646,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject4')._huntingQuerycontentId4,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -618,7 +658,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerSourceLocation_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerSourceLocation_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject5').huntingQueryVersion5]", @@ -627,7 +667,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_5", "location": "[parameters('workspace-location')]", "properties": { @@ -692,7 +732,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject5')._huntingQuerycontentId5,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -703,7 +744,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerTopConnectors_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerTopConnectors_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject6').huntingQueryVersion6]", @@ -712,7 +753,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_6", "location": "[parameters('workspace-location')]", "properties": { @@ -777,7 +818,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject6')._huntingQuerycontentId6,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -788,7 +830,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerTopSourceIP_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerTopSourceIP_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject7').huntingQueryVersion7]", @@ -797,7 +839,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_7", "location": "[parameters('workspace-location')]", "properties": { @@ -862,7 +904,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject7')._huntingQuerycontentId7,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -873,7 +916,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUrlhostname_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerUrlhostname_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject8').huntingQueryVersion8]", @@ -882,7 +925,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_8", "location": "[parameters('workspace-location')]", "properties": { @@ -947,7 +990,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject8')._huntingQuerycontentId8,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject8')._huntingQuerycontentId8,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -958,7 +1002,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUserAccessGroups_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerUserAccessGroups_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject9').huntingQueryVersion9]", @@ -967,7 +1011,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_9", "location": "[parameters('workspace-location')]", "properties": { @@ -1032,7 +1076,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject9')._huntingQuerycontentId9,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject9')._huntingQuerycontentId9,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1043,7 +1088,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUserServerErrors_HuntingQueries Hunting Query with template version 3.0.4", + "description": "ZscalerUserServerErrors_HuntingQueries Hunting Query with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('huntingQueryObject10').huntingQueryVersion10]", @@ -1052,7 +1097,7 @@ "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "Zscaler_Private_Access_(ZPA)_Hunting_Query_10", "location": "[parameters('workspace-location')]", "properties": { @@ -1117,7 +1162,8 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject10')._huntingQuerycontentId10,'-', '1.0.0')))]", "id": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('huntingQueryObject10')._huntingQuerycontentId10,'-', '1.0.0')))]", "version": "1.0.0" - } + }, + "condition": "[parameters('DeployHuntingQuery')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1128,7 +1174,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZPAEvent Data Parser with template version 3.0.4", + "description": "ZPAEvent Data Parser with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserObject1').parserVersion1]", @@ -1137,7 +1183,7 @@ "resources": [ { "name": "[variables('parserObject1')._parserName1]", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "type": "Microsoft.OperationalInsights/workspaces/savedSearches", "location": "[parameters('workspace-location')]", "properties": { @@ -1198,11 +1244,12 @@ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.3')))]", "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.3')))]", "version": "[variables('parserObject1').parserVersion1]" - } + }, + "condition": "[parameters('DeployParser')]" }, { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "[variables('parserObject1')._parserName1]", "location": "[parameters('workspace-location')]", "properties": { @@ -1219,7 +1266,8 @@ "value": "" } ] - } + }, + "condition": "[parameters('DeployParser')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", @@ -1249,7 +1297,8 @@ "tier": "Microsoft", "link": "https://support.microsoft.com" } - } + }, + "condition": "[parameters('DeployParser')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1260,7 +1309,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerSharedZPASession_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerSharedZPASession_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", @@ -1277,7 +1326,7 @@ "description": "Detects shared ZPA session.", "displayName": "Zscaler - Shared ZPA session", "enabled": false, - "query": "let open_sessions =\nZPAEvent\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampstart asc;\nlet closed_sessions =\nZPAEvent\n| where TimeGenerated > ago(1h)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName\n| sort by DstUserName, timestampstart\n| extend prev_session_closetime = prev(timestampend,1)\n| extend prev_session_starttime = prev(timestampstart,1)\n| extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)\n| extend prev_sessionuser = prev(DstUserName, 1) \n| where DstUserName == prev_sessionuser\n| where SrcIpAddr != PreviousSrcIpAddr\n| where prev_session_closetime > timestampstart\n| project DstUserName, SrcIpAddr, PreviousSrcIpAddr\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet open_sessions =\nZPAEvent\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampstart asc;\nlet closed_sessions =\nZPAEvent\n| where TimeGenerated > ago(1h)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName\n| sort by DstUserName, timestampstart\n| extend prev_session_closetime = prev(timestampend,1)\n| extend prev_session_starttime = prev(timestampstart,1)\n| extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)\n| extend prev_sessionuser = prev(DstUserName, 1) \n| where DstUserName == prev_sessionuser\n| where SrcIpAddr != PreviousSrcIpAddr\n| where prev_session_closetime > timestampstart\n| project DstUserName, SrcIpAddr, PreviousSrcIpAddr\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "PT24H", "severity": "High", @@ -1288,7 +1337,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1306,8 +1355,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] }, @@ -1315,8 +1364,8 @@ "entityType": "IP", "fieldMappings": [ { - "columnName": "IPCustomEntity", - "identifier": "Address" + "identifier": "Address", + "columnName": "IPCustomEntity" } ] } @@ -1363,7 +1412,8 @@ "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1374,7 +1424,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUnexpectedCountEventResult_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerUnexpectedCountEventResult_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", @@ -1391,7 +1441,7 @@ "description": "Detects unexpected event count of rejects by policy.", "displayName": "Zscaler - Unexpected event count of rejects by policy", "enabled": false, - "query": "let threshold = 1000;\nZPAEvent\n| where EventResult has \"REJECTED_BY_POLICY\"\n| summarize rejected = count() by EventResult, DstUserName\n| where rejected > threshold\n| extend AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet threshold = 1000;\nZPAEvent\n| where EventResult has \"REJECTED_BY_POLICY\"\n| summarize rejected = count() by EventResult, DstUserName\n| where rejected > threshold\n| extend AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "PT1H", "severity": "High", @@ -1402,7 +1452,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1420,8 +1470,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] } @@ -1468,7 +1518,8 @@ "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1479,7 +1530,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUnexpectedCountries_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerUnexpectedCountries_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject3').analyticRuleVersion3]", @@ -1496,7 +1547,7 @@ "description": "Detects suspicious ZPA connections from forbidden countries.", "displayName": "Zscaler - Forbidden countries", "enabled": false, - "query": "let bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections\nZPAEvent \n| where DvcAction == 'open'\n| where SrcGeoCountry in~ (bl_countries)\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections\nZPAEvent \n| where DvcAction == 'open'\n| where SrcGeoCountry in~ (bl_countries)\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "PT1H", "severity": "High", @@ -1507,7 +1558,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1525,8 +1576,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] }, @@ -1534,8 +1585,8 @@ "entityType": "IP", "fieldMappings": [ { - "columnName": "IPCustomEntity", - "identifier": "Address" + "identifier": "Address", + "columnName": "IPCustomEntity" } ] } @@ -1582,7 +1633,8 @@ "contentProductId": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]", "id": "[variables('analyticRuleObject3')._analyticRulecontentProductId3]", "version": "[variables('analyticRuleObject3').analyticRuleVersion3]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1593,7 +1645,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerUnexpectedUpdateOperation_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerUnexpectedUpdateOperation_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject4').analyticRuleVersion4]", @@ -1610,7 +1662,7 @@ "description": "Detects unexpected version of update operation.", "displayName": "Zscaler - Unexpected update operation", "enabled": false, - "query": "ZPAEvent\n| where isnotempty(AuditOperationType)\n| extend ExpectedVersion1 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditOldValue)\n| extend ExpectedVersion2 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditOldValue)\n| extend NewVersion1 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditNewValue)\n| extend NewVersion2 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditNewValue)\n| extend Comparision1 = iff(tolong(ExpectedVersion2) > tolong(NewVersion2), 'Unexpected version', 'Expected version')\n| extend VersionCheck = iff(tolong(ExpectedVersion1) > tolong(NewVersion1), 'Unexpected version', Comparision1)\n| project-away ExpectedVersion1, ExpectedVersion2, NewVersion1, NewVersion2, Comparision1\n| extend ProcessCustomEntity = AuditOperationType\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nZPAEvent\n| where isnotempty(AuditOperationType)\n| extend ExpectedVersion1 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditOldValue)\n| extend ExpectedVersion2 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditOldValue)\n| extend NewVersion1 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditNewValue)\n| extend NewVersion2 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditNewValue)\n| extend Comparision1 = iff(tolong(ExpectedVersion2) > tolong(NewVersion2), 'Unexpected version', 'Expected version')\n| extend VersionCheck = iff(tolong(ExpectedVersion1) > tolong(NewVersion1), 'Unexpected version', Comparision1)\n| project-away ExpectedVersion1, ExpectedVersion2, NewVersion1, NewVersion2, Comparision1\n| extend ProcessCustomEntity = AuditOperationType\n", "queryFrequency": "PT1H", "queryPeriod": "PT1H", "severity": "Medium", @@ -1621,7 +1673,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1639,8 +1691,26 @@ "entityType": "Process", "fieldMappings": [ { - "columnName": "ProcessCustomEntity", - "identifier": "ProcessId" + "identifier": "ProcessId", + "columnName": "ProcessCustomEntity" + } + ] + }, + { + "entityType": "Host", + "fieldMappings": [ + { + "identifier": "HostName", + "columnName": "DvcHostname" + } + ] + }, + { + "entityType": "IP", + "fieldMappings": [ + { + "identifier": "Address", + "columnName": "SrcIpAddr" } ] } @@ -1687,7 +1757,8 @@ "contentProductId": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]", "id": "[variables('analyticRuleObject4')._analyticRulecontentProductId4]", "version": "[variables('analyticRuleObject4').analyticRuleVersion4]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1698,7 +1769,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAConnectionsByDormantUser_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAConnectionsByDormantUser_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject5').analyticRuleVersion5]", @@ -1715,7 +1786,7 @@ "description": "Detects ZPA connections by dormant user.", "displayName": "Zscaler - Connections by dormant user", "enabled": false, - "query": "let dt_lastlogintime = 14d;\nlet activeUsers =\nZPAEvent \n| where TimeGenerated > ago(dt_lastlogintime)\n| where DvcAction == 'open'\n| summarize lastLoginTime = max(TimeGenerated) by DstUserName\n| summarize makelist(DstUserName);\nZPAEvent\n| where DstUserName !in~ (activeUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lastlogintime = 14d;\nlet activeUsers =\nZPAEvent \n| where TimeGenerated > ago(dt_lastlogintime)\n| where DvcAction == 'open'\n| summarize lastLoginTime = max(TimeGenerated) by DstUserName\n| summarize makelist(DstUserName);\nZPAEvent\n| where DstUserName !in~ (activeUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "P14D", "severity": "High", @@ -1726,7 +1797,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1743,8 +1814,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] } @@ -1791,7 +1862,8 @@ "contentProductId": "[variables('analyticRuleObject5')._analyticRulecontentProductId5]", "id": "[variables('analyticRuleObject5')._analyticRulecontentProductId5]", "version": "[variables('analyticRuleObject5').analyticRuleVersion5]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1802,7 +1874,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAConnectionsByNewUser_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAConnectionsByNewUser_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject6').analyticRuleVersion6]", @@ -1819,7 +1891,7 @@ "description": "Detects ZPA connections by new user.", "displayName": "Zscaler - ZPA connections by new user", "enabled": false, - "query": "let listUsers =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofUsers = make_set(DstUserName) by DstUserName\n| project ListofUsers;\nZPAEvent\n| where DstUserName !in (listUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listUsers =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofUsers = make_set(DstUserName) by DstUserName\n| project ListofUsers;\nZPAEvent\n| where DstUserName !in (listUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "P14D", "severity": "Medium", @@ -1830,7 +1902,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1847,8 +1919,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] } @@ -1895,7 +1967,8 @@ "contentProductId": "[variables('analyticRuleObject6')._analyticRulecontentProductId6]", "id": "[variables('analyticRuleObject6')._analyticRulecontentProductId6]", "version": "[variables('analyticRuleObject6').analyticRuleVersion6]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -1906,7 +1979,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAConnectionsFromNewCountry_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAConnectionsFromNewCountry_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject7').analyticRuleVersion7]", @@ -1923,7 +1996,7 @@ "description": "Detects ZPA connections from new country.", "displayName": "Zscaler - ZPA connections from new country", "enabled": false, - "query": "let listCountries =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofCountries = make_set(SrcGeoCountry) by DstUserName\n| project ListofCountries;\nZPAEvent\n| where isnotempty(SrcGeoCountry)\n| where SrcGeoCountry !in (listCountries)\n| summarize EventCount = count() by DstUserName, SrcGeoCountry\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listCountries =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofCountries = make_set(SrcGeoCountry) by DstUserName\n| project ListofCountries;\nZPAEvent\n| where isnotempty(SrcGeoCountry)\n| where SrcGeoCountry !in (listCountries)\n| summarize EventCount = count() by DstUserName, SrcGeoCountry\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "P14D", "severity": "Medium", @@ -1934,7 +2007,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -1952,8 +2025,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] } @@ -2000,7 +2073,8 @@ "contentProductId": "[variables('analyticRuleObject7')._analyticRulecontentProductId7]", "id": "[variables('analyticRuleObject7')._analyticRulecontentProductId7]", "version": "[variables('analyticRuleObject7').analyticRuleVersion7]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -2011,7 +2085,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAConnectionsFromNewIP_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAConnectionsFromNewIP_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject8').analyticRuleVersion8]", @@ -2028,7 +2102,7 @@ "description": "Detects ZPA connections from new IP.", "displayName": "Zscaler - ZPA connections from new IP", "enabled": false, - "query": "let listIPs =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofIPs = make_set(SrcIpAddr) by DstUserName\n| project ListofIPs;\nZPAEvent\n| where isnotempty(SrcIpAddr)\n| where SrcIpAddr !in (listIPs)\n| summarize EventCount = count() by DstUserName, SrcIpAddr\n| project-away EventCount\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listIPs =\nZPAEvent \n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofIPs = make_set(SrcIpAddr) by DstUserName\n| project ListofIPs;\nZPAEvent\n| where isnotempty(SrcIpAddr)\n| where SrcIpAddr !in (listIPs)\n| summarize EventCount = count() by DstUserName, SrcIpAddr\n| project-away EventCount\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "P14D", "severity": "Medium", @@ -2039,7 +2113,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -2057,8 +2131,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] }, @@ -2066,8 +2140,8 @@ "entityType": "IP", "fieldMappings": [ { - "columnName": "IPCustomEntity", - "identifier": "Address" + "identifier": "Address", + "columnName": "IPCustomEntity" } ] } @@ -2114,7 +2188,8 @@ "contentProductId": "[variables('analyticRuleObject8')._analyticRulecontentProductId8]", "id": "[variables('analyticRuleObject8')._analyticRulecontentProductId8]", "version": "[variables('analyticRuleObject8').analyticRuleVersion8]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -2125,7 +2200,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAConnectionsOutsideOperationalHours_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAConnectionsOutsideOperationalHours_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject9').analyticRuleVersion9]", @@ -2142,7 +2217,7 @@ "description": "Detects ZAP connections outside operational hours.", "displayName": "Zscaler - ZPA connections outside operational hours", "enabled": false, - "query": "ZPAEvent \n| where DvcAction == 'open'\n| where datetime_part(\"Hour\", todatetime(LogTimestamp)) between (datetime_part(\"Hour\", todatetime('19:01:00.7654321')) .. datetime_part(\"Hour\", todatetime('08:01:00.7654321')))\n| summarize count() by DstUserName \n| project DstUserName\n| extend AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nZPAEvent \n| where DvcAction == 'open'\n| where datetime_part(\"Hour\", todatetime(LogTimestamp)) between (datetime_part(\"Hour\", todatetime('19:01:00.7654321')) .. datetime_part(\"Hour\", todatetime('08:01:00.7654321')))\n| summarize count() by DstUserName \n| project DstUserName\n| extend AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "PT1H", "severity": "Medium", @@ -2153,7 +2228,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -2171,8 +2246,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] } @@ -2219,7 +2294,8 @@ "contentProductId": "[variables('analyticRuleObject9')._analyticRulecontentProductId9]", "id": "[variables('analyticRuleObject9')._analyticRulecontentProductId9]", "version": "[variables('analyticRuleObject9').analyticRuleVersion9]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", @@ -2230,7 +2306,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ZscalerZPAUnexpectedSessionDuration_AnalyticalRules Analytics Rule with template version 3.0.4", + "description": "ZscalerZPAUnexpectedSessionDuration_AnalyticalRules Analytics Rule with template version 3.2.2", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleObject10').analyticRuleVersion10]", @@ -2247,7 +2323,7 @@ "description": "Detects Unexpected ZPA session duration.", "displayName": "Zscaler - Unexpected ZPA session duration", "enabled": false, - "query": "let dt_lookBack = 24h;\nlet time_treshhold = timespan(08:00:00);\nlet open_sessions =\nZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampstart asc;\nlet closed_sessions =\nZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName, SrcIpAddr, ConnectionID\n| extend duration = timestampend - timestampstart\n| where duration > time_treshhold\n| where DstUserName !has \"ZPA LSS\"\n| sort by timestampstart asc\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", + "query": "let ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lookBack = 24h;\nlet time_treshhold = timespan(08:00:00);\nlet open_sessions =\nZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampstart asc;\nlet closed_sessions =\nZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName, SrcIpAddr, ConnectionID\n| extend duration = timestampend - timestampstart\n| where duration > time_treshhold\n| where DstUserName !has \"ZPA LSS\"\n| sort by timestampstart asc\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName\n", "queryFrequency": "PT1H", "queryPeriod": "PT24H", "severity": "Medium", @@ -2258,7 +2334,7 @@ "status": "Available", "requiredDataConnectors": [ { - "datatypes": [ + "dataTypes": [ "ZPA_CL" ], "connectorId": "CustomLogsAma" @@ -2276,8 +2352,8 @@ "entityType": "Account", "fieldMappings": [ { - "columnName": "AccountCustomEntity", - "identifier": "Name" + "identifier": "Name", + "columnName": "AccountCustomEntity" } ] }, @@ -2285,8 +2361,8 @@ "entityType": "IP", "fieldMappings": [ { - "columnName": "IPCustomEntity", - "identifier": "Address" + "identifier": "Address", + "columnName": "IPCustomEntity" } ] } @@ -2333,19 +2409,20 @@ "contentProductId": "[variables('analyticRuleObject10')._analyticRulecontentProductId10]", "id": "[variables('analyticRuleObject10')._analyticRulecontentProductId10]", "version": "[variables('analyticRuleObject10').analyticRuleVersion10]" - } + }, + "condition": "[parameters('DeployAnalyticsRule')]" }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.0.4", + "version": "3.2.2", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "Zscaler Private Access (ZPA)", "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", - "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

The Zscaler Private Access (ZPA) solution provides the capability to ingest Zscaler Private Access events into Microsoft Sentinel.

\n

This solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation.

\n

NOTE: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on Aug 31, 2024. Using MMA and AMA on same machine can cause log duplication and extra ingestion cost more details.

\n

Parsers: 1, Workbooks: 1, Analytic Rules: 10, Hunting Queries: 10

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

The Zscaler Private Access (ZPA) solution provides the capability to ingest Zscaler Private Access events into Microsoft Sentinel.

\n

This solution is dependent on the Custom logs via AMA connector to collect the logs. The Custom logs solution will be installed as part of this solution installation.

\n

NOTE: Microsoft recommends installation of Custom logs via AMA Connector. Legacy connector uses the Log Analytics agent which were deprecated on Aug 31, 2024. Using MMA and AMA on same machine can cause log duplication and extra ingestion cost more details.

\n

Parsers: 1, Workbooks: 1, Analytic Rules: 10, XDR Detections: 10, Hunting Queries: 10

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -2482,6 +2559,56 @@ { "kind": "Solution", "contentId": "azuresentinel.azure-sentinel-solution-customlogsviaama" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-40a98355-0e52-479f-8c91-4ab659cba878", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-593e3e2a-43ce-11ec-81d3-0242ac130003", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-672e2846-4226-11ec-81d3-0242ac130003", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-c4902121-7a7e-44d1-810b-88d26db622ff", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-24f0779d-3927-403a-aac1-cc8791653606", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3", + "version": "3.2.1" + }, + { + "kind": "CustomDetection", + "contentId": "xdr-e07846e0-43ad-11ec-81d3-0242ac130003", + "version": "3.2.1" } ] }, @@ -2496,6 +2623,1909 @@ } }, "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-40a98355-0e52-479f-8c91-512a4bd1", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Shared ZPA session", + "id": "[if(true(), 'xdr-40a98355-0e52-479f-8c91-4ab659cba878', 'xdr-40a98355-0e52-479f-8c91-4ab659cba878')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects shared ZPA session.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Shared ZPA session" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet open_sessions =\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampstart asc;\nlet closed_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(1h)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName\n| sort by DstUserName, timestampstart\n| extend prev_session_closetime = prev(timestampend,1)\n| extend prev_session_starttime = prev(timestampstart,1)\n| extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)\n| extend prev_sessionuser = prev(DstUserName, 1)\n| where DstUserName == prev_sessionuser\n| where SrcIpAddr != PreviousSrcIpAddr\n| where prev_session_closetime > timestampstart\n| project DstUserName, SrcIpAddr, PreviousSrcIpAddr\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-40a98355-0e52-479f-8c91-4ab659cba878", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-40a98355-0e52-479f-8c91-4ab659cba878')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-40a98355-0e52-479f-8c91-512a4bd1')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects shared ZPA session.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Shared ZPA session", + "id": "[if(true(), 'xdr-40a98355-0e52-479f-8c91-4ab659cba878', 'xdr-40a98355-0e52-479f-8c91-4ab659cba878')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects shared ZPA session.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Shared ZPA session" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet open_sessions =\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampstart asc;\nlet closed_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(1h)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName\n| sort by DstUserName, timestampstart\n| extend prev_session_closetime = prev(timestampend,1)\n| extend prev_session_starttime = prev(timestampstart,1)\n| extend PreviousSrcIpAddr = prev(SrcIpAddr, 1)\n| extend prev_sessionuser = prev(DstUserName, 1)\n| where DstUserName == prev_sessionuser\n| where SrcIpAddr != PreviousSrcIpAddr\n| where prev_session_closetime > timestampstart\n| project DstUserName, SrcIpAddr, PreviousSrcIpAddr\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-40a98355-0e52-479f-8c91-4ab659cba878", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-40a98355-0e52-479f-8c91-4ab659cba878", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Shared ZPA session", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-40a98355-0e52-479f-8c91-4ab659cba878','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-40a98355-0e52-479f-8c91-4ab659cba878','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-40a98355-0e52-479f-8c91-4ab659cba878", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-593e3e2a-43ce-11ec-81d3-e727cd6d", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected event count of rejects by policy", + "id": "[if(true(), 'xdr-593e3e2a-43ce-11ec-81d3-0242ac130003', 'xdr-593e3e2a-43ce-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "description": "'Detects unexpected event count of rejects by policy.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Unexpected event count of rejects by policy" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet threshold = 1000;\n__xdr_inline_ZPAEvent\n| where EventResult has \"REJECTED_BY_POLICY\"\n| summarize rejected = count() by EventResult, DstUserName\n| where rejected > threshold\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-593e3e2a-43ce-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-593e3e2a-43ce-11ec-81d3-0242ac130003')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-593e3e2a-43ce-11ec-81d3-e727cd6d')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects unexpected event count of rejects by policy.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected event count of rejects by policy", + "id": "[if(true(), 'xdr-593e3e2a-43ce-11ec-81d3-0242ac130003', 'xdr-593e3e2a-43ce-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "description": "'Detects unexpected event count of rejects by policy.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Unexpected event count of rejects by policy" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet threshold = 1000;\n__xdr_inline_ZPAEvent\n| where EventResult has \"REJECTED_BY_POLICY\"\n| summarize rejected = count() by EventResult, DstUserName\n| where rejected > threshold\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-593e3e2a-43ce-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-593e3e2a-43ce-11ec-81d3-0242ac130003", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Unexpected event count of rejects by policy", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-593e3e2a-43ce-11ec-81d3-0242ac130003','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-593e3e2a-43ce-11ec-81d3-0242ac130003','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-593e3e2a-43ce-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-b3d112b4-3e1e-11ec-9bbc-fab01e32", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Forbidden countries", + "id": "[if(true(), 'xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002', 'xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects suspicious ZPA connections from forbidden countries.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Forbidden countries" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| where SrcGeoCountry in~ (bl_countries)\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-b3d112b4-3e1e-11ec-9bbc-fab01e32')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects suspicious ZPA connections from forbidden countries.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Forbidden countries", + "id": "[if(true(), 'xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002', 'xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects suspicious ZPA connections from forbidden countries.'", + "severity": "high", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Forbidden countries" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| where SrcGeoCountry in~ (bl_countries)\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Forbidden countries", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-672e2846-4226-11ec-81d3-6e1c7ad8", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected update operation", + "id": "[if(true(), 'xdr-672e2846-4226-11ec-81d3-0242ac130003', 'xdr-672e2846-4226-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects unexpected version of update operation.'", + "title": "Zscaler - Unexpected update operation", + "entityMappings": { + "hosts": [ + { + "nameColumn": "DvcHostname", + "id": "[if(true(), 'host1', 'host1')]" + } + ], + "ips": [ + { + "addressColumn": "SrcIpAddr", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\n__xdr_inline_ZPAEvent\n| where isnotempty(AuditOperationType)\n| extend ExpectedVersion1 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditOldValue)\n| extend ExpectedVersion2 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditOldValue)\n| extend NewVersion1 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditNewValue)\n| extend NewVersion2 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditNewValue)\n| extend Comparision1 = iff(tolong(ExpectedVersion2) > tolong(NewVersion2), 'Unexpected version', 'Expected version')\n| extend VersionCheck = iff(tolong(ExpectedVersion1) > tolong(NewVersion1), 'Unexpected version', Comparision1)\n| project-away ExpectedVersion1, ExpectedVersion2, NewVersion1, NewVersion2, Comparision1\n| extend ProcessCustomEntity = AuditOperationType" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-672e2846-4226-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-672e2846-4226-11ec-81d3-0242ac130003')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-672e2846-4226-11ec-81d3-6e1c7ad8')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects unexpected version of update operation.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected update operation", + "id": "[if(true(), 'xdr-672e2846-4226-11ec-81d3-0242ac130003', 'xdr-672e2846-4226-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects unexpected version of update operation.'", + "title": "Zscaler - Unexpected update operation", + "entityMappings": { + "hosts": [ + { + "nameColumn": "DvcHostname", + "id": "[if(true(), 'host1', 'host1')]" + } + ], + "ips": [ + { + "addressColumn": "SrcIpAddr", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\n__xdr_inline_ZPAEvent\n| where isnotempty(AuditOperationType)\n| extend ExpectedVersion1 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditOldValue)\n| extend ExpectedVersion2 = extract(@'(expectedVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditOldValue)\n| extend NewVersion1 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 2, AuditNewValue)\n| extend NewVersion2 = extract(@'(\"currentVersion\":\")([0-9]+)\\.([0-9]+\\.[0-9]+)', 3, AuditNewValue)\n| extend Comparision1 = iff(tolong(ExpectedVersion2) > tolong(NewVersion2), 'Unexpected version', 'Expected version')\n| extend VersionCheck = iff(tolong(ExpectedVersion1) > tolong(NewVersion1), 'Unexpected version', Comparision1)\n| project-away ExpectedVersion1, ExpectedVersion2, NewVersion1, NewVersion2, Comparision1\n| extend ProcessCustomEntity = AuditOperationType" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-672e2846-4226-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-672e2846-4226-11ec-81d3-0242ac130003", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Unexpected update operation", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-672e2846-4226-11ec-81d3-0242ac130003','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-672e2846-4226-11ec-81d3-0242ac130003','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-672e2846-4226-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-66bc77ee-3e45-11ec-9bbc-ca2af235", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Connections by dormant user", + "id": "[if(true(), 'xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002', 'xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + } + ], + "tactic": "Persistence" + } + ], + "description": "'Detects ZPA connections by dormant user.'", + "title": "Zscaler - Connections by dormant user", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "high" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lastlogintime = 14d;\nlet activeUsers =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lastlogintime)\n| where DvcAction == 'open'\n| summarize lastLoginTime = max(TimeGenerated) by DstUserName\n| summarize makelist(DstUserName);\n__xdr_inline_ZPAEvent\n| where DstUserName !in~ (activeUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-66bc77ee-3e45-11ec-9bbc-ca2af235')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects ZPA connections by dormant user.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Connections by dormant user", + "id": "[if(true(), 'xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002', 'xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + } + ], + "tactic": "Persistence" + } + ], + "description": "'Detects ZPA connections by dormant user.'", + "title": "Zscaler - Connections by dormant user", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "high" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lastlogintime = 14d;\nlet activeUsers =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lastlogintime)\n| where DvcAction == 'open'\n| summarize lastLoginTime = max(TimeGenerated) by DstUserName\n| summarize makelist(DstUserName);\n__xdr_inline_ZPAEvent\n| where DstUserName !in~ (activeUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Connections by dormant user", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-236a7ec1-0120-40f2-a157-e9e8f753", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections by new user", + "id": "[if(true(), 'xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb', 'xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + } + ], + "tactic": "Persistence" + } + ], + "description": "'Detects ZPA connections by new user.'", + "title": "Zscaler - ZPA connections by new user", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listUsers =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofUsers = make_set(DstUserName) by DstUserName\n| project ListofUsers;\n__xdr_inline_ZPAEvent\n| where DstUserName !in (listUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-236a7ec1-0120-40f2-a157-e9e8f753')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects ZPA connections by new user.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections by new user", + "id": "[if(true(), 'xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb', 'xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + } + ], + "tactic": "Persistence" + } + ], + "description": "'Detects ZPA connections by new user.'", + "title": "Zscaler - ZPA connections by new user", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listUsers =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofUsers = make_set(DstUserName) by DstUserName\n| project ListofUsers;\n__xdr_inline_ZPAEvent\n| where DstUserName !in (listUsers)\n| summarize EventCount = count() by DstUserName\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb", + "contentKind": "CustomDetection", + "displayName": "Zscaler - ZPA connections by new user", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-c4902121-7a7e-44d1-810b-709588d9", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections from new country", + "id": "[if(true(), 'xdr-c4902121-7a7e-44d1-810b-88d26db622ff', 'xdr-c4902121-7a7e-44d1-810b-88d26db622ff')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects ZPA connections from new country.'", + "title": "Zscaler - ZPA connections from new country", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listCountries =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofCountries = make_set(SrcGeoCountry) by DstUserName\n| project ListofCountries;\n__xdr_inline_ZPAEvent\n| where isnotempty(SrcGeoCountry)\n| where SrcGeoCountry !in (listCountries)\n| summarize EventCount = count() by DstUserName, SrcGeoCountry\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-c4902121-7a7e-44d1-810b-88d26db622ff", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-c4902121-7a7e-44d1-810b-88d26db622ff')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-c4902121-7a7e-44d1-810b-709588d9')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects ZPA connections from new country.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections from new country", + "id": "[if(true(), 'xdr-c4902121-7a7e-44d1-810b-88d26db622ff', 'xdr-c4902121-7a7e-44d1-810b-88d26db622ff')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects ZPA connections from new country.'", + "title": "Zscaler - ZPA connections from new country", + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listCountries =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofCountries = make_set(SrcGeoCountry) by DstUserName\n| project ListofCountries;\n__xdr_inline_ZPAEvent\n| where isnotempty(SrcGeoCountry)\n| where SrcGeoCountry !in (listCountries)\n| summarize EventCount = count() by DstUserName, SrcGeoCountry\n| project-away EventCount\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-c4902121-7a7e-44d1-810b-88d26db622ff", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-c4902121-7a7e-44d1-810b-88d26db622ff", + "contentKind": "CustomDetection", + "displayName": "Zscaler - ZPA connections from new country", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-c4902121-7a7e-44d1-810b-88d26db622ff','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-c4902121-7a7e-44d1-810b-88d26db622ff','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-c4902121-7a7e-44d1-810b-88d26db622ff", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-24f0779d-3927-403a-aac1-4598636e", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections from new IP", + "id": "[if(true(), 'xdr-24f0779d-3927-403a-aac1-cc8791653606', 'xdr-24f0779d-3927-403a-aac1-cc8791653606')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects ZPA connections from new IP.'", + "title": "Zscaler - ZPA connections from new IP", + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listIPs =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofIPs = make_set(SrcIpAddr) by DstUserName\n| project ListofIPs;\n__xdr_inline_ZPAEvent\n| where isnotempty(SrcIpAddr)\n| where SrcIpAddr !in (listIPs)\n| summarize EventCount = count() by DstUserName, SrcIpAddr\n| project-away EventCount\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-24f0779d-3927-403a-aac1-cc8791653606", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-24f0779d-3927-403a-aac1-cc8791653606')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-24f0779d-3927-403a-aac1-4598636e')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects ZPA connections from new IP.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections from new IP", + "id": "[if(true(), 'xdr-24f0779d-3927-403a-aac1-cc8791653606', 'xdr-24f0779d-3927-403a-aac1-cc8791653606')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "description": "'Detects ZPA connections from new IP.'", + "title": "Zscaler - ZPA connections from new IP", + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "severity": "medium" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet listIPs =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(14d)\n| where DvcAction == 'open'\n| summarize ListofIPs = make_set(SrcIpAddr) by DstUserName\n| project ListofIPs;\n__xdr_inline_ZPAEvent\n| where isnotempty(SrcIpAddr)\n| where SrcIpAddr !in (listIPs)\n| summarize EventCount = count() by DstUserName, SrcIpAddr\n| project-away EventCount\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-24f0779d-3927-403a-aac1-cc8791653606", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-24f0779d-3927-403a-aac1-cc8791653606", + "contentKind": "CustomDetection", + "displayName": "Zscaler - ZPA connections from new IP", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-24f0779d-3927-403a-aac1-cc8791653606','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-24f0779d-3927-403a-aac1-cc8791653606','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-24f0779d-3927-403a-aac1-cc8791653606", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-2859ad22-46c8-4cc7-ad7b-f1ded155", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections outside operational hours", + "id": "[if(true(), 'xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3', 'xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "description": "'Detects ZAP connections outside operational hours.'", + "severity": "medium", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - ZPA connections outside operational hours" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| where datetime_part(\"Hour\", todatetime(LogTimestamp)) between (datetime_part(\"Hour\", todatetime('19:01:00.7654321')) .. datetime_part(\"Hour\", todatetime('08:01:00.7654321')))\n| summarize count() by DstUserName\n| project DstUserName\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-2859ad22-46c8-4cc7-ad7b-f1ded155')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects ZAP connections outside operational hours.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - ZPA connections outside operational hours", + "id": "[if(true(), 'xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3', 'xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1190" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "accounts": [ + { + "upnColumn": "AccountCustomEntity", + "id": "[if(true(), 'account1', 'account1')]" + } + ] + }, + "description": "'Detects ZAP connections outside operational hours.'", + "severity": "medium", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - ZPA connections outside operational hours" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\n__xdr_inline_ZPAEvent\n| where DvcAction == 'open'\n| where datetime_part(\"Hour\", todatetime(LogTimestamp)) between (datetime_part(\"Hour\", todatetime('19:01:00.7654321')) .. datetime_part(\"Hour\", todatetime('08:01:00.7654321')))\n| summarize count() by DstUserName\n| project DstUserName\n| extend AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3", + "contentKind": "CustomDetection", + "displayName": "Zscaler - ZPA connections outside operational hours", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "ZscalerPrivateAccessZPA-CD-xdr-e07846e0-43ad-11ec-81d3-a8b76b66", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected ZPA session duration", + "id": "[if(true(), 'xdr-e07846e0-43ad-11ec-81d3-0242ac130003', 'xdr-e07846e0-43ad-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects Unexpected ZPA session duration.'", + "severity": "medium", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Unexpected ZPA session duration" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lookBack = 24h;\nlet time_treshhold = timespan(08:00:00);\nlet open_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampstart asc;\nlet closed_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName, SrcIpAddr, ConnectionID\n| extend duration = timestampend - timestampstart\n| where duration > time_treshhold\n| where DstUserName !has \"ZPA LSS\"\n| sort by timestampstart asc\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-e07846e0-43ad-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-cd-',uniquestring('xdr-e07846e0-43ad-11ec-81d3-0242ac130003')))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'ZscalerPrivateAccessZPA-CD-xdr-e07846e0-43ad-11ec-81d3-a8b76b66')]", + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "'Detects Unexpected ZPA session duration.'", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0", + "imports": { + "MicrosoftSecurity": { + "provider": "MicrosoftSecurity", + "version": "1.0.0" + } + }, + "resources": { + "detectionRule": { + "import": "MicrosoftSecurity", + "type": "Microsoft.Security/detectionRules@2026-06-01-preview", + "properties": { + "displayName": "Zscaler - Unexpected ZPA session duration", + "id": "[if(true(), 'xdr-e07846e0-43ad-11ec-81d3-0242ac130003', 'xdr-e07846e0-43ad-11ec-81d3-0242ac130003')]", + "status": "disabled", + "schedule": { + "frequency": "PT1H" + }, + "detectionAction": { + "alertTemplate": { + "tactics": [ + { + "techniques": [ + { + "technique": "T1078" + }, + { + "technique": "T1133" + } + ], + "tactic": "InitialAccess" + } + ], + "entityMappings": { + "ips": [ + { + "addressColumn": "IPCustomEntity", + "id": "[if(true(), 'ip1', 'ip1')]" + } + ] + }, + "description": "'Detects Unexpected ZPA session duration.'", + "severity": "medium", + "customDetails": { + "AccountName": "AccountCustomEntity" + }, + "title": "Zscaler - Unexpected ZPA session duration" + } + }, + "queryCondition": { + "queryText": "let __xdr_inline_ZPAEvent = () {\nZPA_CL\n| extend EventVendor=\"Zscaler\",\n EventProduct=\"Private Access\"\n| parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='\"')\n| extend\n EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')),\n DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')),\n DstUserName=column_ifexists('Username', column_ifexists('User', '')),\n DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))),\n SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')),\n DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', ''))\n};\nlet dt_lookBack = 24h;\nlet time_treshhold = timespan(08:00:00);\nlet open_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'open'\n| summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampstart asc;\nlet closed_sessions =\n__xdr_inline_ZPAEvent\n| where TimeGenerated > ago(dt_lookBack)\n| where DvcAction == 'close'\n| summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID\n| sort by timestampend asc;\nopen_sessions\n| join (closed_sessions) on DstUserName, SrcIpAddr, ConnectionID\n| extend duration = timestampend - timestampstart\n| where duration > time_treshhold\n| where DstUserName !has \"ZPA LSS\"\n| sort by timestampstart asc\n| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName" + }, + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-e07846e0-43ad-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1" + } + } + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "xdr-e07846e0-43ad-11ec-81d3-0242ac130003", + "contentKind": "CustomDetection", + "displayName": "Zscaler - Unexpected ZPA session duration", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-e07846e0-43ad-11ec-81d3-0242ac130003','-','3.2.1')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','cd','-', uniqueString(concat(variables('_solutionId'),'-','CustomDetection','-','xdr-e07846e0-43ad-11ec-81d3-0242ac130003','-','3.2.1')))]", + "version": "3.2.1", + "contentProvenance": { + "packageId": "azuresentinel.azure-sentinel-solution-zscalerprivateaccess", + "packageVersion": "3.2.2", + "contentId": "xdr-e07846e0-43ad-11ec-81d3-0242ac130003", + "contentVersion": "3.2.1", + "requiredWorkloads": [ + { + "dataTypes": [ + "ZPA_CL" + ], + "workload": "sentinel" + } + ], + "requiredDataConnectors": [ + { + "connectorId": "CustomLogsAma", + "dataTypes": [ + "ZPA_CL" + ] + } + ] + } + }, + "condition": "[parameters('DeployCustomDetection')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "pid-74737941-60e1-46cc-98a4-baecc69491f0-partnercenter", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } } ], "outputs": {} diff --git a/Solutions/Zscaler Private Access (ZPA)/Package/testParameters.json b/Solutions/Zscaler Private Access (ZPA)/Package/testParameters.json index 6e6eb31e05a..922cc8ca081 100644 --- a/Solutions/Zscaler Private Access (ZPA)/Package/testParameters.json +++ b/Solutions/Zscaler Private Access (ZPA)/Package/testParameters.json @@ -28,5 +28,40 @@ "metadata": { "description": "Name for the workbook" } + }, + "DeployAnalyticsRule": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel analytic rules carried by this solution (ContentKind AnalyticsRule and its AnalyticsRuleTemplate registration face)." + } + }, + "DeployWorkbook": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel workbook content and its Content Hub registration carried by this solution (ContentKind Workbook and WorkbookTemplate)." + } + }, + "DeployCustomDetection": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Deploy the XDR-native custom detection resources and their Content Hub registrations (ContentKind CustomDetection and CustomDetectionTemplate). Independent of DeployAnalyticsRule: both kinds can be selected together. Existing analytic-rule instances are not disabled or removed. CD enabled or disabled status is controlled separately from this deployment switch." + } + }, + "DeployHuntingQuery": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the Microsoft Sentinel hunting queries carried by this solution." + } + }, + "DeployParser": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Deploy the parsers and their registrations carried by this solution." + } } } diff --git a/Solutions/Zscaler Private Access (ZPA)/ReleaseNotes.md b/Solutions/Zscaler Private Access (ZPA)/ReleaseNotes.md index 8fc2a085452..0083e72e717 100644 --- a/Solutions/Zscaler Private Access (ZPA)/ReleaseNotes.md +++ b/Solutions/Zscaler Private Access (ZPA)/ReleaseNotes.md @@ -1,5 +1,6 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|--------------------------------------------------------------------| +| 3.2.2 | 20-04-2026 | Added 10 Defender XDR Custom Detections migrated from the existing Analytic Rules and hybrid V3.1 solution packaging. | | 3.0.4 | 12-01-2026 | Updated the **ZscalerZPAUnexpectedSessionDuration** Analytic Rule | | 3.0.3 | 28-08-2025 | The parser query now includes additional fields such as SessionID, IPProtocol, ClientCountryCode, and others, improving event parsing and enrichment. | | 3.0.2 | 08-07-2025 | Enhanced **Parser** logic to improve result filtering. | diff --git a/Solutions/Zscaler Private Access (ZPA)/SolutionMetadata.json b/Solutions/Zscaler Private Access (ZPA)/SolutionMetadata.json index f4ea606673c..e8d6e08dc4f 100644 --- a/Solutions/Zscaler Private Access (ZPA)/SolutionMetadata.json +++ b/Solutions/Zscaler Private Access (ZPA)/SolutionMetadata.json @@ -1,7 +1,9 @@ { + "trackingId": "pid-74737941-60e1-46cc-98a4-baecc69491f0-partnercenter", "publisherId": "azuresentinel", "offerId": "azure-sentinel-solution-zscalerprivateaccess", "firstPublishDate": "2022-01-31", + "version": "3.2.2", "providers": ["Zscaler"], "categories": { "domains" : ["Security - Network"] diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerSharedZPASession.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerSharedZPASession.yaml new file mode 100644 index 00000000000..0e56ad6d318 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerSharedZPASession.yaml @@ -0,0 +1,125 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 40a98355-0e52-479f-8c91-4ab659cba878 + path: Analytic Rules/ZscalerSharedZPASession.yaml + version: 1.0.2 + querySha256: 5989e50256d1782f8b5cf190b6769b37fc48412d71d96aa02f67bccdc75dc4d7 + schedule: + queryFrequency: 1h + queryPeriod: 24h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=24h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - Unconfirmed generic Account.Name mapping was omitted because another required Host, Mailbox, or IP asset is available + - Account.Name value is retained as customDetails.AccountName from query column `AccountCustomEntity`, but its target + output binding requires runtime-schema verification; custom details do not restore entity identity or correlation + - Supplemental customDetails.AccountName column `AccountCustomEntity` requires runtime output-schema binding verification + - Custom-detail values must remain within the documented combined 4 KB per-alert limit; runtime values are unverified + and the service drops all custom details if exceeded + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1078 + - T1133 + reviewScope: + sourceDocumentSha256: e3a6973f87cd896dc1bc9e68b97f02d40f479fb50984a21f2489cad4fe18834d + targetQuerySha256: 9879367a218d5a741c55e23cd255c59fbd8d5c07a9c7341e01e8170178b115a4 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: runtime-binding-pending + customDetailKey: AccountName +properties: + id: xdr-40a98355-0e52-479f-8c91-4ab659cba878 + displayName: Zscaler - Shared ZPA session + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let open_sessions = + __xdr_inline_ZPAEvent + | where DvcAction == 'open' + | summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, NetworkSessionId + | sort by timestampstart asc; + let closed_sessions = + __xdr_inline_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 + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Shared ZPA session + description: '''Detects shared ZPA session.''' + severity: high + entityMappings: + ips: + - id: ip1 + addressColumn: IPCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1078 + - technique: T1133 + customDetails: + AccountName: AccountCustomEntity diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountEventResult.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountEventResult.yaml new file mode 100644 index 00000000000..3f2543dc371 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountEventResult.yaml @@ -0,0 +1,139 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 593e3e2a-43ce-11ec-81d3-0242ac130003 + path: Analytic Rules/ZscalerUnexpectedCountEventResult.yaml + version: 1.0.2 + querySha256: 3180227597aabce498864054f808e3032efab5367d014ff0d9a27191c7d65883 + schedule: + queryFrequency: 1h + queryPeriod: 1h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=1h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + - Account.Name value is retained as customDetails.AccountName from query column `AccountCustomEntity`, but its target + output binding requires runtime-schema verification; custom details do not restore entity identity or correlation + - Supplemental customDetails.AccountName column `AccountCustomEntity` requires runtime output-schema binding verification + - Custom-detail values must remain within the documented combined 4 KB per-alert limit; runtime values are unverified + and the service drops all custom details if exceeded + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1078 + - T1133 + reviewScope: + sourceDocumentSha256: d89c557d450586dc301d74baeb8b9aace5fdb90caf9cbc45725d83b255c5de4c + targetQuerySha256: 74b25431fbdd25745aa91cf143fb4b2ad78ccb9a108c4744f455324d2f184e04 + reviewDecisions: + - reason: 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm + that the source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + decision: accepted + sourceDocumentSha256: d89c557d450586dc301d74baeb8b9aace5fdb90caf9cbc45725d83b255c5de4c + targetQuerySha256: 74b25431fbdd25745aa91cf143fb4b2ad78ccb9a108c4744f455324d2f184e04 + eventTimeWindow: + status: default-native-lookback + appliedDefault: hourly-1h-to-native-4h-lookback + queryFrequency: 1h + queryPeriod: 1h + targetFrequency: PT1H + effectiveLookback: PT4H + originalSentinelLookbackSeconds: 3600 + effectiveEventWindowSeconds: 14400 + xdrServiceWindowSeconds: 14400 + filterInjected: false + parityClaimed: false + hasAggregation: true + aggregationWindowDifference: true + timingDifference: Four hours (PT4H / 14400s) is the native XDR ingestion-based lookback window for PT1H execution frequency, + not the execution frequency; original Sentinel queryPeriod was 1h (3600s). + aggregationDifference: Query contains summarize/make-series aggregation; evaluating over the native 4-hour XDR lookback + window without an injected 1h event-time filter may aggregate up to 4 hours of events per hourly run instead of 1 + hour. + sourceDocumentSha256: d89c557d450586dc301d74baeb8b9aace5fdb90caf9cbc45725d83b255c5de4c + targetQuerySha256: 74b25431fbdd25745aa91cf143fb4b2ad78ccb9a108c4744f455324d2f184e04 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: runtime-binding-pending + customDetailKey: AccountName + acceptedReviewReasons: + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' +properties: + id: xdr-593e3e2a-43ce-11ec-81d3-0242ac130003 + displayName: Zscaler - Unexpected event count of rejects by policy + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let threshold = 1000; + __xdr_inline_ZPAEvent + | where EventResult has "REJECTED_BY_POLICY" + | summarize rejected = count() by EventResult, DstUserName + | where rejected > threshold + | extend AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Unexpected event count of rejects by policy + description: '''Detects unexpected event count of rejects by policy.''' + severity: high + entityMappings: + accounts: + - id: account1 + upnColumn: AccountCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1078 + - technique: T1133 + customDetails: + AccountName: AccountCustomEntity diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountries.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountries.yaml new file mode 100644 index 00000000000..db4500d9067 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedCountries.yaml @@ -0,0 +1,127 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: b3d112b4-3e1e-11ec-9bbc-0242ac130002 + path: Analytic Rules/ZscalerUnexpectedCountries.yaml + version: 1.0.2 + querySha256: ef6c0b07c4df49d84197993585ec2841b3ddf80bbb3bc07813f43ac393290688 + schedule: + queryFrequency: 1h + queryPeriod: 1h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=1h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - Unconfirmed generic Account.Name mapping was omitted because another required Host, Mailbox, or IP asset is available + - Account.Name value is retained as customDetails.AccountName from query column `AccountCustomEntity`, but its target + output binding requires runtime-schema verification; custom details do not restore entity identity or correlation + - Supplemental customDetails.AccountName column `AccountCustomEntity` requires runtime output-schema binding verification + - Custom-detail values must remain within the documented combined 4 KB per-alert limit; runtime values are unverified + and the service drops all custom details if exceeded + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1190 + - T1133 + reviewScope: + sourceDocumentSha256: 782c88e9b7f7432fd614a62196b5fd4aa2be06402c85dd05012bdbbf95b2d23a + targetQuerySha256: aa3f3cad0144a4d500557ba6b08a6dcafd6aec313bd662c6784fc480ceb0ea06 + eventTimeWindow: + status: default-native-lookback + appliedDefault: hourly-1h-to-native-4h-lookback + queryFrequency: 1h + queryPeriod: 1h + targetFrequency: PT1H + effectiveLookback: PT4H + originalSentinelLookbackSeconds: 3600 + effectiveEventWindowSeconds: 14400 + xdrServiceWindowSeconds: 14400 + filterInjected: false + parityClaimed: false + hasAggregation: false + aggregationWindowDifference: false + timingDifference: Four hours (PT4H / 14400s) is the native XDR ingestion-based lookback window for PT1H execution frequency, + not the execution frequency; original Sentinel queryPeriod was 1h (3600s). + aggregationDifference: No summarize/make-series aggregation detected in query; native 4-hour XDR lookback relies on + Defender XDR alert deduplication across hourly runs. + sourceDocumentSha256: 782c88e9b7f7432fd614a62196b5fd4aa2be06402c85dd05012bdbbf95b2d23a + targetQuerySha256: aa3f3cad0144a4d500557ba6b08a6dcafd6aec313bd662c6784fc480ceb0ea06 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: runtime-binding-pending + customDetailKey: AccountName +properties: + id: xdr-b3d112b4-3e1e-11ec-9bbc-0242ac130002 + displayName: Zscaler - Forbidden countries + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let bl_countries = dynamic(['CH', 'RU']); //List of countries from which you do not expect connections + __xdr_inline_ZPAEvent + | where DvcAction == 'open' + | where SrcGeoCountry in~ (bl_countries) + | extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Forbidden countries + description: '''Detects suspicious ZPA connections from forbidden countries.''' + severity: high + entityMappings: + ips: + - id: ip1 + addressColumn: IPCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1190 + - technique: T1133 + customDetails: + AccountName: AccountCustomEntity diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedUpdateOperation.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedUpdateOperation.yaml new file mode 100644 index 00000000000..0519b8fc8bf --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerUnexpectedUpdateOperation.yaml @@ -0,0 +1,129 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 672e2846-4226-11ec-81d3-0242ac130003 + path: Analytic Rules/ZscalerUnexpectedUpdateOperation.yaml + version: 1.0.2 + querySha256: bc3eb52f53d769f81422620ba8dfc11a01d6e6629d1be048928f8d5c5300361d + schedule: + queryFrequency: 1h + queryPeriod: 1h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=1h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - Process.ProcessId output column `ProcessCustomEntity` cannot be proven after a destructive projection; no supplemental + customDetails binding was added and KQL was not rewritten. Runtime output-schema verification is required + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1190 + - T1133 + reviewScope: + sourceDocumentSha256: 5f1646b7d9c881f262bba7c384467041d27855b8e4fb076aa13f9bb99beb5157 + targetQuerySha256: 98cb3630d9775d4e554fcce12ea1e4dd6134f8a069e78588cbf04c69161d51fd + eventTimeWindow: + status: default-native-lookback + appliedDefault: hourly-1h-to-native-4h-lookback + queryFrequency: 1h + queryPeriod: 1h + targetFrequency: PT1H + effectiveLookback: PT4H + originalSentinelLookbackSeconds: 3600 + effectiveEventWindowSeconds: 14400 + xdrServiceWindowSeconds: 14400 + filterInjected: false + parityClaimed: false + hasAggregation: false + aggregationWindowDifference: false + timingDifference: Four hours (PT4H / 14400s) is the native XDR ingestion-based lookback window for PT1H execution frequency, + not the execution frequency; original Sentinel queryPeriod was 1h (3600s). + aggregationDifference: No summarize/make-series aggregation detected in query; native 4-hour XDR lookback relies on + Defender XDR alert deduplication across hourly runs. + sourceDocumentSha256: 5f1646b7d9c881f262bba7c384467041d27855b8e4fb076aa13f9bb99beb5157 + targetQuerySha256: 98cb3630d9775d4e554fcce12ea1e4dd6134f8a069e78588cbf04c69161d51fd + supplementalEntityDetails: + - entityType: Process + entityIndex: 1 + identifier: ProcessId + sourceColumn: ProcessCustomEntity + column: ProcessCustomEntity + status: unproven-destructive-projection + reason: unproven-destructive-projection +properties: + id: xdr-672e2846-4226-11ec-81d3-0242ac130003 + displayName: Zscaler - Unexpected update operation + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + __xdr_inline_ZPAEvent + | where isnotempty(AuditOperationType) + | extend ExpectedVersion1 = extract(@'(expectedVersion":")([0-9]+)\.([0-9]+\.[0-9]+)', 2, AuditOldValue) + | extend ExpectedVersion2 = extract(@'(expectedVersion":")([0-9]+)\.([0-9]+\.[0-9]+)', 3, AuditOldValue) + | extend NewVersion1 = extract(@'("currentVersion":")([0-9]+)\.([0-9]+\.[0-9]+)', 2, AuditNewValue) + | extend NewVersion2 = extract(@'("currentVersion":")([0-9]+)\.([0-9]+\.[0-9]+)', 3, AuditNewValue) + | extend Comparision1 = iff(tolong(ExpectedVersion2) > tolong(NewVersion2), 'Unexpected version', 'Expected version') + | extend VersionCheck = iff(tolong(ExpectedVersion1) > tolong(NewVersion1), 'Unexpected version', Comparision1) + | project-away ExpectedVersion1, ExpectedVersion2, NewVersion1, NewVersion2, Comparision1 + | extend ProcessCustomEntity = AuditOperationType + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Unexpected update operation + description: '''Detects unexpected version of update operation.''' + severity: medium + entityMappings: + hosts: + - id: host1 + nameColumn: DvcHostname + ips: + - id: ip1 + addressColumn: SrcIpAddr + tactics: + - tactic: InitialAccess + techniques: + - technique: T1190 + - technique: T1133 diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByDormantUser.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByDormantUser.yaml new file mode 100644 index 00000000000..8ca94db605c --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByDormantUser.yaml @@ -0,0 +1,117 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 66bc77ee-3e45-11ec-9bbc-0242ac130002 + path: Analytic Rules/ZscalerZPAConnectionsByDormantUser.yaml + version: 1.0.2 + querySha256: 0abb8b7cd1ba9efb995cacdc06b6394bf7531e578ad3f1617858289a6cb6d2fa + schedule: + queryFrequency: 1h + queryPeriod: 14d + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=14d; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + - Account.Name output column `AccountCustomEntity` cannot be proven after a destructive projection; no supplemental customDetails + binding was added and KQL was not rewritten. Runtime output-schema verification is required + informational: [] + errors: [] + originalTactics: + - Persistence + originalTechniques: + - T1078 + reviewScope: + sourceDocumentSha256: 95ed1f6340b319d7b94587330c0507ef1923e9d5ae7c48d4a43d799eee3950f2 + targetQuerySha256: a9647fc23c86f82c999cd5b71a3671c6368fee161963aa39356c688cceabf302 + reviewDecisions: + - reason: 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm + that the source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + decision: accepted + sourceDocumentSha256: 95ed1f6340b319d7b94587330c0507ef1923e9d5ae7c48d4a43d799eee3950f2 + targetQuerySha256: a9647fc23c86f82c999cd5b71a3671c6368fee161963aa39356c688cceabf302 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: unproven-destructive-projection + reason: unproven-destructive-projection + acceptedReviewReasons: + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' +properties: + id: xdr-66bc77ee-3e45-11ec-9bbc-0242ac130002 + displayName: Zscaler - Connections by dormant user + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let dt_lastlogintime = 14d; + let activeUsers = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(dt_lastlogintime) + | where DvcAction == 'open' + | summarize lastLoginTime = max(TimeGenerated) by DstUserName + | summarize makelist(DstUserName); + __xdr_inline_ZPAEvent + | where DstUserName !in~ (activeUsers) + | summarize EventCount = count() by DstUserName + | project-away EventCount + | extend AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Connections by dormant user + description: '''Detects ZPA connections by dormant user.''' + severity: high + entityMappings: + accounts: + - id: account1 + upnColumn: AccountCustomEntity + tactics: + - tactic: Persistence + techniques: + - technique: T1078 diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByNewUser.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByNewUser.yaml new file mode 100644 index 00000000000..cdd7dc9dd3d --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsByNewUser.yaml @@ -0,0 +1,116 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 236a7ec1-0120-40f2-a157-c1a72dde8bcb + path: Analytic Rules/ZscalerZPAConnectionsByNewUser.yaml + version: 1.0.2 + querySha256: 1022fe6e6d87638725c9d772c2bf623a9b35fe6fe62c99c5976f5eb9c43f976d + schedule: + queryFrequency: 1h + queryPeriod: 14d + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=14d; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + - Account.Name output column `AccountCustomEntity` cannot be proven after a destructive projection; no supplemental customDetails + binding was added and KQL was not rewritten. Runtime output-schema verification is required + informational: [] + errors: [] + originalTactics: + - Persistence + originalTechniques: + - T1078 + reviewScope: + sourceDocumentSha256: 9b4766e14349289bce30a01303635f2dfbfa217cb2e66cd0d32951b898b7a087 + targetQuerySha256: 5fee4c2fbc189edf34dc81c06bef61485444bfe48cc67d64c5f89c200a9d428f + reviewDecisions: + - reason: 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm + that the source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + decision: accepted + sourceDocumentSha256: 9b4766e14349289bce30a01303635f2dfbfa217cb2e66cd0d32951b898b7a087 + targetQuerySha256: 5fee4c2fbc189edf34dc81c06bef61485444bfe48cc67d64c5f89c200a9d428f + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: unproven-destructive-projection + reason: unproven-destructive-projection + acceptedReviewReasons: + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' +properties: + id: xdr-236a7ec1-0120-40f2-a157-c1a72dde8bcb + displayName: Zscaler - ZPA connections by new user + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let listUsers = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(14d) + | where DvcAction == 'open' + | summarize ListofUsers = make_set(DstUserName) by DstUserName + | project ListofUsers; + __xdr_inline_ZPAEvent + | where DstUserName !in (listUsers) + | summarize EventCount = count() by DstUserName + | project-away EventCount + | extend AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - ZPA connections by new user + description: '''Detects ZPA connections by new user.''' + severity: medium + entityMappings: + accounts: + - id: account1 + upnColumn: AccountCustomEntity + tactics: + - tactic: Persistence + techniques: + - technique: T1078 diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewCountry.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewCountry.yaml new file mode 100644 index 00000000000..df0fd087d61 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewCountry.yaml @@ -0,0 +1,119 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: c4902121-7a7e-44d1-810b-88d26db622ff + path: Analytic Rules/ZscalerZPAConnectionsFromNewCountry.yaml + version: 1.0.2 + querySha256: 7465a6e3640510a4a4914e5ebee7f973772edca1a14640e807047089fe168eab + schedule: + queryFrequency: 1h + queryPeriod: 14d + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=14d; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + - Account.Name output column `AccountCustomEntity` cannot be proven after a destructive projection; no supplemental customDetails + binding was added and KQL was not rewritten. Runtime output-schema verification is required + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1190 + - T1133 + reviewScope: + sourceDocumentSha256: 065eabbc76d5b56fe12a631762529b30c89ea00f49666547eec563f74fe463b4 + targetQuerySha256: fcf5814fa562727c3530f765dcd9e455c56228a2737183b906747d1f0085202c + reviewDecisions: + - reason: 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm + that the source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + decision: accepted + sourceDocumentSha256: 065eabbc76d5b56fe12a631762529b30c89ea00f49666547eec563f74fe463b4 + targetQuerySha256: fcf5814fa562727c3530f765dcd9e455c56228a2737183b906747d1f0085202c + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: unproven-destructive-projection + reason: unproven-destructive-projection + acceptedReviewReasons: + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' +properties: + id: xdr-c4902121-7a7e-44d1-810b-88d26db622ff + displayName: Zscaler - ZPA connections from new country + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let listCountries = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(14d) + | where DvcAction == 'open' + | summarize ListofCountries = make_set(SrcGeoCountry) by DstUserName + | project ListofCountries; + __xdr_inline_ZPAEvent + | where isnotempty(SrcGeoCountry) + | where SrcGeoCountry !in (listCountries) + | summarize EventCount = count() by DstUserName, SrcGeoCountry + | project-away EventCount + | extend AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - ZPA connections from new country + description: '''Detects ZPA connections from new country.''' + severity: medium + entityMappings: + accounts: + - id: account1 + upnColumn: AccountCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1190 + - technique: T1133 diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewIP.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewIP.yaml new file mode 100644 index 00000000000..2c5c4df0c54 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsFromNewIP.yaml @@ -0,0 +1,109 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 24f0779d-3927-403a-aac1-cc8791653606 + path: Analytic Rules/ZscalerZPAConnectionsFromNewIP.yaml + version: 1.0.2 + querySha256: e0b5c16fddc41e739d6eed55cff294fa91531ba954e9fbde760eaea684de5bbe + schedule: + queryFrequency: 1h + queryPeriod: 14d + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=14d; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - Unconfirmed generic Account.Name mapping was omitted because another required Host, Mailbox, or IP asset is available + - Account.Name output column `AccountCustomEntity` cannot be proven after a destructive projection; no supplemental customDetails + binding was added and KQL was not rewritten. Runtime output-schema verification is required + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1078 + - T1133 + reviewScope: + sourceDocumentSha256: 2c8d958f507ef1f1762e586db62b87e7dbf8d2b8e4ebb713b8deb8c60b9a793d + targetQuerySha256: 3f89bc77060f9d3a20e1d0bdbf7301874043312dc22fa43937b1bc05a58caa60 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: unproven-destructive-projection + reason: unproven-destructive-projection +properties: + id: xdr-24f0779d-3927-403a-aac1-cc8791653606 + displayName: Zscaler - ZPA connections from new IP + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let listIPs = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(14d) + | where DvcAction == 'open' + | summarize ListofIPs = make_set(SrcIpAddr) by DstUserName + | project ListofIPs; + __xdr_inline_ZPAEvent + | where isnotempty(SrcIpAddr) + | where SrcIpAddr !in (listIPs) + | summarize EventCount = count() by DstUserName, SrcIpAddr + | project-away EventCount + | extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - ZPA connections from new IP + description: '''Detects ZPA connections from new IP.''' + severity: medium + entityMappings: + ips: + - id: ip1 + addressColumn: IPCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1078 + - technique: T1133 diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsOutsideOperationalHours.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsOutsideOperationalHours.yaml new file mode 100644 index 00000000000..83c45ed5355 --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAConnectionsOutsideOperationalHours.yaml @@ -0,0 +1,139 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: 2859ad22-46c8-4cc7-ad7b-80ce0cba0af3 + path: Analytic Rules/ZscalerZPAConnectionsOutsideOperationalHours.yaml + version: 1.0.2 + querySha256: 6f42453ff7ae0bb37211e7d86eee80208cf527f039c74f3ed6009ad32ece3bbe + schedule: + queryFrequency: 1h + queryPeriod: 1h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=1h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + - Account.Name value is retained as customDetails.AccountName from query column `AccountCustomEntity`, but its target + output binding requires runtime-schema verification; custom details do not restore entity identity or correlation + - Supplemental customDetails.AccountName column `AccountCustomEntity` requires runtime output-schema binding verification + - Custom-detail values must remain within the documented combined 4 KB per-alert limit; runtime values are unverified + and the service drops all custom details if exceeded + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1190 + - T1133 + reviewScope: + sourceDocumentSha256: 2042f508c9763da3aa38d1f083a1df374b759ca4dc947e08dbb6dd5c9d68859d + targetQuerySha256: 513bdac8c920e1cb3a1940c0aab76d89a68812c36650d57ec47b49ba648fe255 + reviewDecisions: + - reason: 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm + that the source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' + decision: accepted + sourceDocumentSha256: 2042f508c9763da3aa38d1f083a1df374b759ca4dc947e08dbb6dd5c9d68859d + targetQuerySha256: 513bdac8c920e1cb3a1940c0aab76d89a68812c36650d57ec47b49ba648fe255 + eventTimeWindow: + status: default-native-lookback + appliedDefault: hourly-1h-to-native-4h-lookback + queryFrequency: 1h + queryPeriod: 1h + targetFrequency: PT1H + effectiveLookback: PT4H + originalSentinelLookbackSeconds: 3600 + effectiveEventWindowSeconds: 14400 + xdrServiceWindowSeconds: 14400 + filterInjected: false + parityClaimed: false + hasAggregation: true + aggregationWindowDifference: true + timingDifference: Four hours (PT4H / 14400s) is the native XDR ingestion-based lookback window for PT1H execution frequency, + not the execution frequency; original Sentinel queryPeriod was 1h (3600s). + aggregationDifference: Query contains summarize/make-series aggregation; evaluating over the native 4-hour XDR lookback + window without an injected 1h event-time filter may aggregate up to 4 hours of events per hourly run instead of 1 + hour. + sourceDocumentSha256: 2042f508c9763da3aa38d1f083a1df374b759ca4dc947e08dbb6dd5c9d68859d + targetQuerySha256: 513bdac8c920e1cb3a1940c0aab76d89a68812c36650d57ec47b49ba648fe255 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: runtime-binding-pending + customDetailKey: AccountName + acceptedReviewReasons: + - 'Entity confirmation required: `AccountCustomEntity` was provisionally mapped to Account.upnColumn. Confirm that the + source always emits a complete UPN; otherwise project an Entra user ID, SID, or account name plus domain' +properties: + id: xdr-2859ad22-46c8-4cc7-ad7b-80ce0cba0af3 + displayName: Zscaler - ZPA connections outside operational hours + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + __xdr_inline_ZPAEvent + | where DvcAction == 'open' + | where datetime_part("Hour", todatetime(LogTimestamp)) between (datetime_part("Hour", todatetime('19:01:00.7654321')) .. datetime_part("Hour", todatetime('08:01:00.7654321'))) + | summarize count() by DstUserName + | project DstUserName + | extend AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - ZPA connections outside operational hours + description: '''Detects ZAP connections outside operational hours.''' + severity: medium + entityMappings: + accounts: + - id: account1 + upnColumn: AccountCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1190 + - technique: T1133 + customDetails: + AccountName: AccountCustomEntity diff --git a/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAUnexpectedSessionDuration.yaml b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAUnexpectedSessionDuration.yaml new file mode 100644 index 00000000000..b807a5b384a --- /dev/null +++ b/Solutions/Zscaler Private Access (ZPA)/XDR Detections/ZscalerZPAUnexpectedSessionDuration.yaml @@ -0,0 +1,123 @@ +schemaVersion: 1.0.0 +version: 3.2.1 +kind: CustomDetection +resourceType: Microsoft.Security/detectionRules +apiVersion: 2026-06-01-preview +requiredDataConnectors: +- connectorId: CustomLogsAma + dataTypes: + - ZPA_CL +contentProvenance: + requiredWorkloads: + - workload: sentinel + dataTypes: + - ZPA_CL + requiredDataConnectors: + - connectorId: CustomLogsAma + dataTypes: + - ZPA_CL + dependencyReviewRequired: false + source: + platform: Microsoft Sentinel + kind: AnalyticsRule + id: e07846e0-43ad-11ec-81d3-0242ac130003 + path: Analytic Rules/ZscalerZPAUnexpectedSessionDuration.yaml + version: 1.0.3 + querySha256: 743c032a51b7c1934ed51f0ef5e958f5bdf7021a3459f4cae557ae31d7bf0f84 + schedule: + queryFrequency: 1h + queryPeriod: 24h + conversion: + tool: sentinel-to-xdr-migration + version: 0.1.0 + status: converted + reviewRequired: false + reviewReasons: [] + requiredWorkloads: + - sentinel + warnings: + - Renamed local parser binding ZPAEvent to __xdr_inline_ZPAEvent to avoid a saved parser collision + - 'Schedule assessment: source frequency=1h, lookback=24h; target frequency=PT1H, native lookback=unknown/unconfigured; + mixed, Sentinel-only, or unknown query surface; no custom lookback is configured in the payload. See https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules#lookback' + - Unconfirmed generic Account.Name mapping was omitted because another required Host, Mailbox, or IP asset is available + - Account.Name value is retained as customDetails.AccountName from query column `AccountCustomEntity`, but its target + output binding requires runtime-schema verification; custom details do not restore entity identity or correlation + - Supplemental customDetails.AccountName column `AccountCustomEntity` requires runtime output-schema binding verification + - Custom-detail values must remain within the documented combined 4 KB per-alert limit; runtime values are unverified + and the service drops all custom details if exceeded + informational: [] + errors: [] + originalTactics: + - InitialAccess + originalTechniques: + - T1078 + - T1133 + reviewScope: + sourceDocumentSha256: e04396857d636cb6191946327c2a7c7fa0131f4941e58c9be7368be2e9c0a412 + targetQuerySha256: 2c94b2831dc494dd49872ac191bee65fff1642133a8682b40bc4d70166a9d910 + supplementalEntityDetails: + - entityType: Account + entityIndex: 1 + identifier: Name + sourceColumn: AccountCustomEntity + column: AccountCustomEntity + status: runtime-binding-pending + customDetailKey: AccountName +properties: + id: xdr-e07846e0-43ad-11ec-81d3-0242ac130003 + displayName: Zscaler - Unexpected ZPA session duration + status: disabled + queryCondition: + queryText: |- + let __xdr_inline_ZPAEvent = () { + ZPA_CL + | extend EventVendor="Zscaler", + EventProduct="Private Access" + | parse-kv Message as (LogTimestamp:string, Customer:string, SessionID:string, ConnectionID:string, NetworkProtocol:string, DoubleEncryption:string, SrcIpAddr:string, SrcNatIpAddr:string, SrcGeoLatitude:string, SrcGeoLongitude:string, SrcGeoCountry:string, ClientZEN:string, NetworkRuleName:string, ConnectorZEN:string, ConnectorIP:string, ConnectorPort:string, SrcDvcHostname:string, Application:string, AppGroup:string, DstDomainHostname:string, DstIpAddr:string, PolicyProcessingTime:string, CAProcessingTime:string, ConnectorZENSetupTime:string, ConnectionSetupTime:string, ServerSetupTime:string, AppLearnTime:string, TimestampConnectionStart:string, TimestampConnectionEnd:string, TimestampCATx:string, TimestampCARx:string, TimestampAppLearnStart:string, TimestampZENFirstRxClient:string, TimestampZENFirstTxClient:string, TimestampZENLastRxClient:string, TimestampZENLastTxClient:string, TimestampConnectorZENSetupComplete:string, TimestampZENFirstRxConnector:string, TimestampZENFirstTxConnector:string, TimestampZENLastRxConnector:string, TimestampZENLastTxConnector:string, ZENBytesRxClient:string, ZENBytesTxClient:string, ZENTotalBytesRxConnector:string, ZENBytesRxConnector:string, ZENTotalBytesTxConnector:string, ZENBytesTxConnector:string, Idp:string, Version:string, ZEN:string, CertificateCN:string, PrivateIP:string, DvcIpAddr:string, Latitude:string, Longitude:string, CountryCode:string, TimestampAuthentication:string, TimestampUnAuthentication:string, DvcHostname:string, SrcDvcOs:string, DvcType:string, TrustedNetworks:string, TrustedNetworksNames:string, SAMLAttributes:string, PosturesHit:string, PosturesMiss:string, ZENLatitude:string, ZENLongitude:string, ZENCountryCode:string, SessionType:string, Connector:string, ConnectorGroup:string, CPUUtilization:string, MemUtilization:string, ServiceCount:string, InterfaceDefRoute:string, DefRouteGW:string, PrimaryDNSResolver:string, HostUpTime:string, ConnectorUpTime:string, NumOfInterfaces:string, BytesRxInterface:string, PacketsRxInterface:string, ErrorsRxInterface:string, DiscardsRxInterface:string, BytesTxInterface:string, PacketsTxInterface:string, ErrorsTxInterface:string, DiscardsTxInterface:string, ModifiedTime:string, CreationTime:string, ModifiedBy:string, RequestID:string, AuditOldValue:string, AuditNewValue:string, AuditOperationType:string, ObjectType:string, ObjectName:string, ObjectID:string, CustomerID:string, Exporter:string, TimestampRequestReceiveStart:string, TimestampRequestReceiveHeaderFinish:string, TimestampRequestReceiveFinish:string, TimestampRequestTransmitStart:string, TimestampRequestTransmitFinish:string, TimestampResponseReceiveStart:string, TimestampResponseReceiveFinish:string, TimestampResponseTransmitStart:string, TimestampResponseTransmitFinish:string, TotalTimeRequestReceive:string, TotalTimeRequestTransmit:string, TotalTimeResponseReceive:string, TotalTimeResponseTransmit:string, TotalTimeConnectionSetup:string, TotalTimeServerResponse:string, HttpRequestMethod:string, NetworkApplicationProtocol:string, UrlHostname:string, UrlOriginal:string, HttpUserAgentOriginal:string, HttpRequestXff:string, NameID:string, HttpStatusCode:string, HttpRequestBodyBytes:string, HttpResponseBodyBytes:string, SrcPortNumber:string, EventResultDetails:string, CorsToken:string, Origin:string, InternalReason:string, ConnectionStatus:string, SessionStatus:string, Username:string, User:string, ServicePort:string, ServerPort:string, ApplicationPort:string, ZENTotalBytesRxClient:string, TotalBytesRx:string, ZENTotalBytesTxClient:string, TotalBytesTx:string, IPProtocol:double, ClientCountryCode:string, ClientLatitude:string, ClientLongitude:string, ClientPublicIP:string, ClientPrivateIP:string, Policy:string, Host:string, Server:string, ServerIP:string, ClientCity:string, MicroTenantID:string, AppMicroTenantID:string, Platform:string, Hostname:string, NetworkSessionId:string, ) with (pair_delimiter=',', kv_delimiter=':', quote='"') + | extend + EventResult=column_ifexists('InternalReason', column_ifexists('ConnectionStatus', '')), + DvcAction=column_ifexists('ConnectionStatus', column_ifexists('SessionStatus', '')), + DstUserName=column_ifexists('Username', column_ifexists('User', '')), + DstPortNumber=column_ifexists('ServicePort', column_ifexists('ServerPort', column_ifexists('ApplicationPort', ''))), + SrcBytes=column_ifexists('ZENTotalBytesRxClient', column_ifexists('TotalBytesRx', '')), + DstBytes=column_ifexists('ZENTotalBytesTxClient', column_ifexists('TotalBytesTx', '')) + }; + let dt_lookBack = 24h; + let time_treshhold = timespan(08:00:00); + let open_sessions = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(dt_lookBack) + | where DvcAction == 'open' + | summarize timestampstart = min(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID + | sort by timestampstart asc; + let closed_sessions = + __xdr_inline_ZPAEvent + | where TimeGenerated > ago(dt_lookBack) + | where DvcAction == 'close' + | summarize timestampend = max(TimeGenerated) by DstUserName, SrcIpAddr, ConnectionID + | sort by timestampend asc; + open_sessions + | join (closed_sessions) on DstUserName, SrcIpAddr, ConnectionID + | extend duration = timestampend - timestampstart + | where duration > time_treshhold + | where DstUserName !has "ZPA LSS" + | sort by timestampstart asc + | extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUserName + schedule: + frequency: PT1H + detectionAction: + alertTemplate: + title: Zscaler - Unexpected ZPA session duration + description: '''Detects Unexpected ZPA session duration.''' + severity: medium + entityMappings: + ips: + - id: ip1 + addressColumn: IPCustomEntity + tactics: + - tactic: InitialAccess + techniques: + - technique: T1078 + - technique: T1133 + customDetails: + AccountName: AccountCustomEntity