Back
Id720335f4-ee8c-4270-9424-d0859222168c
RulenamePort Sweep
DescriptionIdentifies 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.
SeverityMedium
TacticsDiscovery
Reconnaissance
TechniquesT1046
T1595.001
Required data connectorsAzureFirewall
KindScheduled
Query frequency1h
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Firewall/Analytic%20Rules/Azure%20Firewall%20-%20Port%20Sweep.yaml
Version1.2.3
Arm template720335f4-ee8c-4270-9424-d0859222168c.json
Deploy To Azure
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
name: Port Sweep
tactics:
- Discovery
- Reconnaissance
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.
queryFrequency: 1h
triggerThreshold: 0
customDetails:
  DestinationPort: DestinationPort
relevantTechniques:
- T1046
- T1595.001
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Firewall/Analytic%20Rules/Azure%20Firewall%20-%20Port%20Sweep.yaml
kind: Scheduled
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.'
requiredDataConnectors:
- connectorId: AzureFirewall
  dataTypes:
  - AzureDiagnostics
  - AZFWApplicationRule
  - AZFWNetworkRule
status: Available
severity: Medium
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: SourceIp
  entityType: IP
- fieldMappings:
  - identifier: Url
    columnName: Fqdn
  entityType: URL
queryPeriod: 1d
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
triggerOperator: gt
version: 1.2.3
id: 720335f4-ee8c-4270-9424-d0859222168c
{
  "$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": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "Source IP {{SourceIp}} has scanned {{AlertTimedCountHostsInBinTime}} different hosts on port {{DestinationPort}} within a short time frame, which may indicate reconnaissance activity.",
          "alertDisplayNameFormat": "Port Sweep Detected from {{SourceIp}} on Port {{DestinationPort}}"
        },
        "alertRuleTemplateName": "720335f4-ee8c-4270-9424-d0859222168c",
        "customDetails": {
          "DestinationPort": "DestinationPort"
        },
        "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%20Firewall/Analytic%20Rules/Azure%20Firewall%20-%20Port%20Sweep.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": [
          "T1595.001"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Discovery",
          "Reconnaissance"
        ],
        "techniques": [
          "T1046",
          "T1595"
        ],
        "templateVersion": "1.2.3",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}