Detection rules › Kusto
Tailscale Premium: Subnet router throughput anomaly
Identifies when a subnet router (gateway node bridging the tailnet to an on-prem or cloud subnet) handles 3x or more its 7-day baseline traffic in the last hour. Spikes can indicate exfiltration or scanning. Requires Tailscale Premium or Enterprise.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Command & Control | |
| Exfiltration |
Rule body
id: a5b6c7d8-5e6f-7a8b-9c0d-1e2f3a4b5c6d
name: "Tailscale Premium: Subnet router throughput anomaly"
description: |
Identifies when a subnet router (gateway node bridging the tailnet to an on-prem or cloud subnet) handles 3x or more its 7-day baseline traffic in the last hour. Spikes can indicate exfiltration or scanning. Requires Tailscale Premium or Enterprise.
severity: Low
status: Available
requiredDataConnectors:
- connectorId: TailscalePremiumCCF
dataTypes:
- Tailscale_Network_CL
queryFrequency: 1h
queryPeriod: 8d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Exfiltration
- CommandAndControl
relevantTechniques:
- T1572
- T1041
query: |
let baselineDays = 7d;
let recent = 1h;
let multiplier = 3.0;
let recentTraffic =
Tailscale_Network_CL
| where TimeGenerated > ago(recent)
| where HasSubnetTraffic
| mv-expand t = SubnetTraffic
| extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
| summarize RecentBytes = sum(Bytes) by NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags=tostring(SrcTags);
let baseline =
Tailscale_Network_CL
| where TimeGenerated between (ago(baselineDays + recent) .. ago(recent))
| where HasSubnetTraffic
| mv-expand t = SubnetTraffic
| extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
| summarize TotalBaselineBytes = sum(Bytes) by NodeId
| extend BaselineHourlyBytes = TotalBaselineBytes / 168.0;
recentTraffic
| join kind=inner baseline on NodeId
| where RecentBytes > BaselineHourlyBytes * multiplier
| extend Multiplier = round(RecentBytes / BaselineHourlyBytes, 1), RecentMB = round(RecentBytes / 1024.0 / 1024.0, 2), BaselineHourlyMB = round(BaselineHourlyBytes / 1024.0 / 1024.0, 2)
| project NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags, RecentMB, BaselineHourlyMB, Multiplier
| order by Multiplier desc
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: SrcNodeName
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: SrcUser
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: P1D
matchingMethod: AllEntities
kind: Scheduled
version: 1.0.0
Stages and Predicates
Stage 0: let
let baselineDays = 7d;
let recent = 1h;
let multiplier = 3.0;
let recentTraffic = Tailscale_Network_CL <inlined as stages below>;
let baseline =
Tailscale_Network_CL
| where TimeGenerated between (ago(baselineDays + recent) .. ago(recent))
| where HasSubnetTraffic
| mv-expand t = SubnetTraffic
| extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
| summarize TotalBaselineBytes = sum(Bytes) by NodeId
| extend BaselineHourlyBytes = TotalBaselineBytes / 168.0;
Stage 1: source
Tailscale_Network_CL
Stage 2: where
| where TimeGenerated > ago(recent)
Stage 3: where
| where HasSubnetTraffic
Stage 4: mv-expand
| mv-expand t = SubnetTraffic
Stage 5: extend
| extend Bytes = tolong(t.txBytes) + tolong(t.rxBytes)
Stage 6: summarize
| summarize RecentBytes = sum(Bytes) by NodeId, SrcNodeName, SrcUser, SrcOs, SrcTags=tostring(SrcTags)
Stage 7: join
| join kind=inner baseline on NodeId
Stage 8: where
where RecentBytes > (BaselineHourlyBytes * 3.0)
Stage 9: extend
extend BaselineHourlyMB, Multiplier, RecentMB
Stage 10: project
project BaselineHourlyMB, Multiplier, NodeId, RecentMB, SrcNodeName, SrcOs, SrcTags, SrcUser
Stage 11: sort
sort by Multiplier
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
RecentBytes | cross_field_compare |
| field:"RecentBytes" kind:cross_field_compare value:"BaselineHourlyBytes" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
BaselineHourlyMB | project |
Multiplier | project |
NodeId | project |
RecentMB | project |
SrcNodeName | project |
SrcOs | project |
SrcTags | project |
SrcUser | project |