Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Anomaly found in Network Session Traffic ASIM Network Session schema

Back
Idcd6def0d-3ef0-4d55-a7e3-faa96c46ba12
RulenameAnomaly found in Network Session Traffic (ASIM Network Session schema)
DescriptionThe rule identifies anomalous pattern in network session traffic based on previously seen data, different Device Action, Network Protocol, Network Direction or overall volume. The rule utilize ASIM normalization, and is applied to any source which supports the ASIM Network Session schema. This rule leverages log summaries generated by a Summary Rule or Summarized Playbook. If no such summaries are available, the rule falls back to direct analysis using ASIM function.
SeverityMedium
TacticsCommandAndControl
Discovery
Exfiltration
LateralMovement
TechniquesT1095
T1071
T1046
T1030
T1210
Required data connectorsAIVectraStream
AWSS3
AzureFirewall
AzureMonitor(VMInsights)
AzureNSG
CheckPoint
CiscoASA
CiscoAsaAma
CiscoMeraki
Corelight
Fortinet
MicrosoftSysmonForLinux
MicrosoftThreatProtection
PaloAltoNetworks
SecurityEvents
WindowsForwardedEvents
WindowsSecurityEvents
Zscaler
KindScheduled
Query frequency1d
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network Session Essentials/Analytic Rules/AnomalyFoundInNetworkSessionTraffic.yaml
Version1.2.0
Arm templatecd6def0d-3ef0-4d55-a7e3-faa96c46ba12.json
Deploy To Azure
let min_t = ago(14d);
let max_t = now();
let dt = 1d;
let fieldForDvcAction = "DvcAction";
let fieldForNetworkDirection = "NetworkDirection";
let fieldForNetworkProtocol = "NetworkProtocol";
let AnomalyThreshold = 2.5;
let eps = materialize (_Im_NetworkSession
    | project TimeGenerated
    | where TimeGenerated > ago(5m)
    | count
    | extend Count = Count / 300);
let maxSummarizedTime = toscalar (
    union isfuzzy=true
        (
        NetworkSummary_Protocol_CL
        | where EventTime > min_t
        | summarize max_TimeGenerated=max(EventTime)
        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
        ),
        (
        NetworkCustomAnalytics_protocol_CL
        | where EventTime_t > min_t
        | summarize max_TimeGenerated=max(EventTime_t)
        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
        ),
        (
        print(min_t)
        | project max_TimeGenerated = print_0
        )
    | summarize maxTimeGenerated = max(max_TimeGenerated) 
    );
let NetworkSummary_Protocol = materialize(
    union isfuzzy=true 
        (
        NetworkSummary_Protocol_CL
        | where EventTime > ago(1d)
        | project v = int(2)
        ),
        (
        print int(1) 
        | project v = print_0
        )
    | summarize maxv = max(v)
    | extend
        NetworkSummary_Protocol_Exists = (maxv > 1),
        NetworkCustomAnalyticsExists = false
    );
let NetworkCustomAnalytics = materialize(
    union isfuzzy=true 
        (
        NetworkCustomAnalytics_protocol_CL
        | where EventTime_t > ago(1d) 
        | project v = int(2)
        ),
        (
        print int(1) 
        | project v = print_0
        )
    | summarize maxv = max(v)
    | extend
        NetworkCustomAnalyticsExists = (maxv > 1),
        NetworkSummary_Protocol_Exists = false
    );
let allData = union isfuzzy=true 
        (
        (datatable(
    exists: int,
    NetworkSummary_Protocol_Exists: bool,
    NetworkCustomAnalyticsExists: bool
)[
    1, false, false
]
        | where toscalar(eps) > 1000
        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)
        | join (
            _Im_NetworkSession(starttime=todatetime(ago(2d)), endtime=now())
            | where TimeGenerated > maxSummarizedTime
            | summarize Count=count()
                by
                NetworkProtocol,
                DstPortNumber,
                DstAppName,
                NetworkDirection,
                DvcAction,
                bin(TimeGenerated, 10m)
            | extend
                EventTime = TimeGenerated,
                Count = toint(Count),
                DstPortNumber = toint(DstPortNumber),
                exists=int(1)
            )
            on exists
        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
        ),
        (
        (datatable(
    exists: int,
    NetworkSummary_Protocol_Exists: bool,
    NetworkCustomAnalyticsExists: bool
)[
    1, false, false
]
        | where toscalar(eps) between (501 .. 1000)
        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)
        | join (
            _Im_NetworkSession(starttime=todatetime(ago(3d)), endtime=now())
            | where TimeGenerated > maxSummarizedTime
            | summarize Count=count()
                by
                NetworkProtocol,
                DstPortNumber,
                DstAppName,
                NetworkDirection,
                DvcAction,
                bin(TimeGenerated, 10m)
            | extend
                EventTime = TimeGenerated,
                Count = toint(Count),
                DstPortNumber = toint(DstPortNumber),
                exists=int(1)
            )
            on exists
        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
        ),
        (
        (datatable(
    exists: int,
    NetworkSummary_Protocol_Exists: bool,
    NetworkCustomAnalyticsExists: bool
)[
    1, false, false
]
        | where toscalar(eps) <= 500
        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists
        )
        | join (
            _Im_NetworkSession(starttime=todatetime(ago(4d)), endtime=now())
            | where TimeGenerated > maxSummarizedTime
            | summarize Count=count()
                by
                NetworkProtocol,
                DstPortNumber,
                DstAppName,
                NetworkDirection,
                DvcAction,
                bin(TimeGenerated, 10m)
            | extend
                EventTime = TimeGenerated,
                Count = toint(Count),
                DstPortNumber = toint(DstPortNumber),
                exists=int(1)
            )
            on exists
        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
        ),
        (
        (datatable(exists: int, NetworkSummary_Protocol_Exists: bool)[1, false]
        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
        )
        | join (
            NetworkCustomAnalytics_protocol_CL
            | where EventTime_t > min_t
            | project
                NetworkProtocol=NetworkProtocol_s,
                DstPortNumber=DstPortNumber_d,
                DstAppName=DstAppName_s,
                NetworkDirection=NetworkDirection_s,
                DvcAction=DvcAction_s,
                Count=count__d,
                EventTime=EventTime_t,
                TimeGenerated,
                Type
            | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber), exists=int(1)
            )
            on exists
        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
        ),
        (
        NetworkSummary_Protocol_CL
        | where EventTime > min_t
        | project
            NetworkProtocol,
            DstPortNumber,
            DstAppName,
            NetworkDirection,
            DvcAction,
            Count=count_,
            EventTime,
            TimeGenerated,
            Type
        | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber)
        )
;
let findVolumneBasedAnomaly = allData
    | make-series total=sum(Count) on EventTime from min_t to max_t step dt
    | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit') 
    | mv-expand anomalies, score, baseline, EventTime, total
    | extend
        anomalies = toint(anomalies),
        score = toint(score),
        baseline = toint(baseline),
        EventTime = todatetime(EventTime),
        total = tolong(total)
    | where EventTime >= ago(1d)
    | where score >= 2 * AnomalyThreshold
;
let findAnomalies = (field: string) {
    allData
    | where isnotempty(column_ifexists(field, ""))
    | make-series total=sum(Count) on EventTime from min_t to max_t step dt by column_ifexists(field, "")
    | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit')
    | mv-expand anomalies, score, baseline, EventTime, total
    | extend
        anomalies = toint(anomalies),
        score = toint(score),
        baseline = toint(baseline),
        EventTime = todatetime(EventTime),
        total = tolong(total)
    | where EventTime >= ago(1d)
    | where score >= 2 * AnomalyThreshold
};
union
    findAnomalies(fieldForDvcAction),
    findAnomalies(fieldForNetworkDirection),
    findAnomalies(fieldForNetworkProtocol),
    findVolumneBasedAnomaly
| extend
    anomalyFieldType  = case (
                        isnotempty(column_ifexists(fieldForDvcAction, "")),
                        "DvcAction",
                        isnotempty(column_ifexists(fieldForNetworkDirection, "")),
                        "NetworkDirection",
                        isnotempty(column_ifexists(fieldForNetworkProtocol, "")),
                        "NetworkProtocol",
                        "TotalVolume"
                    ),
    anomalyFieldValue  = case (
                        isnotempty(column_ifexists(fieldForDvcAction, "")),
                        column_ifexists(fieldForDvcAction, ""),
                        isnotempty(column_ifexists(fieldForNetworkDirection, "")),
                        column_ifexists(fieldForNetworkDirection, ""),
                        isnotempty(column_ifexists(fieldForNetworkProtocol, "")),
                        column_ifexists(fieldForNetworkProtocol, ""),
                        "Overall"
                    )
requiredDataConnectors:
- connectorId: AWSS3
  dataTypes:
  - AWSVPCFlow
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - DeviceNetworkEvents
- connectorId: SecurityEvents
  dataTypes:
  - SecurityEvent
- connectorId: WindowsSecurityEvents
  dataTypes:
  - SecurityEvent
- connectorId: WindowsForwardedEvents
  dataTypes:
  - WindowsEvent
- connectorId: Zscaler
  dataTypes:
  - CommonSecurityLog
- connectorId: MicrosoftSysmonForLinux
  dataTypes:
  - Syslog
- connectorId: PaloAltoNetworks
  dataTypes:
  - CommonSecurityLog
- connectorId: AzureMonitor(VMInsights)
  dataTypes:
  - VMConnection
- connectorId: AzureFirewall
  dataTypes:
  - AzureDiagnostics
- connectorId: AzureNSG
  dataTypes:
  - AzureDiagnostics
- connectorId: CiscoASA
  dataTypes:
  - CommonSecurityLog
- connectorId: CiscoAsaAma
  dataTypes:
  - CommonSecurityLog
- connectorId: Corelight
  dataTypes:
  - Corelight_CL
- connectorId: AIVectraStream
  dataTypes:
  - VectraStream
- connectorId: CheckPoint
  dataTypes:
  - CommonSecurityLog
- connectorId: Fortinet
  dataTypes:
  - CommonSecurityLog
- connectorId: CiscoMeraki
  dataTypes:
  - Syslog
  - CiscoMerakiNativePoller
query: |
  let min_t = ago(14d);
  let max_t = now();
  let dt = 1d;
  let fieldForDvcAction = "DvcAction";
  let fieldForNetworkDirection = "NetworkDirection";
  let fieldForNetworkProtocol = "NetworkProtocol";
  let AnomalyThreshold = 2.5;
  let eps = materialize (_Im_NetworkSession
      | project TimeGenerated
      | where TimeGenerated > ago(5m)
      | count
      | extend Count = Count / 300);
  let maxSummarizedTime = toscalar (
      union isfuzzy=true
          (
          NetworkSummary_Protocol_CL
          | where EventTime > min_t
          | summarize max_TimeGenerated=max(EventTime)
          | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
          ),
          (
          NetworkCustomAnalytics_protocol_CL
          | where EventTime_t > min_t
          | summarize max_TimeGenerated=max(EventTime_t)
          | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
          ),
          (
          print(min_t)
          | project max_TimeGenerated = print_0
          )
      | summarize maxTimeGenerated = max(max_TimeGenerated) 
      );
  let NetworkSummary_Protocol = materialize(
      union isfuzzy=true 
          (
          NetworkSummary_Protocol_CL
          | where EventTime > ago(1d)
          | project v = int(2)
          ),
          (
          print int(1) 
          | project v = print_0
          )
      | summarize maxv = max(v)
      | extend
          NetworkSummary_Protocol_Exists = (maxv > 1),
          NetworkCustomAnalyticsExists = false
      );
  let NetworkCustomAnalytics = materialize(
      union isfuzzy=true 
          (
          NetworkCustomAnalytics_protocol_CL
          | where EventTime_t > ago(1d) 
          | project v = int(2)
          ),
          (
          print int(1) 
          | project v = print_0
          )
      | summarize maxv = max(v)
      | extend
          NetworkCustomAnalyticsExists = (maxv > 1),
          NetworkSummary_Protocol_Exists = false
      );
  let allData = union isfuzzy=true 
          (
          (datatable(
      exists: int,
      NetworkSummary_Protocol_Exists: bool,
      NetworkCustomAnalyticsExists: bool
  )[
      1, false, false
  ]
          | where toscalar(eps) > 1000
          | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
          | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)
          | join (
              _Im_NetworkSession(starttime=todatetime(ago(2d)), endtime=now())
              | where TimeGenerated > maxSummarizedTime
              | summarize Count=count()
                  by
                  NetworkProtocol,
                  DstPortNumber,
                  DstAppName,
                  NetworkDirection,
                  DvcAction,
                  bin(TimeGenerated, 10m)
              | extend
                  EventTime = TimeGenerated,
                  Count = toint(Count),
                  DstPortNumber = toint(DstPortNumber),
                  exists=int(1)
              )
              on exists
          | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
          ),
          (
          (datatable(
      exists: int,
      NetworkSummary_Protocol_Exists: bool,
      NetworkCustomAnalyticsExists: bool
  )[
      1, false, false
  ]
          | where toscalar(eps) between (501 .. 1000)
          | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
          | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)
          | join (
              _Im_NetworkSession(starttime=todatetime(ago(3d)), endtime=now())
              | where TimeGenerated > maxSummarizedTime
              | summarize Count=count()
                  by
                  NetworkProtocol,
                  DstPortNumber,
                  DstAppName,
                  NetworkDirection,
                  DvcAction,
                  bin(TimeGenerated, 10m)
              | extend
                  EventTime = TimeGenerated,
                  Count = toint(Count),
                  DstPortNumber = toint(DstPortNumber),
                  exists=int(1)
              )
              on exists
          | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
          ),
          (
          (datatable(
      exists: int,
      NetworkSummary_Protocol_Exists: bool,
      NetworkCustomAnalyticsExists: bool
  )[
      1, false, false
  ]
          | where toscalar(eps) <= 500
          | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
          | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists
          )
          | join (
              _Im_NetworkSession(starttime=todatetime(ago(4d)), endtime=now())
              | where TimeGenerated > maxSummarizedTime
              | summarize Count=count()
                  by
                  NetworkProtocol,
                  DstPortNumber,
                  DstAppName,
                  NetworkDirection,
                  DvcAction,
                  bin(TimeGenerated, 10m)
              | extend
                  EventTime = TimeGenerated,
                  Count = toint(Count),
                  DstPortNumber = toint(DstPortNumber),
                  exists=int(1)
              )
              on exists
          | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
          ),
          (
          (datatable(exists: int, NetworkSummary_Protocol_Exists: bool)[1, false]
          | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
          )
          | join (
              NetworkCustomAnalytics_protocol_CL
              | where EventTime_t > min_t
              | project
                  NetworkProtocol=NetworkProtocol_s,
                  DstPortNumber=DstPortNumber_d,
                  DstAppName=DstAppName_s,
                  NetworkDirection=NetworkDirection_s,
                  DvcAction=DvcAction_s,
                  Count=count__d,
                  EventTime=EventTime_t,
                  TimeGenerated,
                  Type
              | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber), exists=int(1)
              )
              on exists
          | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
          ),
          (
          NetworkSummary_Protocol_CL
          | where EventTime > min_t
          | project
              NetworkProtocol,
              DstPortNumber,
              DstAppName,
              NetworkDirection,
              DvcAction,
              Count=count_,
              EventTime,
              TimeGenerated,
              Type
          | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber)
          )
  ;
  let findVolumneBasedAnomaly = allData
      | make-series total=sum(Count) on EventTime from min_t to max_t step dt
      | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit') 
      | mv-expand anomalies, score, baseline, EventTime, total
      | extend
          anomalies = toint(anomalies),
          score = toint(score),
          baseline = toint(baseline),
          EventTime = todatetime(EventTime),
          total = tolong(total)
      | where EventTime >= ago(1d)
      | where score >= 2 * AnomalyThreshold
  ;
  let findAnomalies = (field: string) {
      allData
      | where isnotempty(column_ifexists(field, ""))
      | make-series total=sum(Count) on EventTime from min_t to max_t step dt by column_ifexists(field, "")
      | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit')
      | mv-expand anomalies, score, baseline, EventTime, total
      | extend
          anomalies = toint(anomalies),
          score = toint(score),
          baseline = toint(baseline),
          EventTime = todatetime(EventTime),
          total = tolong(total)
      | where EventTime >= ago(1d)
      | where score >= 2 * AnomalyThreshold
  };
  union
      findAnomalies(fieldForDvcAction),
      findAnomalies(fieldForNetworkDirection),
      findAnomalies(fieldForNetworkProtocol),
      findVolumneBasedAnomaly
  | extend
      anomalyFieldType  = case (
                          isnotempty(column_ifexists(fieldForDvcAction, "")),
                          "DvcAction",
                          isnotempty(column_ifexists(fieldForNetworkDirection, "")),
                          "NetworkDirection",
                          isnotempty(column_ifexists(fieldForNetworkProtocol, "")),
                          "NetworkProtocol",
                          "TotalVolume"
                      ),
      anomalyFieldValue  = case (
                          isnotempty(column_ifexists(fieldForDvcAction, "")),
                          column_ifexists(fieldForDvcAction, ""),
                          isnotempty(column_ifexists(fieldForNetworkDirection, "")),
                          column_ifexists(fieldForNetworkDirection, ""),
                          isnotempty(column_ifexists(fieldForNetworkProtocol, "")),
                          column_ifexists(fieldForNetworkProtocol, ""),
                          "Overall"
                      )  
version: 1.2.0
triggerOperator: gt
queryPeriod: 14d
triggerThreshold: 0
kind: Scheduled
status: Available
relevantTechniques:
- T1095
- T1071
- T1046
- T1030
- T1210
name: Anomaly found in Network Session Traffic (ASIM Network Session schema)
description: |
    'The rule identifies anomalous pattern in network session traffic based on previously seen data, different Device Action, Network Protocol, Network Direction or overall volume. The rule utilize [ASIM](https://aka.ms/AboutASIM) normalization, and is applied to any source which supports the ASIM Network Session schema. This rule leverages log summaries generated by a Summary Rule or Summarized Playbook. If no such summaries are available, the rule falls back to direct analysis using ASIM function.'
severity: Medium
tactics:
- CommandAndControl
- Discovery
- Exfiltration
- LateralMovement
customDetails:
  Score: score
  AnomalyFieldValue: anomalyFieldValue
  AnomalyFieldType: anomalyFieldType
alertDetailsOverride:
  alertDisplayNameFormat: Anomaly was observed with {{anomalyFieldValue}} Traffic
  alertDescriptionFormat: Based on past data, anomaly was observed in {{anomalyFieldValue}} Traffic with a score of {{score}}.
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network Session Essentials/Analytic Rules/AnomalyFoundInNetworkSessionTraffic.yaml
queryFrequency: 1d
eventGroupingSettings:
  aggregationKind: AlertPerResult
tags:
- SchemaVersion: 0.2.4
  Schema: ASimNetworkSessions
id: cd6def0d-3ef0-4d55-a7e3-faa96c46ba12
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/cd6def0d-3ef0-4d55-a7e3-faa96c46ba12')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/cd6def0d-3ef0-4d55-a7e3-faa96c46ba12')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "Based on past data, anomaly was observed in {{anomalyFieldValue}} Traffic with a score of {{score}}.",
          "alertDisplayNameFormat": "Anomaly was observed with {{anomalyFieldValue}} Traffic"
        },
        "alertRuleTemplateName": "cd6def0d-3ef0-4d55-a7e3-faa96c46ba12",
        "customDetails": {
          "AnomalyFieldType": "anomalyFieldType",
          "AnomalyFieldValue": "anomalyFieldValue",
          "Score": "score"
        },
        "description": "'The rule identifies anomalous pattern in network session traffic based on previously seen data, different Device Action, Network Protocol, Network Direction or overall volume. The rule utilize [ASIM](https://aka.ms/AboutASIM) normalization, and is applied to any source which supports the ASIM Network Session schema. This rule leverages log summaries generated by a Summary Rule or Summarized Playbook. If no such summaries are available, the rule falls back to direct analysis using ASIM function.'\n",
        "displayName": "Anomaly found in Network Session Traffic (ASIM Network Session schema)",
        "enabled": true,
        "entityMappings": null,
        "eventGroupingSettings": {
          "aggregationKind": "AlertPerResult"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network Session Essentials/Analytic Rules/AnomalyFoundInNetworkSessionTraffic.yaml",
        "query": "let min_t = ago(14d);\nlet max_t = now();\nlet dt = 1d;\nlet fieldForDvcAction = \"DvcAction\";\nlet fieldForNetworkDirection = \"NetworkDirection\";\nlet fieldForNetworkProtocol = \"NetworkProtocol\";\nlet AnomalyThreshold = 2.5;\nlet eps = materialize (_Im_NetworkSession\n    | project TimeGenerated\n    | where TimeGenerated > ago(5m)\n    | count\n    | extend Count = Count / 300);\nlet maxSummarizedTime = toscalar (\n    union isfuzzy=true\n        (\n        NetworkSummary_Protocol_CL\n        | where EventTime > min_t\n        | summarize max_TimeGenerated=max(EventTime)\n        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)\n        ),\n        (\n        NetworkCustomAnalytics_protocol_CL\n        | where EventTime_t > min_t\n        | summarize max_TimeGenerated=max(EventTime_t)\n        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)\n        ),\n        (\n        print(min_t)\n        | project max_TimeGenerated = print_0\n        )\n    | summarize maxTimeGenerated = max(max_TimeGenerated) \n    );\nlet NetworkSummary_Protocol = materialize(\n    union isfuzzy=true \n        (\n        NetworkSummary_Protocol_CL\n        | where EventTime > ago(1d)\n        | project v = int(2)\n        ),\n        (\n        print int(1) \n        | project v = print_0\n        )\n    | summarize maxv = max(v)\n    | extend\n        NetworkSummary_Protocol_Exists = (maxv > 1),\n        NetworkCustomAnalyticsExists = false\n    );\nlet NetworkCustomAnalytics = materialize(\n    union isfuzzy=true \n        (\n        NetworkCustomAnalytics_protocol_CL\n        | where EventTime_t > ago(1d) \n        | project v = int(2)\n        ),\n        (\n        print int(1) \n        | project v = print_0\n        )\n    | summarize maxv = max(v)\n    | extend\n        NetworkCustomAnalyticsExists = (maxv > 1),\n        NetworkSummary_Protocol_Exists = false\n    );\nlet allData = union isfuzzy=true \n        (\n        (datatable(\n    exists: int,\n    NetworkSummary_Protocol_Exists: bool,\n    NetworkCustomAnalyticsExists: bool\n)[\n    1, false, false\n]\n        | where toscalar(eps) > 1000\n        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists\n        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)\n        | join (\n            _Im_NetworkSession(starttime=todatetime(ago(2d)), endtime=now())\n            | where TimeGenerated > maxSummarizedTime\n            | summarize Count=count()\n                by\n                NetworkProtocol,\n                DstPortNumber,\n                DstAppName,\n                NetworkDirection,\n                DvcAction,\n                bin(TimeGenerated, 10m)\n            | extend\n                EventTime = TimeGenerated,\n                Count = toint(Count),\n                DstPortNumber = toint(DstPortNumber),\n                exists=int(1)\n            )\n            on exists\n        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*\n        ),\n        (\n        (datatable(\n    exists: int,\n    NetworkSummary_Protocol_Exists: bool,\n    NetworkCustomAnalyticsExists: bool\n)[\n    1, false, false\n]\n        | where toscalar(eps) between (501 .. 1000)\n        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists\n        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists)\n        | join (\n            _Im_NetworkSession(starttime=todatetime(ago(3d)), endtime=now())\n            | where TimeGenerated > maxSummarizedTime\n            | summarize Count=count()\n                by\n                NetworkProtocol,\n                DstPortNumber,\n                DstAppName,\n                NetworkDirection,\n                DvcAction,\n                bin(TimeGenerated, 10m)\n            | extend\n                EventTime = TimeGenerated,\n                Count = toint(Count),\n                DstPortNumber = toint(DstPortNumber),\n                exists=int(1)\n            )\n            on exists\n        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*\n        ),\n        (\n        (datatable(\n    exists: int,\n    NetworkSummary_Protocol_Exists: bool,\n    NetworkCustomAnalyticsExists: bool\n)[\n    1, false, false\n]\n        | where toscalar(eps) <= 500\n        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists\n        | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists\n        )\n        | join (\n            _Im_NetworkSession(starttime=todatetime(ago(4d)), endtime=now())\n            | where TimeGenerated > maxSummarizedTime\n            | summarize Count=count()\n                by\n                NetworkProtocol,\n                DstPortNumber,\n                DstAppName,\n                NetworkDirection,\n                DvcAction,\n                bin(TimeGenerated, 10m)\n            | extend\n                EventTime = TimeGenerated,\n                Count = toint(Count),\n                DstPortNumber = toint(DstPortNumber),\n                exists=int(1)\n            )\n            on exists\n        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*\n        ),\n        (\n        (datatable(exists: int, NetworkSummary_Protocol_Exists: bool)[1, false]\n        | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists\n        )\n        | join (\n            NetworkCustomAnalytics_protocol_CL\n            | where EventTime_t > min_t\n            | project\n                NetworkProtocol=NetworkProtocol_s,\n                DstPortNumber=DstPortNumber_d,\n                DstAppName=DstAppName_s,\n                NetworkDirection=NetworkDirection_s,\n                DvcAction=DvcAction_s,\n                Count=count__d,\n                EventTime=EventTime_t,\n                TimeGenerated,\n                Type\n            | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber), exists=int(1)\n            )\n            on exists\n        | project-away exists*, maxv, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*\n        ),\n        (\n        NetworkSummary_Protocol_CL\n        | where EventTime > min_t\n        | project\n            NetworkProtocol,\n            DstPortNumber,\n            DstAppName,\n            NetworkDirection,\n            DvcAction,\n            Count=count_,\n            EventTime,\n            TimeGenerated,\n            Type\n        | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber)\n        )\n;\nlet findVolumneBasedAnomaly = allData\n    | make-series total=sum(Count) on EventTime from min_t to max_t step dt\n    | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit') \n    | mv-expand anomalies, score, baseline, EventTime, total\n    | extend\n        anomalies = toint(anomalies),\n        score = toint(score),\n        baseline = toint(baseline),\n        EventTime = todatetime(EventTime),\n        total = tolong(total)\n    | where EventTime >= ago(1d)\n    | where score >= 2 * AnomalyThreshold\n;\nlet findAnomalies = (field: string) {\n    allData\n    | where isnotempty(column_ifexists(field, \"\"))\n    | make-series total=sum(Count) on EventTime from min_t to max_t step dt by column_ifexists(field, \"\")\n    | extend (anomalies, score, baseline) = series_decompose_anomalies(total, AnomalyThreshold, -1, 'linefit')\n    | mv-expand anomalies, score, baseline, EventTime, total\n    | extend\n        anomalies = toint(anomalies),\n        score = toint(score),\n        baseline = toint(baseline),\n        EventTime = todatetime(EventTime),\n        total = tolong(total)\n    | where EventTime >= ago(1d)\n    | where score >= 2 * AnomalyThreshold\n};\nunion\n    findAnomalies(fieldForDvcAction),\n    findAnomalies(fieldForNetworkDirection),\n    findAnomalies(fieldForNetworkProtocol),\n    findVolumneBasedAnomaly\n| extend\n    anomalyFieldType  = case (\n                        isnotempty(column_ifexists(fieldForDvcAction, \"\")),\n                        \"DvcAction\",\n                        isnotempty(column_ifexists(fieldForNetworkDirection, \"\")),\n                        \"NetworkDirection\",\n                        isnotempty(column_ifexists(fieldForNetworkProtocol, \"\")),\n                        \"NetworkProtocol\",\n                        \"TotalVolume\"\n                    ),\n    anomalyFieldValue  = case (\n                        isnotempty(column_ifexists(fieldForDvcAction, \"\")),\n                        column_ifexists(fieldForDvcAction, \"\"),\n                        isnotempty(column_ifexists(fieldForNetworkDirection, \"\")),\n                        column_ifexists(fieldForNetworkDirection, \"\"),\n                        isnotempty(column_ifexists(fieldForNetworkProtocol, \"\")),\n                        column_ifexists(fieldForNetworkProtocol, \"\"),\n                        \"Overall\"\n                    )\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl",
          "Discovery",
          "Exfiltration",
          "LateralMovement"
        ],
        "tags": [
          {
            "Schema": "ASimNetworkSessions",
            "SchemaVersion": "0.2.4"
          }
        ],
        "techniques": [
          "T1030",
          "T1046",
          "T1071",
          "T1095",
          "T1210"
        ],
        "templateVersion": "1.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}