Detection rules › Kusto

Palo Alto - potential beaconing detected

Status
available
Severity
low
Time window
1h
Group by
DestinationIP, DestinationPort, DeviceName, SourceIP, SourceUserID, TimeDeltainSeconds
Source
github.com/Azure/Azure-Sentinel

'Identifies beaconing patterns from Palo Alto Network traffic logs based on recurrent timedelta patterns. The query leverages various KQL functions to calculate time deltas and then compares it with total events observed in a day to find percentage of beaconing. This outbound beaconing pattern to untrusted public networks should be investigated for any malware callbacks or data exfiltration attempts. Reference Blog: https://medium.com/@HuntOperator/detect-beaconing-with-flare-elastic-stack-and-intrusion-detection-systems-110dc74e0c56 https://techcommunity.microsoft.com/t5/microsoft-sentinel-blog/detect-network-beaconing-via-intra-request-time-delta-patterns/ba-p/779586'

MITRE ATT&CK coverage

Rule body kusto

id: f0be259a-34ac-4946-aa15-ca2b115d5feb
name: Palo Alto - potential beaconing detected
description: |
  'Identifies beaconing patterns from Palo Alto Network traffic logs based on recurrent timedelta patterns.
  The query leverages various KQL functions to calculate time deltas and then compares it with total events observed in a day to find percentage of beaconing.
  This outbound beaconing pattern to untrusted public networks should be investigated for any malware callbacks or data exfiltration attempts.
  Reference Blog:
  https://medium.com/@HuntOperator/detect-beaconing-with-flare-elastic-stack-and-intrusion-detection-systems-110dc74e0c56
  https://techcommunity.microsoft.com/t5/microsoft-sentinel-blog/detect-network-beaconing-via-intra-request-time-delta-patterns/ba-p/779586'
severity: Low
status: Available
requiredDataConnectors:
  - connectorId: CefAma
    dataTypes:
      - CommonSecurityLog
queryFrequency: 1d
queryPeriod: 2d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CommandAndControl
relevantTechniques:
  - T1071
  - T1571
query: |
  let starttime = 2d;
  let endtime = 1d;
  let TimeDeltaThreshold = 25;
  let TotalEventsThreshold = 30;
  let MostFrequentTimeDeltaThreshold = 25;
  let PercentBeaconThreshold = 80;
  CommonSecurityLog
  | where DeviceVendor == "Palo Alto Networks" and Activity == "TRAFFIC"
  | where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime)))
  | where ipv4_is_private(DestinationIP)== false
  | project TimeGenerated, DeviceName, SourceUserID, SourceIP, SourcePort, DestinationIP, DestinationPort, ReceivedBytes, SentBytes
  | sort by SourceIP asc,TimeGenerated asc, DestinationIP asc, DestinationPort asc
  | serialize
  | extend nextTimeGenerated = next(TimeGenerated, 1), nextSourceIP = next(SourceIP, 1)
  | extend TimeDeltainSeconds = datetime_diff('second',nextTimeGenerated,TimeGenerated)
  | where SourceIP == nextSourceIP
  //Whitelisting criteria/ threshold criteria
  | where TimeDeltainSeconds > TimeDeltaThreshold
  | summarize count(), sum(ReceivedBytes), sum(SentBytes)
  by TimeDeltainSeconds, bin(TimeGenerated, 1h), DeviceName, SourceUserID, SourceIP, DestinationIP, DestinationPort
  | summarize (MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds) = arg_max(count_, TimeDeltainSeconds), TotalEvents=sum(count_), TotalSentBytes = sum(sum_SentBytes), TotalReceivedBytes = sum(sum_ReceivedBytes)
  by bin(TimeGenerated, 1h), DeviceName, SourceUserID, SourceIP, DestinationIP, DestinationPort
  | where TotalEvents > TotalEventsThreshold and MostFrequentTimeDeltaCount > MostFrequentTimeDeltaThreshold
  | extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100
  | where BeaconPercent > PercentBeaconThreshold
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: SourceUserID
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: DeviceName
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: DestinationIP
version: 1.0.7
kind: Scheduled

Stages and Predicates

Parameters

let starttime = 2d;
let endtime = 1d;
let TimeDeltaThreshold = 25;
let TotalEventsThreshold = 30;
let MostFrequentTimeDeltaThreshold = 25;
let PercentBeaconThreshold = 80;

Stage 1: source

CommonSecurityLog

Stage 2: where

| where DeviceVendor == "Palo Alto Networks" and Activity == "TRAFFIC"

Stage 3: where

| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime)))

Stage 4: where

| where ipv4_is_private(DestinationIP)== false

Stage 5: project

| project TimeGenerated, DeviceName, SourceUserID, SourceIP, SourcePort, DestinationIP, DestinationPort, ReceivedBytes, SentBytes

Stage 6: sort

| sort by SourceIP asc,TimeGenerated asc, DestinationIP asc, DestinationPort asc

Stage 7: kusto:serialize

| serialize

Stage 8: extend

| extend nextTimeGenerated = next(TimeGenerated, 1), nextSourceIP = next(SourceIP, 1)

Stage 9: extend

| extend TimeDeltainSeconds = datetime_diff('second',nextTimeGenerated,TimeGenerated)

Stage 10: where

| where SourceIP == nextSourceIP

Stage 11: where

| where TimeDeltainSeconds > TimeDeltaThreshold

Stage 12: summarize

| summarize count(), sum(ReceivedBytes), sum(SentBytes)
by TimeDeltainSeconds, bin(TimeGenerated, 1h), DeviceName, SourceUserID, SourceIP, DestinationIP, DestinationPort

Stage 13: summarize

| summarize (MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds) = arg_max(count_, TimeDeltainSeconds), TotalEvents=sum(count_), TotalSentBytes = sum(sum_SentBytes), TotalReceivedBytes = sum(sum_ReceivedBytes)
by bin(TimeGenerated, 1h), DeviceName, SourceUserID, SourceIP, DestinationIP, DestinationPort
Threshold
gt 30

Stage 14: where

| where TotalEvents > TotalEventsThreshold and MostFrequentTimeDeltaCount > MostFrequentTimeDeltaThreshold

Stage 15: extend

| extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100

Stage 16: where

| where BeaconPercent > PercentBeaconThreshold

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
DestinationIPcidr_match10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 127.0.0.0/8

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
Activityeq
  • TRAFFIC transforms: cased
BeaconPercentgt
  • 80 transforms: cased
DeviceVendoreq
  • Palo Alto Networks transforms: cased
MostFrequentTimeDeltaCountgt
  • 25 transforms: cased
SourceIPeq
  • nextSourceIP transforms: cased
TimeDeltainSecondsgt
  • 25 transforms: cased
TotalEventsgt
  • 30 transforms: cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
DestinationIPsummarize
DestinationPortsummarize
DeviceNamesummarize
MostFrequentTimeDeltaCountsummarize
SourceIPsummarize
SourceUserIDsummarize
TotalEventssummarize
TotalReceivedBytessummarize
TotalSentBytessummarize
BeaconPercentextend