Back
Id826f930c-2f25-4508-8e75-a95b809a4e15
RulenameAbnormal Port to Protocol
DescriptionIdentifies communication for well known protocol over a non-standard port based on learning period activity. This can indicate malicious communication (C2) or exfiltration by attackers trying to communicate over known ports (22:SSH, 80:HTTP) but dont use the known protocol headers to match the port number.



Configurable Parameters:



- Learning period time - learning period for protocol learning in days. Default is set to 7.
SeverityMedium
TacticsExfiltration
CommandAndControl
DefenseEvasion
TechniquesT1041
T1571
T1572
Required data connectorsAzureFirewall
KindScheduled
Query frequency1h
Query period8d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Firewall/Analytic%20Rules/Azure%20Firewall%20-%20Abnormal%20Port%20to%20Protocol.yaml
Version1.1.5
Arm template826f930c-2f25-4508-8e75-a95b809a4e15.json
Deploy To Azure
let LearningPeriod = 7d;
let RunTime = 1h;
let StartLearningPeriod = LearningPeriod + RunTime;
let DetectionWindowStart = ago(RunTime);
let LearningPortToProtocol1 =  (AzureDiagnostics
| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
| where OperationName == "AzureFirewallApplicationRuleLog"
| extend msg_s= column_ifexists('msg_s',Message)
| parse msg_s with Protocol " request from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int "." *
| where isnotempty(DestinationPort)
| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
let LearningPortToProtocol2 = (AZFWNetworkRule
| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
| where isnotempty(DestinationPort)
| extend Fqdn = DestinationIp
| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
let LearningPortToProtocol3 = (AZFWApplicationRule
| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
| where isnotempty(DestinationPort)
| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
let AlertTimePortToProtocol1 = (AzureDiagnostics
| where TimeGenerated between (DetectionWindowStart .. now())
| where OperationName == "AzureFirewallApplicationRuleLog"
| extend msg_s= column_ifexists('msg_s',Message)
| parse msg_s with Protocol " request from " SourceIp ":" SourcePort " to " Fqdn ":" DestinationPort:int "." *
| where isnotempty(DestinationPort)
| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
let AlertTimePortToProtocol2 = (AZFWNetworkRule
| where TimeGenerated between (DetectionWindowStart .. now())
| where isnotempty(DestinationPort)
| extend Fqdn = DestinationIp
| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
let AlertTimePortToProtocol3 = (AZFWApplicationRule
| where TimeGenerated between (DetectionWindowStart .. now())
| where isnotempty(DestinationPort)
| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
(union isfuzzy=true 
(AlertTimePortToProtocol1 
| join kind=leftouter (LearningPortToProtocol1) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
| where LearningTimeProtocol != AlertTimeProtocol),
(AlertTimePortToProtocol2 
| join kind=leftanti (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort, $left.AlertTimeProtocol == $right.LearningTimeProtocol),
(AlertTimePortToProtocol3 
| join kind=leftouter (LearningPortToProtocol3) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
| where LearningTimeProtocol != AlertTimeProtocol))
queryFrequency: 1h
triggerOperator: gt
query: |
  let LearningPeriod = 7d;
  let RunTime = 1h;
  let StartLearningPeriod = LearningPeriod + RunTime;
  let DetectionWindowStart = ago(RunTime);
  let LearningPortToProtocol1 =  (AzureDiagnostics
  | where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
  | where OperationName == "AzureFirewallApplicationRuleLog"
  | extend msg_s= column_ifexists('msg_s',Message)
  | parse msg_s with Protocol " request from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int "." *
  | where isnotempty(DestinationPort)
  | summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
  let LearningPortToProtocol2 = (AZFWNetworkRule
  | where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
  | where isnotempty(DestinationPort)
  | extend Fqdn = DestinationIp
  | summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
  let LearningPortToProtocol3 = (AZFWApplicationRule
  | where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
  | where isnotempty(DestinationPort)
  | summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);
  let AlertTimePortToProtocol1 = (AzureDiagnostics
  | where TimeGenerated between (DetectionWindowStart .. now())
  | where OperationName == "AzureFirewallApplicationRuleLog"
  | extend msg_s= column_ifexists('msg_s',Message)
  | parse msg_s with Protocol " request from " SourceIp ":" SourcePort " to " Fqdn ":" DestinationPort:int "." *
  | where isnotempty(DestinationPort)
  | summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
  let AlertTimePortToProtocol2 = (AZFWNetworkRule
  | where TimeGenerated between (DetectionWindowStart .. now())
  | where isnotempty(DestinationPort)
  | extend Fqdn = DestinationIp
  | summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
  let AlertTimePortToProtocol3 = (AZFWApplicationRule
  | where TimeGenerated between (DetectionWindowStart .. now())
  | where isnotempty(DestinationPort)
  | summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
  (union isfuzzy=true 
  (AlertTimePortToProtocol1 
  | join kind=leftouter (LearningPortToProtocol1) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
  | where LearningTimeProtocol != AlertTimeProtocol),
  (AlertTimePortToProtocol2 
  | join kind=leftanti (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort, $left.AlertTimeProtocol == $right.LearningTimeProtocol),
  (AlertTimePortToProtocol3 
  | join kind=leftouter (LearningPortToProtocol3) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
  | where LearningTimeProtocol != AlertTimeProtocol))
version: 1.1.5
entityMappings:
- entityType: IP
  fieldMappings:
  - columnName: SourceIp
    identifier: Address
- entityType: URL
  fieldMappings:
  - columnName: Fqdn
    identifier: Url
description: |
  'Identifies communication for well known protocol over a non-standard port based on learning period activity. This can indicate malicious communication (C2) or exfiltration by attackers trying to communicate over known ports (22:SSH, 80:HTTP) but dont use the known protocol headers to match the port number.

  Configurable Parameters:

  - Learning period time - learning period for protocol learning in days. Default is set to 7.'
kind: Scheduled
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure%20Firewall/Analytic%20Rules/Azure%20Firewall%20-%20Abnormal%20Port%20to%20Protocol.yaml
triggerThreshold: 0
id: 826f930c-2f25-4508-8e75-a95b809a4e15
customDetails:
  AbnormalPort: AlertTimeDstPort
  NetworkProtocol: AlertTimeProtocol
alertDetailsOverride:
  alertDisplayNameFormat: Abnormal Port to Protocol Communication Detected from {{SourceIp}} to {{Fqdn}}
  alertDescriptionFormat: Communication was observed over port {{AlertTimeDstPort}} using protocol {{AlertTimeProtocol}}, which is different from the protocol observed during the learning period. This could indicate potential malicious activity such as C2 communication or data exfiltration.
severity: Medium
status: Available
relevantTechniques:
- T1041
- T1571
- T1572
requiredDataConnectors:
- connectorId: AzureFirewall
  dataTypes:
  - AzureDiagnostics
  - AZFWApplicationRule
  - AZFWNetworkRule
name: Abnormal Port to Protocol
tactics:
- Exfiltration
- CommandAndControl
- DefenseEvasion
queryPeriod: 8d
{
  "$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/826f930c-2f25-4508-8e75-a95b809a4e15')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/826f930c-2f25-4508-8e75-a95b809a4e15')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "Communication was observed over port {{AlertTimeDstPort}} using protocol {{AlertTimeProtocol}}, which is different from the protocol observed during the learning period. This could indicate potential malicious activity such as C2 communication or data exfiltration.",
          "alertDisplayNameFormat": "Abnormal Port to Protocol Communication Detected from {{SourceIp}} to {{Fqdn}}"
        },
        "alertRuleTemplateName": "826f930c-2f25-4508-8e75-a95b809a4e15",
        "customDetails": {
          "AbnormalPort": "AlertTimeDstPort",
          "NetworkProtocol": "AlertTimeProtocol"
        },
        "description": "'Identifies communication for well known protocol over a non-standard port based on learning period activity. This can indicate malicious communication (C2) or exfiltration by attackers trying to communicate over known ports (22:SSH, 80:HTTP) but dont use the known protocol headers to match the port number.\n\nConfigurable Parameters:\n\n- Learning period time - learning period for protocol learning in days. Default is set to 7.'\n",
        "displayName": "Abnormal Port to Protocol",
        "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-%20Abnormal%20Port%20to%20Protocol.yaml",
        "query": "let LearningPeriod = 7d;\nlet RunTime = 1h;\nlet StartLearningPeriod = LearningPeriod + RunTime;\nlet DetectionWindowStart = ago(RunTime);\nlet LearningPortToProtocol1 =  (AzureDiagnostics\n| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))\n| where OperationName == \"AzureFirewallApplicationRuleLog\"\n| extend msg_s= column_ifexists('msg_s',Message)\n| parse msg_s with Protocol \" request from \" SourceIp \":\" SourcePort:int \" to \" Fqdn \":\" DestinationPort:int \".\" *\n| where isnotempty(DestinationPort)\n| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);\nlet LearningPortToProtocol2 = (AZFWNetworkRule\n| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))\n| where isnotempty(DestinationPort)\n| extend Fqdn = DestinationIp\n| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);\nlet LearningPortToProtocol3 = (AZFWApplicationRule\n| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))\n| where isnotempty(DestinationPort)\n| summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = Protocol, SourceIp, Fqdn);\nlet AlertTimePortToProtocol1 = (AzureDiagnostics\n| where TimeGenerated between (DetectionWindowStart .. now())\n| where OperationName == \"AzureFirewallApplicationRuleLog\"\n| extend msg_s= column_ifexists('msg_s',Message)\n| parse msg_s with Protocol \" request from \" SourceIp \":\" SourcePort \" to \" Fqdn \":\" DestinationPort:int \".\" *\n| where isnotempty(DestinationPort)\n| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);\nlet AlertTimePortToProtocol2 = (AZFWNetworkRule\n| where TimeGenerated between (DetectionWindowStart .. now())\n| where isnotempty(DestinationPort)\n| extend Fqdn = DestinationIp\n| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);\nlet AlertTimePortToProtocol3 = (AZFWApplicationRule\n| where TimeGenerated between (DetectionWindowStart .. now())\n| where isnotempty(DestinationPort)\n| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);\n(union isfuzzy=true \n(AlertTimePortToProtocol1 \n| join kind=leftouter (LearningPortToProtocol1) on $left.AlertTimeDstPort == $right.LearningTimeDstPort\n| where LearningTimeProtocol != AlertTimeProtocol),\n(AlertTimePortToProtocol2 \n| join kind=leftanti (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort, $left.AlertTimeProtocol == $right.LearningTimeProtocol),\n(AlertTimePortToProtocol3 \n| join kind=leftouter (LearningPortToProtocol3) on $left.AlertTimeDstPort == $right.LearningTimeDstPort\n| where LearningTimeProtocol != AlertTimeProtocol))\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P8D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl",
          "DefenseEvasion",
          "Exfiltration"
        ],
        "techniques": [
          "T1041",
          "T1571",
          "T1572"
        ],
        "templateVersion": "1.1.5",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}