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

Detect port misuse by anomaly based detection ASIM Network Session schema

Back
Idcbf07406-fa2a-48b0-82b8-efad58db14ec
RulenameDetect port misuse by anomaly based detection (ASIM Network Session schema)
DescriptionThis rule detects anomalous pattern in port usage. The rule utilize ASIM normalization, and is applied to any source which supports the ASIM Network Session schema. To tune the rule to your environment configure it using the ‘NetworkSession_Monitor_Configuration’ watchlist. 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
LateralMovement
Execution
InitialAccess
TechniquesT1095
T1059
T1203
T1190
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/DetectPortMisuseByAnomalyBasedDetection.yaml
Version1.2.0
Arm templatecbf07406-fa2a-48b0-82b8-efad58db14ec.json
Deploy To Azure
let lookback = 14d;
let mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')
    | where Type == "Detection" and ThresholdType == "Anomaly" and Severity != "Disabled"  
    | extend
        Ports = split(Ports, ","),
        App = split(App, ","),
        Protocol = split(Protocol, ","),
        Direction = split(Direction, ","),
        Action = split(Action, ",")
    | project
        Ports,
        App,
        Protocol,
        Direction,
        Action,
        Type,
        ThresholdType,
        Threshold,
        Severity,
        Tactic,
        Name,
        Description
    | mv-expand Ports
    | mv-expand App
    | mv-expand Protocol
    | mv-expand Direction
    | mv-expand Action
    | extend
        Ports = tostring(Ports),
        App = tostring(App),
        Protocol = tostring(Protocol),
        Direction = tostring(Direction),
        Action = tostring(Action),
        Threshold = toint(Threshold)
;
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 > ago(lookback)
        | summarize max_TimeGenerated=max(EventTime)
        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
        ),
        (
        NetworkCustomAnalytics_protocol_CL
        | where EventTime_t > ago(lookback)
        | summarize max_TimeGenerated=max(EventTime_t)
        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
        ),
        (
        print(ago(lookback))
        | 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 > ago(lookback)
            | 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 > ago(lookback)
        | project
            NetworkProtocol,
            DstPortNumber,
            DstAppName,
            NetworkDirection,
            DvcAction,
            Count=count_,
            EventTime,
            TimeGenerated,
            Type
        | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber)
        )
    | project-away exists*, maxv*, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
;
allData
| where isnotempty(DstPortNumber)
| make-series Total=sum(Count) on EventTime from ago(lookback) to now() step 1d by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction
| 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)
| extend DstPortNumber = tostring(DstPortNumber)
| where score >= 2 * AnomalyThreshold and baseline > 0
| join kind=inner ['mapping'] where Ports == DstPortNumber
| where (Protocol == "*" or Protocol has NetworkProtocol)
    and (Direction == "*" or Direction has NetworkDirection)
    and (Action == "*" or Action has DvcAction)  
| project
    Name,
    Description,
    NetworkProtocol,
    DstPortNumber,
    NetworkDirection,
    DvcAction,
    Severity,
    Tactic
| summarize
    NetworkProtocols=make_set_if(NetworkProtocol, isnotempty(NetworkProtocol), 20), 
    NetworkDirections=make_set_if(NetworkDirection, isnotempty(NetworkDirection), 5), 
    DvcActions=make_set_if(DvcAction, isnotempty(DvcAction), 10)
    by Name, Severity, Tactic, DstPortNumber, Description
version: 1.2.0
severity: Medium
triggerOperator: gt
id: cbf07406-fa2a-48b0-82b8-efad58db14ec
tags:
- SchemaVersion: 0.2.4
  Schema: ASimNetworkSessions
eventGroupingSettings:
  aggregationKind: AlertPerResult
tactics:
- CommandAndControl
- LateralMovement
- Execution
- InitialAccess
triggerThreshold: 0
query: |
  let lookback = 14d;
  let mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')
      | where Type == "Detection" and ThresholdType == "Anomaly" and Severity != "Disabled"  
      | extend
          Ports = split(Ports, ","),
          App = split(App, ","),
          Protocol = split(Protocol, ","),
          Direction = split(Direction, ","),
          Action = split(Action, ",")
      | project
          Ports,
          App,
          Protocol,
          Direction,
          Action,
          Type,
          ThresholdType,
          Threshold,
          Severity,
          Tactic,
          Name,
          Description
      | mv-expand Ports
      | mv-expand App
      | mv-expand Protocol
      | mv-expand Direction
      | mv-expand Action
      | extend
          Ports = tostring(Ports),
          App = tostring(App),
          Protocol = tostring(Protocol),
          Direction = tostring(Direction),
          Action = tostring(Action),
          Threshold = toint(Threshold)
  ;
  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 > ago(lookback)
          | summarize max_TimeGenerated=max(EventTime)
          | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
          ),
          (
          NetworkCustomAnalytics_protocol_CL
          | where EventTime_t > ago(lookback)
          | summarize max_TimeGenerated=max(EventTime_t)
          | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)
          ),
          (
          print(ago(lookback))
          | 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 > ago(lookback)
              | 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 > ago(lookback)
          | project
              NetworkProtocol,
              DstPortNumber,
              DstAppName,
              NetworkDirection,
              DvcAction,
              Count=count_,
              EventTime,
              TimeGenerated,
              Type
          | extend Count = toint(Count), DstPortNumber = toint(DstPortNumber)
          )
      | project-away exists*, maxv*, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*
  ;
  allData
  | where isnotempty(DstPortNumber)
  | make-series Total=sum(Count) on EventTime from ago(lookback) to now() step 1d by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction
  | 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)
  | extend DstPortNumber = tostring(DstPortNumber)
  | where score >= 2 * AnomalyThreshold and baseline > 0
  | join kind=inner ['mapping'] where Ports == DstPortNumber
  | where (Protocol == "*" or Protocol has NetworkProtocol)
      and (Direction == "*" or Direction has NetworkDirection)
      and (Action == "*" or Action has DvcAction)  
  | project
      Name,
      Description,
      NetworkProtocol,
      DstPortNumber,
      NetworkDirection,
      DvcAction,
      Severity,
      Tactic
  | summarize
      NetworkProtocols=make_set_if(NetworkProtocol, isnotempty(NetworkProtocol), 20), 
      NetworkDirections=make_set_if(NetworkDirection, isnotempty(NetworkDirection), 5), 
      DvcActions=make_set_if(DvcAction, isnotempty(DvcAction), 10)
      by Name, Severity, Tactic, DstPortNumber, Description  
name: Detect port misuse by anomaly based detection (ASIM Network Session schema)
relevantTechniques:
- T1095
- T1059
- T1203
- T1190
requiredDataConnectors:
- dataTypes:
  - AWSVPCFlow
  connectorId: AWSS3
- dataTypes:
  - DeviceNetworkEvents
  connectorId: MicrosoftThreatProtection
- dataTypes:
  - SecurityEvent
  connectorId: SecurityEvents
- dataTypes:
  - SecurityEvent
  connectorId: WindowsSecurityEvents
- dataTypes:
  - WindowsEvent
  connectorId: WindowsForwardedEvents
- dataTypes:
  - CommonSecurityLog
  connectorId: Zscaler
- dataTypes:
  - Syslog
  connectorId: MicrosoftSysmonForLinux
- dataTypes:
  - CommonSecurityLog
  connectorId: PaloAltoNetworks
- dataTypes:
  - VMConnection
  connectorId: AzureMonitor(VMInsights)
- dataTypes:
  - AzureDiagnostics
  connectorId: AzureFirewall
- dataTypes:
  - AzureDiagnostics
  connectorId: AzureNSG
- dataTypes:
  - CommonSecurityLog
  connectorId: CiscoASA
- dataTypes:
  - CommonSecurityLog
  connectorId: CiscoAsaAma
- dataTypes:
  - Corelight_CL
  connectorId: Corelight
- dataTypes:
  - VectraStream
  connectorId: AIVectraStream
- dataTypes:
  - CommonSecurityLog
  connectorId: CheckPoint
- dataTypes:
  - CommonSecurityLog
  connectorId: Fortinet
- dataTypes:
  - Syslog
  - CiscoMerakiNativePoller
  connectorId: CiscoMeraki
status: Available
queryPeriod: 14d
kind: Scheduled
alertDetailsOverride:
  alertDescriptionFormat: '{{Description}}'
  alertTacticsColumnName: Tactic
  alertSeverityColumnName: Severity
  alertDisplayNameFormat: Detected {{Name}}
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network Session Essentials/Analytic Rules/DetectPortMisuseByAnomalyBasedDetection.yaml
customDetails:
  AllNetworkDirections: NetworkDirections
  AllDvcAction: DvcActions
  AllNetworkProtocols: NetworkProtocols
  DstPortNumber: DstPortNumber
queryFrequency: 1d
description: |
    'This rule detects anomalous pattern in port usage. The rule utilize [ASIM](https://aka.ms/AboutASIM) normalization, and is applied to any source which supports the ASIM Network Session schema. To tune the rule to your environment configure it using the 'NetworkSession_Monitor_Configuration' watchlist. 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.'
{
  "$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/cbf07406-fa2a-48b0-82b8-efad58db14ec')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/cbf07406-fa2a-48b0-82b8-efad58db14ec')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "{{Description}}",
          "alertDisplayNameFormat": "Detected {{Name}}",
          "alertSeverityColumnName": "Severity",
          "alertTacticsColumnName": "Tactic"
        },
        "alertRuleTemplateName": "cbf07406-fa2a-48b0-82b8-efad58db14ec",
        "customDetails": {
          "AllDvcAction": "DvcActions",
          "AllNetworkDirections": "NetworkDirections",
          "AllNetworkProtocols": "NetworkProtocols",
          "DstPortNumber": "DstPortNumber"
        },
        "description": "'This rule detects anomalous pattern in port usage. The rule utilize [ASIM](https://aka.ms/AboutASIM) normalization, and is applied to any source which supports the ASIM Network Session schema. To tune the rule to your environment configure it using the 'NetworkSession_Monitor_Configuration' watchlist. 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": "Detect port misuse by anomaly based detection (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/DetectPortMisuseByAnomalyBasedDetection.yaml",
        "query": "let lookback = 14d;\nlet mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')\n    | where Type == \"Detection\" and ThresholdType == \"Anomaly\" and Severity != \"Disabled\"  \n    | extend\n        Ports = split(Ports, \",\"),\n        App = split(App, \",\"),\n        Protocol = split(Protocol, \",\"),\n        Direction = split(Direction, \",\"),\n        Action = split(Action, \",\")\n    | project\n        Ports,\n        App,\n        Protocol,\n        Direction,\n        Action,\n        Type,\n        ThresholdType,\n        Threshold,\n        Severity,\n        Tactic,\n        Name,\n        Description\n    | mv-expand Ports\n    | mv-expand App\n    | mv-expand Protocol\n    | mv-expand Direction\n    | mv-expand Action\n    | extend\n        Ports = tostring(Ports),\n        App = tostring(App),\n        Protocol = tostring(Protocol),\n        Direction = tostring(Direction),\n        Action = tostring(Action),\n        Threshold = toint(Threshold)\n;\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 > ago(lookback)\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 > ago(lookback)\n        | summarize max_TimeGenerated=max(EventTime_t)\n        | extend max_TimeGenerated = datetime_add('minute', 20, max_TimeGenerated)\n        ),\n        (\n        print(ago(lookback))\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        )\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        )\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 > ago(lookback)\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 > ago(lookback)\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    | project-away exists*, maxv*, NetworkSummary_Protocol_Exists*, NetworkCustomAnalyticsExists*\n;\nallData\n| where isnotempty(DstPortNumber)\n| make-series Total=sum(Count) on EventTime from ago(lookback) to now() step 1d by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction\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| extend DstPortNumber = tostring(DstPortNumber)\n| where score >= 2 * AnomalyThreshold and baseline > 0\n| join kind=inner ['mapping'] where Ports == DstPortNumber\n| where (Protocol == \"*\" or Protocol has NetworkProtocol)\n    and (Direction == \"*\" or Direction has NetworkDirection)\n    and (Action == \"*\" or Action has DvcAction)  \n| project\n    Name,\n    Description,\n    NetworkProtocol,\n    DstPortNumber,\n    NetworkDirection,\n    DvcAction,\n    Severity,\n    Tactic\n| summarize\n    NetworkProtocols=make_set_if(NetworkProtocol, isnotempty(NetworkProtocol), 20), \n    NetworkDirections=make_set_if(NetworkDirection, isnotempty(NetworkDirection), 5), \n    DvcActions=make_set_if(DvcAction, isnotempty(DvcAction), 10)\n    by Name, Severity, Tactic, DstPortNumber, Description\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl",
          "Execution",
          "InitialAccess",
          "LateralMovement"
        ],
        "tags": [
          {
            "Schema": "ASimNetworkSessions",
            "SchemaVersion": "0.2.4"
          }
        ],
        "techniques": [
          "T1059",
          "T1095",
          "T1190",
          "T1203"
        ],
        "templateVersion": "1.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}