Detection rules › Kusto
Port Sweep
'Identifies a source IP scanning same open ports on the Azure Firewall IPs. This can indicate malicious scanning of port by an attacker, trying to reveal IPs with specific ports open in the organization. The ports can be compromised by attackers for initial access, most often by exploiting vulnerability. Configurable Parameters: - Port sweep time - the time range to look for multiple hosts scanned. Default is set to 30 seconds. - Minimum different hosts threshold - alert only if more than this number of hosts scanned. Default is set to 200.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | |
| Discovery |
Rule body
id: 720335f4-ee8c-4270-9424-d0859222168c
name: Port Sweep
description: |
'Identifies a source IP scanning same open ports on the Azure Firewall IPs. This can indicate malicious scanning of port by an attacker, trying to reveal IPs with specific ports open in the organization. The ports can be compromised by attackers for initial access, most often by exploiting vulnerability.
Configurable Parameters:
- Port sweep time - the time range to look for multiple hosts scanned. Default is set to 30 seconds.
- Minimum different hosts threshold - alert only if more than this number of hosts scanned. Default is set to 200.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: AzureFirewall
dataTypes:
- AzureDiagnostics
- AZFWApplicationRule
- AZFWNetworkRule
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Discovery
- Reconnaissance
relevantTechniques:
- T1046
- T1595.001
query: |
let MinimumDifferentHostsThreshold = 200;
let ExcludedPorts = dynamic([80 , 443]);
let BinTime = 30s;
union isfuzzy=true(
AZFWApplicationRule
| where DestinationPort !in (ExcludedPorts)
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
| mv-expand Fqdn = AlertTimedCountHostsInBinTime),
(AZFWNetworkRule
| extend Fqdn = DestinationIp
| where DestinationPort !in (ExcludedPorts)
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
| mv-expand Fqdn = AlertTimedCountHostsInBinTime),
(AzureDiagnostics
| where OperationName == "AzureFirewallApplicationRuleLog" or OperationName == "AzureFirewallNetworkRuleLog"
| parse msg_s with * "from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int ". " * "Action: " Action "." *
| where DestinationPort !in (ExcludedPorts)
| where isnotempty(Fqdn) and isnotempty(SourceIp) and isnotempty(DestinationPort)
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
| mv-expand Fqdn = AlertTimedCountHostsInBinTime)
| project bin(TimeGenerated, BinTime), SourceIp, DestinationPort, AlertTimedCountHostsInBinTime, Fqdn
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIp
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Fqdn
customDetails:
DestinationPort: DestinationPort
alertDetailsOverride:
alertDisplayNameFormat: 'Port Sweep Detected from {{SourceIp}} on Port {{DestinationPort}}'
alertDescriptionFormat: 'Source IP {{SourceIp}} has scanned {{AlertTimedCountHostsInBinTime}} different hosts on port {{DestinationPort}} within a short time frame, which may indicate reconnaissance activity.'
version: 1.2.3
kind: Scheduled
Stages and Predicates
Stage 0: let
let MinimumDifferentHostsThreshold = 200;
let ExcludedPorts = dynamic([80 , 443]);
let BinTime = 30s;
Stage 1: union
union of 3 branches
Stage 2: source
AZFWApplicationRule
Stage 3: where
| where DestinationPort !in (ExcludedPorts)
Stage 4: summarize
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
Stage 5: where
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
Stage 6: mv-expand
| mv-expand Fqdn = AlertTimedCountHostsInBinTime
Stage 7: source
AZFWNetworkRule
Stage 8: extend
| extend Fqdn = DestinationIp
Stage 9: where
| where DestinationPort !in (ExcludedPorts)
Stage 10: summarize
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
Stage 11: where
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
Stage 12: mv-expand
| mv-expand Fqdn = AlertTimedCountHostsInBinTime
Stage 13: source
AzureDiagnostics
Stage 14: where
| where OperationName == "AzureFirewallApplicationRuleLog" or OperationName == "AzureFirewallNetworkRuleLog"
Stage 15: parse
| parse msg_s with * "from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int ". " * "Action: " Action "." *
Stage 16: where
| where DestinationPort !in (ExcludedPorts)
Stage 17: where
| where isnotempty(Fqdn) and isnotempty(SourceIp) and isnotempty(DestinationPort)
Stage 18: summarize
| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort
Stage 19: where
| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold
Stage 20: mv-expand
| mv-expand Fqdn = AlertTimedCountHostsInBinTime
Stage 21: project
project AlertTimedCountHostsInBinTime, DestinationPort, Fqdn, SourceIp
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
DestinationPort | is_not_null | field:"DestinationPort" kind:is_not_null | |
Fqdn | is_not_null | field:"Fqdn" kind:is_not_null | |
OperationName | eq |
| field:"OperationName" kind:eq |
SourceIp | is_not_null | field:"src_ip" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
DestinationPort | in | 443, 80 | excludes:DestinationPort field:"DestinationPort" value:"443" field:"DestinationPort" value:"80" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AlertTimedCountHostsInBinTime | project |
DestinationPort | project |
Fqdn | project |
SourceIp | project |