Detection rules › Kusto
Port scan detected (ASIM Network Session schema)
This rule identifies a possible port scan, in which a single source tries to access a large number of different ports is a short time frame. This may indicate that a port scanner is trying to identify open ports in order to penetrate a system. This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM NetworkSession schema
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Discovery | T1046 Network Service Discovery |
Event coverage
Rule body kusto
id: 1da9853f-3dea-4ea9-b7e5-26730da3d537
name: Port scan detected (ASIM Network Session schema)
description: |
'This rule identifies a possible port scan, in which a single source tries to access a large number of different ports is a short time frame. This may indicate that a [port scanner](https://en.wikipedia.org/wiki/Port_scanner) is trying to identify open ports in order to penetrate a system.
This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema'
alertDetailsOverride:
alertDisplayNameFormat: Potential port scan from {{SrcIpAddr}}
alertDescriptionFormat: A port scan has been performed from address {{SrcIpAddr}} over {{AttemptedPortsCount}} ports within 5 minutes. This may indicate that a [port scanner](https://en.wikipedia.org/wiki/Port_scanner) is trying to identify open ports in order to penetrate a system.
severity: Medium
status: Available
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
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Discovery
relevantTechniques:
- T1046
tags:
- ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Sophos%20XG%20Firewall/Analytic%20Rules/PortScanDetected.yaml
version: 1.0.0
- Schema: ASimNetworkSessions
SchemaVersion: 0.2.4
query: |
let PortScanThreshold = 50;
_Im_NetworkSession
| where ipv4_is_private(SrcIpAddr) == False
| where SrcIpAddr !in ("127.0.0.1", "::1")
| summarize AttemptedPortsCount=dcount(DstPortNumber), AttemptedPorts=make_set(DstPortNumber, 100), ReportedBy=make_set(strcat(EventVendor, "/", EventProduct), 20) by SrcIpAddr, bin(TimeGenerated, 5m)
| where AttemptedPortsCount > PortScanThreshold
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
customDetails:
AttemptedPortsCount: AttemptedPortsCount
version: 1.0.6
kind: Scheduled
Stages and Predicates
Parameters
let PortScanThreshold = 50;
Stage 1: source
_Im_NetworkSession
Stage 2: where
| where ipv4_is_private(SrcIpAddr) == False
Stage 3: where
| where SrcIpAddr !in ("127.0.0.1", "::1")
Stage 4: summarize
| summarize AttemptedPortsCount=dcount(DstPortNumber), AttemptedPorts=make_set(DstPortNumber, 100), ReportedBy=make_set(strcat(EventVendor, "/", EventProduct), 20) by SrcIpAddr, bin(TimeGenerated, 5m)
Stage 5: where
| where AttemptedPortsCount > PortScanThreshold
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
SrcIpAddr | cidr_match | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 127.0.0.0/8 |
SrcIpAddr | in | 127.0.0.1, ::1 |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
AttemptedPortsCount | gt |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
AttemptedPorts | summarize |
AttemptedPortsCount | summarize |
ReportedBy | summarize |
SrcIpAddr | summarize |