Port Sweep
Id | 720335f4-ee8c-4270-9424-d0859222168c |
Rulename | 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 |
Tactics | Discovery |
Techniques | T1046 |
Required data connectors | AzureFirewall |
Kind | Scheduled |
Query frequency | 1h |
Query period | 1d |
Trigger threshold | 1 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure Firewall/Analytic Rules/Azure Firewall - Port Sweep.yaml |
Version | 1.2.2 |
Arm template | 720335f4-ee8c-4270-9424-d0859222168c.json |
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
status: Available
triggerOperator: gt
triggerThreshold: 1
name: Port Sweep
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure Firewall/Analytic Rules/Azure Firewall - Port Sweep.yaml
queryPeriod: 1d
severity: Medium
kind: Scheduled
entityMappings:
- entityType: IP
fieldMappings:
- columnName: SourceIp
identifier: Address
- entityType: URL
fieldMappings:
- columnName: Fqdn
identifier: Url
queryFrequency: 1h
relevantTechniques:
- T1046
requiredDataConnectors:
- dataTypes:
- AzureDiagnostics
- AZFWApplicationRule
- AZFWNetworkRule
connectorId: AzureFirewall
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.'
tactics:
- Discovery
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
id: 720335f4-ee8c-4270-9424-d0859222168c
version: 1.2.2
{
"$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/720335f4-ee8c-4270-9424-d0859222168c')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/720335f4-ee8c-4270-9424-d0859222168c')]",
"properties": {
"alertRuleTemplateName": "720335f4-ee8c-4270-9424-d0859222168c",
"customDetails": null,
"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.\n\nConfigurable Parameters:\n\n- Port sweep time - the time range to look for multiple hosts scanned. Default is set to 30 seconds.\n- Minimum different hosts threshold - alert only if more than this number of hosts scanned. Default is set to 200.'\n",
"displayName": "Port Sweep",
"enabled": true,
"entityMappings": [
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "SourceIp",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Fqdn",
"identifier": "Url"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure Firewall/Analytic Rules/Azure Firewall - Port Sweep.yaml",
"query": "let MinimumDifferentHostsThreshold = 200;\nlet ExcludedPorts = dynamic([80 , 443]);\nlet BinTime = 30s;\nunion isfuzzy=true(\nAZFWApplicationRule\n| where DestinationPort !in (ExcludedPorts)\n| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort\n| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold\n| mv-expand Fqdn = AlertTimedCountHostsInBinTime),\n(AZFWNetworkRule\n| extend Fqdn = DestinationIp\n| where DestinationPort !in (ExcludedPorts)\n| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort\n| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold\n| mv-expand Fqdn = AlertTimedCountHostsInBinTime),\n(AzureDiagnostics\n| where OperationName == \"AzureFirewallApplicationRuleLog\" or OperationName == \"AzureFirewallNetworkRuleLog\"\n| parse msg_s with * \"from \" SourceIp \":\" SourcePort:int \" to \" Fqdn \":\" DestinationPort:int \". \" * \"Action: \" Action \".\" *\n| where DestinationPort !in (ExcludedPorts)\n| where isnotempty(Fqdn) and isnotempty(SourceIp) and isnotempty(DestinationPort)\n| summarize AlertTimedCountHostsInBinTime = make_set(Fqdn) by SourceIp, bin(TimeGenerated, BinTime), DestinationPort\n| where array_length(AlertTimedCountHostsInBinTime) > MinimumDifferentHostsThreshold\n| mv-expand Fqdn = AlertTimedCountHostsInBinTime)\n| project bin(TimeGenerated, BinTime), SourceIp, DestinationPort, AlertTimedCountHostsInBinTime, Fqdn\n",
"queryFrequency": "PT1H",
"queryPeriod": "P1D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Discovery"
],
"techniques": [
"T1046"
],
"templateVersion": "1.2.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 1
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}