Analytic rule catalog
Tailscale Device Tailscale SSH newly enabled
Back
| Id | f0a1b2c3-4567-8901-23de-f12345670041 |
| Rulename | Tailscale: Device Tailscale SSH newly enabled |
| Description | Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it. |
| Severity | Medium |
| Tactics | Persistence LateralMovement |
| Techniques | T1021 T1098 |
| Required data connectors | TailscaleCCF |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 2d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscaleDeviceSshNewlyEnabled.yaml |
| Version | 1.0.0 |
| Arm template | f0a1b2c3-4567-8901-23de-f12345670041.json |
let recent =
Tailscale_Devices_CL
| where TimeGenerated > ago(1h)
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;
let prior =
Tailscale_Devices_CL
| where TimeGenerated between (ago(2d) .. ago(1h))
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| distinct DeviceId;
recent
| join kind=leftanti prior on DeviceId
| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen
incidentConfiguration:
createIncident: true
groupingConfiguration:
lookbackDuration: P1D
reopenClosedIncident: false
enabled: true
matchingMethod: AllEntities
entityMappings:
- entityType: Host
fieldMappings:
- columnName: Hostname
identifier: HostName
- entityType: Account
fieldMappings:
- columnName: User
identifier: FullName
query: |
let recent =
Tailscale_Devices_CL
| where TimeGenerated > ago(1h)
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;
let prior =
Tailscale_Devices_CL
| where TimeGenerated between (ago(2d) .. ago(1h))
| summarize arg_max(TimeGenerated, *) by DeviceId
| where SshEnabled == true
| distinct DeviceId;
recent
| join kind=leftanti prior on DeviceId
| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen
id: f0a1b2c3-4567-8901-23de-f12345670041
queryFrequency: 1h
status: Available
version: 1.0.0
severity: Medium
relevantTechniques:
- T1021
- T1098
name: 'Tailscale: Device Tailscale SSH newly enabled'
kind: Scheduled
tactics:
- Persistence
- LateralMovement
requiredDataConnectors:
- dataTypes:
- Tailscale_Devices_CL
connectorId: TailscaleCCF
description: |
Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it.
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscaleDeviceSshNewlyEnabled.yaml
triggerOperator: gt
triggerThreshold: 0
queryPeriod: 2d
{
"$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/f0a1b2c3-4567-8901-23de-f12345670041')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/f0a1b2c3-4567-8901-23de-f12345670041')]",
"properties": {
"alertRuleTemplateName": "f0a1b2c3-4567-8901-23de-f12345670041",
"customDetails": null,
"description": "Identifies when Tailscale SSH is enabled on a device that previously did not have it. SSH provides authenticated shell access over the tailnet using Tailscale identity, broadening attack surface if unexpected. Verify and confirm the SSH ACL covers it.\n",
"displayName": "Tailscale: Device Tailscale SSH newly enabled",
"enabled": true,
"entityMappings": [
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "Hostname",
"identifier": "HostName"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "User",
"identifier": "FullName"
}
]
}
],
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"enabled": true,
"lookbackDuration": "P1D",
"matchingMethod": "AllEntities",
"reopenClosedIncident": false
}
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Tailscale%20%28CCF%29/Analytic%20Rules/TailscaleDeviceSshNewlyEnabled.yaml",
"query": "let recent =\n Tailscale_Devices_CL\n | where TimeGenerated > ago(1h)\n | summarize arg_max(TimeGenerated, *) by DeviceId\n | where SshEnabled == true\n | project DeviceId, DeviceName, Hostname, User, Os, ClientVersion, LastSeen;\nlet prior =\n Tailscale_Devices_CL\n | where TimeGenerated between (ago(2d) .. ago(1h))\n | summarize arg_max(TimeGenerated, *) by DeviceId\n | where SshEnabled == true\n | distinct DeviceId;\nrecent\n| join kind=leftanti prior on DeviceId\n| project TimeGenerated = now(), DeviceName, Hostname, User, Os, ClientVersion, LastSeen\n",
"queryFrequency": "PT1H",
"queryPeriod": "P2D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"LateralMovement",
"Persistence"
],
"techniques": [
"T1021",
"T1098"
],
"templateVersion": "1.0.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}