Anomaly found in Network Session Traffic ASIM Network Session schema
Id | cd6def0d-3ef0-4d55-a7e3-faa96c46ba12 |
Rulename | 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 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 |
Techniques | T1095 T1071 T1046 T1030 T1210 |
Required data connectors | AIVectraStream AWSS3 AzureFirewall AzureMonitor(VMInsights) AzureNSG CheckPoint CiscoASA CiscoAsaAma CiscoMeraki Corelight Fortinet MicrosoftSysmonForLinux MicrosoftThreatProtection PaloAltoNetworks SecurityEvents WindowsForwardedEvents WindowsSecurityEvents Zscaler |
Kind | Scheduled |
Query frequency | 1d |
Query period | 14d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network Session Essentials/Analytic Rules/AnomalyFoundInNetworkSessionTraffic.yaml |
Version | 1.2.0 |
Arm template | cd6def0d-3ef0-4d55-a7e3-faa96c46ba12.json |
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"
)
relevantTechniques:
- T1095
- T1071
- T1046
- T1030
- T1210
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
triggerThreshold: 0
queryFrequency: 1d
queryPeriod: 14d
eventGroupingSettings:
aggregationKind: AlertPerResult
version: 1.2.0
tags:
- SchemaVersion: 0.2.4
Schema: ASimNetworkSessions
id: cd6def0d-3ef0-4d55-a7e3-faa96c46ba12
customDetails:
AnomalyFieldType: anomalyFieldType
Score: score
AnomalyFieldValue: anomalyFieldValue
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
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"
)
status: Available
kind: Scheduled
tactics:
- CommandAndControl
- Discovery
- Exfiltration
- LateralMovement
severity: Medium
name: Anomaly found in Network Session Traffic (ASIM Network Session schema)
triggerOperator: gt
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.'
{
"$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"
}
]
}