Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Abnormal Port to Protocol

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
TechniquesT1041
T1571
Required data connectorsAzureFirewall
KindScheduled
Query frequency1h
Query period8d
Trigger threshold1
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure Firewall/Analytic Rules/Azure Firewall - Abnormal Port to Protocol.yaml
Version1.1.2
Arm template826f930c-2f25-4508-8e75-a95b809a4e15.json
Deploy To Azure
let LearningPeriod = 7d;
let RunTime = 1d;
let StartLearningPeriod = LearningPeriod + RunTime;
let EndRunTime = RunTime - 1d;
let LearningPortToProtocol1 =  (AzureDiagnostics
| where OperationName == "AzureFirewallApplicationRuleLog"
| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
| 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 (ago(RunTime) .. ago(EndRunTime))
| 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 (ago(RunTime) .. ago(EndRunTime))
| where isnotempty(DestinationPort)
| extend Fqdn = DestinationIp
| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
let AlertTimePortToProtocol3 = (AZFWApplicationRule
| where TimeGenerated between (ago(RunTime) .. ago(EndRunTime))
| 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=leftouter (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
| where LearningTimeProtocol != AlertTimeProtocol),
(AlertTimePortToProtocol3 
| join kind=leftouter (LearningPortToProtocol3) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
| where LearningTimeProtocol != AlertTimeProtocol))
entityMappings:
- entityType: IP
  fieldMappings:
  - columnName: SourceIp
    identifier: Address
- entityType: URL
  fieldMappings:
  - columnName: Fqdn
    identifier: Url
tactics:
- Exfiltration
- CommandAndControl
triggerOperator: gt
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.'  
requiredDataConnectors:
- connectorId: AzureFirewall
  dataTypes:
  - AzureDiagnostics
  - AZFWApplicationRule
  - AZFWNetworkRule
relevantTechniques:
- T1041
- T1571
version: 1.1.2
id: 826f930c-2f25-4508-8e75-a95b809a4e15
kind: Scheduled
query: |
  let LearningPeriod = 7d;
  let RunTime = 1d;
  let StartLearningPeriod = LearningPeriod + RunTime;
  let EndRunTime = RunTime - 1d;
  let LearningPortToProtocol1 =  (AzureDiagnostics
  | where OperationName == "AzureFirewallApplicationRuleLog"
  | where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))
  | 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 (ago(RunTime) .. ago(EndRunTime))
  | 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 (ago(RunTime) .. ago(EndRunTime))
  | where isnotempty(DestinationPort)
  | extend Fqdn = DestinationIp
  | summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);
  let AlertTimePortToProtocol3 = (AZFWApplicationRule
  | where TimeGenerated between (ago(RunTime) .. ago(EndRunTime))
  | 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=leftouter (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
  | where LearningTimeProtocol != AlertTimeProtocol),
  (AlertTimePortToProtocol3 
  | join kind=leftouter (LearningPortToProtocol3) on $left.AlertTimeDstPort == $right.LearningTimeDstPort
  | where LearningTimeProtocol != AlertTimeProtocol))  
status: Available
triggerThreshold: 1
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Azure Firewall/Analytic Rules/Azure Firewall - Abnormal Port to Protocol.yaml
queryFrequency: 1h
severity: Medium
name: Abnormal Port to Protocol
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": {
        "alertRuleTemplateName": "826f930c-2f25-4508-8e75-a95b809a4e15",
        "customDetails": null,
        "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 Firewall/Analytic Rules/Azure Firewall - Abnormal Port to Protocol.yaml",
        "query": "let LearningPeriod = 7d;\nlet RunTime = 1d;\nlet StartLearningPeriod = LearningPeriod + RunTime;\nlet EndRunTime = RunTime - 1d;\nlet LearningPortToProtocol1 =  (AzureDiagnostics\n| where OperationName == \"AzureFirewallApplicationRuleLog\"\n| where TimeGenerated between (ago(StartLearningPeriod) .. ago(RunTime))\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 (ago(RunTime) .. ago(EndRunTime))\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 (ago(RunTime) .. ago(EndRunTime))\n| where isnotempty(DestinationPort)\n| extend Fqdn = DestinationIp\n| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = Protocol);\nlet AlertTimePortToProtocol3 = (AZFWApplicationRule\n| where TimeGenerated between (ago(RunTime) .. ago(EndRunTime))\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=leftouter (LearningPortToProtocol2) on $left.AlertTimeDstPort == $right.LearningTimeDstPort\n| where LearningTimeProtocol != AlertTimeProtocol),\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",
          "Exfiltration"
        ],
        "techniques": [
          "T1041",
          "T1571"
        ],
        "templateVersion": "1.1.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 1
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}