Detection rules › Kusto

GSA - Detect Protocol Changes for Destination Ports

Status
available
Severity
medium
Time window
8d
Group by
AlertTimeDstPort, AlertTimeProtocol, DestinationFqdn, SourceIp
Source
github.com/Azure/Azure-Sentinel

Identifies changes in the protocol used for specific destination ports, comparing the current runtime with a learned baseline. This can indicate potential protocol misuse or configuration changes. Configurable Parameters: - Learning period: The time range to establish the baseline. Default is set to 7 days. - Run time: The time range for current analysis. Default is set to 1 day.

MITRE ATT&CK coverage

TacticTechniques
Command & Control

Rule body

id: f6a8d6a5-3e9f-47c8-a8d5-1b2b9d3b7d6a
name: GSA - Detect Protocol Changes for Destination Ports
description: |
  Identifies changes in the protocol used for specific destination ports, comparing the current runtime with a learned baseline.
  This can indicate potential protocol misuse or configuration changes.
  Configurable Parameters:
  - Learning period: The time range to establish the baseline. Default is set to 7 days.
  - Run time: The time range for current analysis. Default is set to 1 day.
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - NetworkAccessTrafficLogs
queryFrequency: 1h
queryPeriod: 8d
triggerOperator: gt
triggerThreshold: 1
tactics:
  - DefenseEvasion
  - Exfiltration
  - CommandAndControl
relevantTechniques:
  - T1571
query: |
  let LearningPeriod = 7d;
  let RunTime = 1d;
  let StartLearningPeriod = ago(LearningPeriod + RunTime);
  let EndRunTime = ago(RunTime);
  let LearningPortToProtocol = 
    NetworkAccessTraffic
    | where TimeGenerated between (StartLearningPeriod .. EndRunTime)
    | where isnotempty(DestinationPort)
    | summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = TransportProtocol, SourceIp, DestinationFqdn;
  let AlertTimePortToProtocol = 
    NetworkAccessTraffic
    | where TimeGenerated between (EndRunTime .. now())
    | where isnotempty(DestinationPort)
    | summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = TransportProtocol, SourceIp, DestinationFqdn;
  AlertTimePortToProtocol
    | join kind=leftouter (LearningPortToProtocol) on $left.AlertTimeDstPort == $right.LearningTimeDstPort and $left.SourceIp == $right.SourceIp and $left.DestinationFqdn == $right.DestinationFqdn
    | where isnotempty(LearningTimeProtocol) and isnotempty(AlertTimeProtocol) and LearningTimeProtocol != AlertTimeProtocol
    | project AlertTimeDstPort, AlertTimeProtocol, LearningTimeProtocol, SourceIp, DestinationFqdn
    | extend IPCustomEntity = SourceIp, FqdnCustomEntity = DestinationFqdn
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: FqdnCustomEntity
version: 1.0.4
kind: Scheduled

Stages and Predicates

Stage 0: let

let LearningPeriod = 7d;
let RunTime = 1d;
let StartLearningPeriod = ago(LearningPeriod + RunTime);
let EndRunTime = ago(RunTime);
let LearningPortToProtocol = 
  NetworkAccessTraffic
  | where TimeGenerated between (StartLearningPeriod .. EndRunTime)
  | where isnotempty(DestinationPort)
  | summarize LearningTimeCount = count() by LearningTimeDstPort = DestinationPort, LearningTimeProtocol = TransportProtocol, SourceIp, DestinationFqdn;
let AlertTimePortToProtocol = NetworkAccessTraffic <inlined as stages below>;

Stage 1: source

NetworkAccessTraffic

Stage 2: where

| where TimeGenerated between (EndRunTime .. now())

Stage 3: where

| where isnotempty(DestinationPort)

Stage 4: summarize

| summarize AlertTimeCount = count() by AlertTimeDstPort = DestinationPort, AlertTimeProtocol = TransportProtocol, SourceIp, DestinationFqdn

Stage 5: join

| join kind=leftouter (LearningPortToProtocol) on $left.AlertTimeDstPort == $right.LearningTimeDstPort and $left.SourceIp == $right.SourceIp and $left.DestinationFqdn == $right.DestinationFqdn

Stage 6: where

where isnotempty(AlertTimeProtocol) and LearningTimeProtocol != AlertTimeProtocol and isnotempty(LearningTimeProtocol)

Stage 7: project

project AlertTimeDstPort, AlertTimeProtocol, DestinationFqdn, LearningTimeProtocol, SourceIp

Stage 8: extend

extend FqdnCustomEntity, IPCustomEntity

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
AlertTimeDstPortproject
AlertTimeProtocolproject
DestinationFqdnproject
LearningTimeProtocolproject
SourceIpproject
FqdnCustomEntityextend
IPCustomEntityextend