↳ GitHub sourceAnalytics ruleHigh

Whisper Security - BGP Route Anomaly with Traffic Spike

Description

Detects BGP origin AS changes for IP prefixes correlated with network traffic volume spikes. May indicate BGP hijacking or adversary-in-the-middle attacks.
Rule type
Scheduled
Version
1.0.0
Declared status
Available
Query frequency
15m
Query period
1d
Trigger
gt 0

Declared MITRE coverage

Declared sources

Metadata from the source file. No dependencies inferred from KQL.

Connectors

Data types

KQL query

Original query, unchanged.

// MITRE ATT&CK: T1557 - Adversary-in-the-Middle
// Tactic: Collection
// Detects BGP route origin changes correlated with traffic volume anomalies
let lookbackPeriod = 1d;
let bgpChanges = WhisperHistory_CL
    | where TimeGenerated > ago(lookbackPeriod)
    | where isnotempty(bgpOrigin)
    | serialize
    | extend PreviousOrigin = prev(bgpOrigin), PreviousIndicator = prev(indicator)
    | where indicator == PreviousIndicator
    | where bgpOrigin != PreviousOrigin
    | where isnotempty(PreviousOrigin)
    | project indicator, bgpPrefix, OldOrigin = PreviousOrigin, NewOrigin = bgpOrigin, ChangeTime = snapshotDate;
let CommonSecurityLogSafe = union isfuzzy=true CommonSecurityLog, (datatable(TimeGenerated:datetime, DestinationIP:string, SentBytes:long, ReceivedBytes:long)[]);
let trafficBaseline = CommonSecurityLogSafe
    | where TimeGenerated > ago(lookbackPeriod)
    | where isnotempty(DestinationIP)
    | summarize BaselineBytes = avg(SentBytes + ReceivedBytes), BaselineCount = count() by DestinationIP, bin(TimeGenerated, 1h)
    | summarize AvgBaselineBytes = avg(BaselineBytes), AvgBaselineCount = avg(BaselineCount) by DestinationIP;
let recentTraffic = CommonSecurityLogSafe
    | where TimeGenerated > ago(15m)
    | where isnotempty(DestinationIP)
    | summarize RecentBytes = sum(SentBytes + ReceivedBytes), RecentCount = count() by DestinationIP;
recentTraffic
    | join kind=inner (trafficBaseline) on DestinationIP
    | where RecentBytes > AvgBaselineBytes * 3 or RecentCount > AvgBaselineCount * 3
    | extend TrafficChange = iff(AvgBaselineBytes > 0, round((RecentBytes - AvgBaselineBytes) / AvgBaselineBytes * 100, 2), 0.0)
    | join kind=inner (bgpChanges) on $left.DestinationIP == $right.indicator
    | project TimeGenerated = ChangeTime, IPAddress = DestinationIP, Prefix = bgpPrefix, OriginASN = NewOrigin, OldOriginASN = OldOrigin, TrafficChange, RecentBytes, AvgBaselineBytes

Declared entities

IP

Related content

Links established from declared identifiers and solution manifests.

Source provenance

GitHub

Displayed values come from files in Azure/Azure-Sentinel. They describe the published template, not your workspace configuration.

Source identifier
1c08a7cb-7ff4-5a37-a961-39c29f8d07bd
Additional source files 2Solutions/Whisper/Analytic Rules/BgpRouteAnomalyTrafficSpike.yamlsource ↗Solutions/Whisper/Data/Solution_Whisper.jsonsolution-membership ↗
GSTEP / CATALOG TRACKING

Added to catalog : 16 Sept 2026 · 05:49 UTC
Last change observed : 16 Sept 2026 · 05:49 UTC

GSTEP sync dates, separate from the source content’s publication dates.