Analytic rule catalog
Detect port misuse by static threshold ASIM Network Session schema
Back
| Id | 156997bd-da0f-4729-b47a-0a3e02dd50c8 |
| Rulename | Detect port misuse by static threshold (ASIM Network Session schema) |
| Description | This detection rule detects port usage above the configured threshold. 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. |
| Severity | Medium |
| Tactics | CommandAndControl Execution InitialAccess |
| Techniques | T1095 T1059 T1203 T1190 |
| 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 | 20m |
| Query period | 60m |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network%20Session%20Essentials/Analytic%20Rules/DetectPortMisuseByStaticThreshold.yaml |
| Version | 1.2.1 |
| Arm template | 156997bd-da0f-4729-b47a-0a3e02dd50c8.json |
let lookback = 20m;
let mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')
| where Type == "Detection" and ThresholdType == "Static" 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 NetworkSummary_Protocol = materialize(
union isfuzzy=true
(
NetworkSummary_Protocol_CL
| 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
(
NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| 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
]
| join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
| join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists
)
| join (
_Im_NetworkSession(starttime=bin(now(-20m), 20m), endtime=bin(now(), 20m))
| where TimeGenerated > bin(now(-20m), 20m)
| summarize Count=count()
by
NetworkProtocol,
DstPortNumber,
DstAppName,
NetworkDirection,
DvcAction,
bin(TimeGenerated, 20m)
| 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 (
NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| where EventTime_t == toscalar(NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| summarize max(EventTime_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 == toscalar(NetworkSummary_Protocol_CL
| summarize max(EventTime))
| 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)
| summarize Sum=sum(Count) by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction
| join kind=inner ['mapping'] where Ports has tostring(DstPortNumber)
| where Sum > Threshold
and (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
relevantTechniques:
- T1095
- T1059
- T1203
- T1190
alertDetailsOverride:
alertSeverityColumnName: Severity
alertTacticsColumnName: Tactic
alertDisplayNameFormat: Detected {{Name}}
alertDescriptionFormat: '{{Description}}'
id: 156997bd-da0f-4729-b47a-0a3e02dd50c8
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network%20Session%20Essentials/Analytic%20Rules/DetectPortMisuseByStaticThreshold.yaml
triggerOperator: gt
tactics:
- CommandAndControl
- Execution
- InitialAccess
kind: Scheduled
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
queryPeriod: 60m
eventGroupingSettings:
aggregationKind: AlertPerResult
severity: Medium
tags:
- SchemaVersion: 0.2.4
Schema: ASimNetworkSessions
triggerThreshold: 0
version: 1.2.1
customDetails:
DstPortNumber: DstPortNumber
AllNetworkDirections: NetworkDirections
AllNetworkProtocols: NetworkProtocols
AllDvcAction: DvcActions
name: Detect port misuse by static threshold (ASIM Network Session schema)
status: Available
query: |
let lookback = 20m;
let mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')
| where Type == "Detection" and ThresholdType == "Static" 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 NetworkSummary_Protocol = materialize(
union isfuzzy=true
(
NetworkSummary_Protocol_CL
| 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
(
NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| 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
]
| join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists
| join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists
)
| join (
_Im_NetworkSession(starttime=bin(now(-20m), 20m), endtime=bin(now(), 20m))
| where TimeGenerated > bin(now(-20m), 20m)
| summarize Count=count()
by
NetworkProtocol,
DstPortNumber,
DstAppName,
NetworkDirection,
DvcAction,
bin(TimeGenerated, 20m)
| 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 (
NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| where EventTime_t == toscalar(NetworkSessionEssentialsCustomParser
| where Type in ("NetworkCustomAnalytics_protocol_CL", "NetworkCustomAnalytics_protocolV1_CL")
| summarize max(EventTime_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 == toscalar(NetworkSummary_Protocol_CL
| summarize max(EventTime))
| 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)
| summarize Sum=sum(Count) by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction
| join kind=inner ['mapping'] where Ports has tostring(DstPortNumber)
| where Sum > Threshold
and (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
description: |
'This detection rule detects port usage above the configured threshold. 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.'
queryFrequency: 20m
{
"$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/156997bd-da0f-4729-b47a-0a3e02dd50c8')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/156997bd-da0f-4729-b47a-0a3e02dd50c8')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "{{Description}}",
"alertDisplayNameFormat": "Detected {{Name}}",
"alertSeverityColumnName": "Severity",
"alertTacticsColumnName": "Tactic"
},
"alertRuleTemplateName": "156997bd-da0f-4729-b47a-0a3e02dd50c8",
"customDetails": {
"AllDvcAction": "DvcActions",
"AllNetworkDirections": "NetworkDirections",
"AllNetworkProtocols": "NetworkProtocols",
"DstPortNumber": "DstPortNumber"
},
"description": "'This detection rule detects port usage above the configured threshold. 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 static threshold (ASIM Network Session schema)",
"enabled": true,
"entityMappings": null,
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Network%20Session%20Essentials/Analytic%20Rules/DetectPortMisuseByStaticThreshold.yaml",
"query": "let lookback = 20m; \nlet mapping = _GetWatchlist('NetworkSession_Monitor_Configuration')\n | where Type == \"Detection\" and ThresholdType == \"Static\" 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);\nlet NetworkSummary_Protocol = materialize(\n union isfuzzy=true \n (\n NetworkSummary_Protocol_CL\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 NetworkSessionEssentialsCustomParser\n | where Type in (\"NetworkCustomAnalytics_protocol_CL\", \"NetworkCustomAnalytics_protocolV1_CL\")\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 | join (NetworkSummary_Protocol) on NetworkSummary_Protocol_Exists\n | join (NetworkCustomAnalytics) on NetworkCustomAnalyticsExists\n )\n | join (\n _Im_NetworkSession(starttime=bin(now(-20m), 20m), endtime=bin(now(), 20m))\n | where TimeGenerated > bin(now(-20m), 20m)\n | summarize Count=count()\n by\n NetworkProtocol,\n DstPortNumber,\n DstAppName,\n NetworkDirection,\n DvcAction,\n bin(TimeGenerated, 20m)\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 NetworkSessionEssentialsCustomParser\n | where Type in (\"NetworkCustomAnalytics_protocol_CL\", \"NetworkCustomAnalytics_protocolV1_CL\")\n | where EventTime_t == toscalar(NetworkSessionEssentialsCustomParser\n | where Type in (\"NetworkCustomAnalytics_protocol_CL\", \"NetworkCustomAnalytics_protocolV1_CL\")\n | summarize max(EventTime_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 == toscalar(NetworkSummary_Protocol_CL\n | summarize max(EventTime))\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| summarize Sum=sum(Count) by DstPortNumber, NetworkProtocol, NetworkDirection, DvcAction \n| join kind=inner ['mapping'] where Ports has tostring(DstPortNumber)\n| where Sum > Threshold \n and (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": "PT20M",
"queryPeriod": "PT60M",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CommandAndControl",
"Execution",
"InitialAccess"
],
"tags": [
{
"Schema": "ASimNetworkSessions",
"SchemaVersion": "0.2.4"
}
],
"techniques": [
"T1059",
"T1095",
"T1190",
"T1203"
],
"templateVersion": "1.2.1",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}