Analytic rule catalog
Canary alerts to incidents
Back
| Id | 06360572-94a7-42a4-add7-58fb933b2353 |
| Rulename | Canary alerts to incidents |
| Description | Creates Microsoft Sentinel incidents from Thinkst Canary alerts. |
| Severity | High |
| Tactics | LateralMovement Exfiltration |
| Techniques | T1021 T1041 |
| Required data connectors | ThinkstCanary |
| Kind | NRT |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/ThinkstCanary/Analytic%20Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml |
| Version | 1.0.2 |
| Arm template | 06360572-94a7-42a4-add7-58fb933b2353.json |
ThinkstCanaryIncidents_CL
| where Description != "Canary Disconnected"
| where Description != "Canary Reconnected"
| where Description != "Canary Settings Changed"
| where Description != "Fake Location"
| where Description != "Network Settings Roll-back"
| extend EventData = todynamic(RawEvent[0])
| extend IsCanarytoken = Description contains "Canarytoken"
or LogType startswith "16"
or LogType startswith "17"
or isnotempty(tostring(EventData.canarytoken))
| extend PhysicalCanaryName = coalesce(tostring(Host.name), NodeId),
PhysicalCanaryIP = coalesce(tostring(Host.ip_address), DestinationIP, IpAddress),
TokenMemo = iff(IsCanarytoken, substring(Memo, 0, 256), ""),
TokenType = coalesce(tostring(EventData.kind), tostring(EventData.type)),
TokenHostname = tostring(EventData.hostname),
TokenTarget = substring(coalesce(tostring(EventData.url), tostring(EventData.hostname), tostring(EventData.cloned_site), tostring(EventData.original_site), tostring(EventData.generic_data), tostring(EventData.location)), 0, 512),
TokenUsername = coalesce(tostring(EventData.windows_desktopini_access_username), tostring(EventData.ms_macro_username), tostring(EventData.cmd_user_name)),
TokenDomain = coalesce(tostring(EventData.windows_desktopini_access_domain), tostring(EventData.cmd_machine_name)),
TokenHost = coalesce(tostring(EventData.windows_desktopini_computer_name), tostring(EventData.cmd_computer_name), tostring(EventData.cmd_workstation), tostring(EventData.cmd_machine_name)),
TokenSourceIP = coalesce(tostring(EventData.cmd_resolved_ip), tostring(EventData.ms_macro_ip)),
TokenCity = coalesce(tostring(EventData.geoip.city), tostring(EventData.geoip.City), tostring(EventData.City)),
TokenCountry = coalesce(tostring(EventData.geoip.country), tostring(EventData.geoip.country_name), tostring(EventData.geoip.Country), tostring(EventData.Country)),
TokenContext = case(
isnotempty(tostring(EventData.client_public_key)), strcat("WireGuard public key: ", substring(tostring(EventData.client_public_key), 0, 128), "; session: ", tostring(EventData.client_session_index)),
isnotempty(tostring(EventData.masked_card_number)), strcat("Masked card: ", tostring(EventData.masked_card_number), "; transaction: ", tostring(EventData.transaction_amount), " ", tostring(EventData.transaction_currency), "; merchant: ", tostring(EventData.merchant)),
isnotempty(tostring(EventData.referer)), strcat("Referrer: ", substring(tostring(EventData.referer), 0, 256)),
""),
UserAgent = substring(coalesce(tostring(EventData.USERAGENT), tostring(EventData.HEADERS['user-agent']), tostring(EventData.headers['User-Agent']), tostring(EventData.headers['user-agent'])), 0, 512)
| extend ActorUsername = coalesce(tostring(EventData.USERNAME), tostring(EventData.USER), tostring(EventData.FORMDATA.username), tostring(EventData.POSTDATA.username), TokenUsername),
ActorDomain = coalesce(tostring(EventData.DOMAIN), tostring(EventData.DOMAINNAME), TokenDomain),
ActorHost = coalesce(TokenHost, tostring(EventData.HOSTNAME)),
Activity = coalesce(TokenContext, TokenType, tostring(EventData.INSTANCE_NAME), tostring(EventData.FUNC_NAME), tostring(EventData.METHOD), tostring(EventData.OPCODE), tostring(EventData.COMMAND), tostring(EventData.FUNCTION), Description)
| extend SourceIP = coalesce(SourceIP, tostring(EventData.src_host), TokenSourceIP),
SourceGeo = case(isnotempty(TokenCity) and isnotempty(TokenCountry), strcat(TokenCity, ", ", TokenCountry), isnotempty(TokenCity), TokenCity, TokenCountry),
AssetType = iff(IsCanarytoken, "Canarytoken", "Canary"),
AssetName = iff(IsCanarytoken, coalesce(TokenMemo, TokenTarget, TokenType, NodeId), PhysicalCanaryName),
AssetNode = NodeId,
AssetIP = iff(IsCanarytoken, "", PhysicalCanaryIP),
AssetLocation = iff(IsCanarytoken, "", tostring(Host.description)),
CanaryEntityName = iff(IsCanarytoken, "", PhysicalCanaryName),
CanaryEntityIP = iff(IsCanarytoken, "", PhysicalCanaryIP)
| extend SourceDisplay = coalesce(SourceIP, SrcHostReverse, "unknown source")
| project TimeGenerated, Description, IncidentId, AssetType, AssetName, AssetNode,
AssetIP, AssetLocation, FlockName, TokenMemo, TokenType, TokenTarget,
TokenHostname, ActorUsername, ActorDomain, ActorHost, SourceGeo, SourceIP,
SourceDisplay, SrcHostReverse, DestinationPort, Activity, UserAgent, LogType,
EventsCount, CanaryEntityName, CanaryEntityIP
suppressionDuration: 1h
name: Canary alerts to incidents
suppressionEnabled: false
query: |
ThinkstCanaryIncidents_CL
| where Description != "Canary Disconnected"
| where Description != "Canary Reconnected"
| where Description != "Canary Settings Changed"
| where Description != "Fake Location"
| where Description != "Network Settings Roll-back"
| extend EventData = todynamic(RawEvent[0])
| extend IsCanarytoken = Description contains "Canarytoken"
or LogType startswith "16"
or LogType startswith "17"
or isnotempty(tostring(EventData.canarytoken))
| extend PhysicalCanaryName = coalesce(tostring(Host.name), NodeId),
PhysicalCanaryIP = coalesce(tostring(Host.ip_address), DestinationIP, IpAddress),
TokenMemo = iff(IsCanarytoken, substring(Memo, 0, 256), ""),
TokenType = coalesce(tostring(EventData.kind), tostring(EventData.type)),
TokenHostname = tostring(EventData.hostname),
TokenTarget = substring(coalesce(tostring(EventData.url), tostring(EventData.hostname), tostring(EventData.cloned_site), tostring(EventData.original_site), tostring(EventData.generic_data), tostring(EventData.location)), 0, 512),
TokenUsername = coalesce(tostring(EventData.windows_desktopini_access_username), tostring(EventData.ms_macro_username), tostring(EventData.cmd_user_name)),
TokenDomain = coalesce(tostring(EventData.windows_desktopini_access_domain), tostring(EventData.cmd_machine_name)),
TokenHost = coalesce(tostring(EventData.windows_desktopini_computer_name), tostring(EventData.cmd_computer_name), tostring(EventData.cmd_workstation), tostring(EventData.cmd_machine_name)),
TokenSourceIP = coalesce(tostring(EventData.cmd_resolved_ip), tostring(EventData.ms_macro_ip)),
TokenCity = coalesce(tostring(EventData.geoip.city), tostring(EventData.geoip.City), tostring(EventData.City)),
TokenCountry = coalesce(tostring(EventData.geoip.country), tostring(EventData.geoip.country_name), tostring(EventData.geoip.Country), tostring(EventData.Country)),
TokenContext = case(
isnotempty(tostring(EventData.client_public_key)), strcat("WireGuard public key: ", substring(tostring(EventData.client_public_key), 0, 128), "; session: ", tostring(EventData.client_session_index)),
isnotempty(tostring(EventData.masked_card_number)), strcat("Masked card: ", tostring(EventData.masked_card_number), "; transaction: ", tostring(EventData.transaction_amount), " ", tostring(EventData.transaction_currency), "; merchant: ", tostring(EventData.merchant)),
isnotempty(tostring(EventData.referer)), strcat("Referrer: ", substring(tostring(EventData.referer), 0, 256)),
""),
UserAgent = substring(coalesce(tostring(EventData.USERAGENT), tostring(EventData.HEADERS['user-agent']), tostring(EventData.headers['User-Agent']), tostring(EventData.headers['user-agent'])), 0, 512)
| extend ActorUsername = coalesce(tostring(EventData.USERNAME), tostring(EventData.USER), tostring(EventData.FORMDATA.username), tostring(EventData.POSTDATA.username), TokenUsername),
ActorDomain = coalesce(tostring(EventData.DOMAIN), tostring(EventData.DOMAINNAME), TokenDomain),
ActorHost = coalesce(TokenHost, tostring(EventData.HOSTNAME)),
Activity = coalesce(TokenContext, TokenType, tostring(EventData.INSTANCE_NAME), tostring(EventData.FUNC_NAME), tostring(EventData.METHOD), tostring(EventData.OPCODE), tostring(EventData.COMMAND), tostring(EventData.FUNCTION), Description)
| extend SourceIP = coalesce(SourceIP, tostring(EventData.src_host), TokenSourceIP),
SourceGeo = case(isnotempty(TokenCity) and isnotempty(TokenCountry), strcat(TokenCity, ", ", TokenCountry), isnotempty(TokenCity), TokenCity, TokenCountry),
AssetType = iff(IsCanarytoken, "Canarytoken", "Canary"),
AssetName = iff(IsCanarytoken, coalesce(TokenMemo, TokenTarget, TokenType, NodeId), PhysicalCanaryName),
AssetNode = NodeId,
AssetIP = iff(IsCanarytoken, "", PhysicalCanaryIP),
AssetLocation = iff(IsCanarytoken, "", tostring(Host.description)),
CanaryEntityName = iff(IsCanarytoken, "", PhysicalCanaryName),
CanaryEntityIP = iff(IsCanarytoken, "", PhysicalCanaryIP)
| extend SourceDisplay = coalesce(SourceIP, SrcHostReverse, "unknown source")
| project TimeGenerated, Description, IncidentId, AssetType, AssetName, AssetNode,
AssetIP, AssetLocation, FlockName, TokenMemo, TokenType, TokenTarget,
TokenHostname, ActorUsername, ActorDomain, ActorHost, SourceGeo, SourceIP,
SourceDisplay, SrcHostReverse, DestinationPort, Activity, UserAgent, LogType,
EventsCount, CanaryEntityName, CanaryEntityIP
description: Creates Microsoft Sentinel incidents from Thinkst Canary alerts.
id: 06360572-94a7-42a4-add7-58fb933b2353
kind: NRT
version: 1.0.2
status: Available
customDetails:
TokenType: TokenType
LogType: LogType
ActorUsername: ActorUsername
AssetIP: AssetIP
TokenTarget: TokenTarget
DestinationPort: DestinationPort
SourceGeo: SourceGeo
AssetLocation: AssetLocation
AssetNode: AssetNode
AssetType: AssetType
Activity: Activity
IncidentKey: IncidentId
EventsCount: EventsCount
ActorDomain: ActorDomain
ActorHost: ActorHost
AssetName: AssetName
UserAgent: UserAgent
TokenMemo: TokenMemo
FlockName: FlockName
SourceIP: SourceIP
relevantTechniques:
- T1021
- T1041
eventGroupingSettings:
aggregationKind: AlertPerResult
severity: High
requiredDataConnectors:
- connectorId: ThinkstCanary
dataTypes:
- ThinkstCanaryIncidents_CL
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/ThinkstCanary/Analytic%20Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml
incidentConfiguration:
groupingConfiguration:
lookbackDuration: PT5H
reopenClosedIncident: false
matchingMethod: AllEntities
enabled: false
createIncident: true
alertDetailsOverride:
alertDescriptionFormat: Thinkst {{AssetType}} {{AssetName}} recorded this activity from {{SourceDisplay}}. Review the mapped entities and custom details for asset, actor, and activity context.
alertDisplayNameFormat: '{{Description}} - {{AssetName}} from {{SourceDisplay}}'
tactics:
- LateralMovement
- Exfiltration
entityMappings:
- fieldMappings:
- identifier: Address
columnName: SourceIP
entityType: IP
- fieldMappings:
- identifier: Address
columnName: CanaryEntityIP
entityType: IP
- fieldMappings:
- identifier: HostName
columnName: CanaryEntityName
entityType: Host
- fieldMappings:
- identifier: Name
columnName: ActorUsername
entityType: Account
- fieldMappings:
- identifier: DomainName
columnName: TokenHostname
entityType: DNS
{
"$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/06360572-94a7-42a4-add7-58fb933b2353')]",
"kind": "NRT",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/06360572-94a7-42a4-add7-58fb933b2353')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "Thinkst {{AssetType}} {{AssetName}} recorded this activity from {{SourceDisplay}}. Review the mapped entities and custom details for asset, actor, and activity context.",
"alertDisplayNameFormat": "{{Description}} - {{AssetName}} from {{SourceDisplay}}"
},
"alertRuleTemplateName": "06360572-94a7-42a4-add7-58fb933b2353",
"customDetails": {
"Activity": "Activity",
"ActorDomain": "ActorDomain",
"ActorHost": "ActorHost",
"ActorUsername": "ActorUsername",
"AssetIP": "AssetIP",
"AssetLocation": "AssetLocation",
"AssetName": "AssetName",
"AssetNode": "AssetNode",
"AssetType": "AssetType",
"DestinationPort": "DestinationPort",
"EventsCount": "EventsCount",
"FlockName": "FlockName",
"IncidentKey": "IncidentId",
"LogType": "LogType",
"SourceGeo": "SourceGeo",
"SourceIP": "SourceIP",
"TokenMemo": "TokenMemo",
"TokenTarget": "TokenTarget",
"TokenType": "TokenType",
"UserAgent": "UserAgent"
},
"description": "Creates Microsoft Sentinel incidents from Thinkst Canary alerts.",
"displayName": "Canary alerts to incidents",
"enabled": true,
"entityMappings": [
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "SourceIP",
"identifier": "Address"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "CanaryEntityIP",
"identifier": "Address"
}
]
},
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "CanaryEntityName",
"identifier": "HostName"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "ActorUsername",
"identifier": "Name"
}
]
},
{
"entityType": "DNS",
"fieldMappings": [
{
"columnName": "TokenHostname",
"identifier": "DomainName"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"enabled": false,
"lookbackDuration": "PT5H",
"matchingMethod": "AllEntities",
"reopenClosedIncident": false
}
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/ThinkstCanary/Analytic%20Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml",
"query": "ThinkstCanaryIncidents_CL\n| where Description != \"Canary Disconnected\"\n| where Description != \"Canary Reconnected\"\n| where Description != \"Canary Settings Changed\"\n| where Description != \"Fake Location\"\n| where Description != \"Network Settings Roll-back\"\n| extend EventData = todynamic(RawEvent[0])\n| extend IsCanarytoken = Description contains \"Canarytoken\"\n or LogType startswith \"16\"\n or LogType startswith \"17\"\n or isnotempty(tostring(EventData.canarytoken))\n| extend PhysicalCanaryName = coalesce(tostring(Host.name), NodeId),\n PhysicalCanaryIP = coalesce(tostring(Host.ip_address), DestinationIP, IpAddress),\n TokenMemo = iff(IsCanarytoken, substring(Memo, 0, 256), \"\"),\n TokenType = coalesce(tostring(EventData.kind), tostring(EventData.type)),\n TokenHostname = tostring(EventData.hostname),\n TokenTarget = substring(coalesce(tostring(EventData.url), tostring(EventData.hostname), tostring(EventData.cloned_site), tostring(EventData.original_site), tostring(EventData.generic_data), tostring(EventData.location)), 0, 512),\n TokenUsername = coalesce(tostring(EventData.windows_desktopini_access_username), tostring(EventData.ms_macro_username), tostring(EventData.cmd_user_name)),\n TokenDomain = coalesce(tostring(EventData.windows_desktopini_access_domain), tostring(EventData.cmd_machine_name)),\n TokenHost = coalesce(tostring(EventData.windows_desktopini_computer_name), tostring(EventData.cmd_computer_name), tostring(EventData.cmd_workstation), tostring(EventData.cmd_machine_name)),\n TokenSourceIP = coalesce(tostring(EventData.cmd_resolved_ip), tostring(EventData.ms_macro_ip)),\n TokenCity = coalesce(tostring(EventData.geoip.city), tostring(EventData.geoip.City), tostring(EventData.City)),\n TokenCountry = coalesce(tostring(EventData.geoip.country), tostring(EventData.geoip.country_name), tostring(EventData.geoip.Country), tostring(EventData.Country)),\n TokenContext = case(\n isnotempty(tostring(EventData.client_public_key)), strcat(\"WireGuard public key: \", substring(tostring(EventData.client_public_key), 0, 128), \"; session: \", tostring(EventData.client_session_index)),\n isnotempty(tostring(EventData.masked_card_number)), strcat(\"Masked card: \", tostring(EventData.masked_card_number), \"; transaction: \", tostring(EventData.transaction_amount), \" \", tostring(EventData.transaction_currency), \"; merchant: \", tostring(EventData.merchant)),\n isnotempty(tostring(EventData.referer)), strcat(\"Referrer: \", substring(tostring(EventData.referer), 0, 256)),\n \"\"),\n UserAgent = substring(coalesce(tostring(EventData.USERAGENT), tostring(EventData.HEADERS['user-agent']), tostring(EventData.headers['User-Agent']), tostring(EventData.headers['user-agent'])), 0, 512)\n| extend ActorUsername = coalesce(tostring(EventData.USERNAME), tostring(EventData.USER), tostring(EventData.FORMDATA.username), tostring(EventData.POSTDATA.username), TokenUsername),\n ActorDomain = coalesce(tostring(EventData.DOMAIN), tostring(EventData.DOMAINNAME), TokenDomain),\n ActorHost = coalesce(TokenHost, tostring(EventData.HOSTNAME)),\n Activity = coalesce(TokenContext, TokenType, tostring(EventData.INSTANCE_NAME), tostring(EventData.FUNC_NAME), tostring(EventData.METHOD), tostring(EventData.OPCODE), tostring(EventData.COMMAND), tostring(EventData.FUNCTION), Description)\n| extend SourceIP = coalesce(SourceIP, tostring(EventData.src_host), TokenSourceIP),\n SourceGeo = case(isnotempty(TokenCity) and isnotempty(TokenCountry), strcat(TokenCity, \", \", TokenCountry), isnotempty(TokenCity), TokenCity, TokenCountry),\n AssetType = iff(IsCanarytoken, \"Canarytoken\", \"Canary\"),\n AssetName = iff(IsCanarytoken, coalesce(TokenMemo, TokenTarget, TokenType, NodeId), PhysicalCanaryName),\n AssetNode = NodeId,\n AssetIP = iff(IsCanarytoken, \"\", PhysicalCanaryIP),\n AssetLocation = iff(IsCanarytoken, \"\", tostring(Host.description)),\n CanaryEntityName = iff(IsCanarytoken, \"\", PhysicalCanaryName),\n CanaryEntityIP = iff(IsCanarytoken, \"\", PhysicalCanaryIP)\n| extend SourceDisplay = coalesce(SourceIP, SrcHostReverse, \"unknown source\")\n| project TimeGenerated, Description, IncidentId, AssetType, AssetName, AssetNode,\n AssetIP, AssetLocation, FlockName, TokenMemo, TokenType, TokenTarget,\n TokenHostname, ActorUsername, ActorDomain, ActorHost, SourceGeo, SourceIP,\n SourceDisplay, SrcHostReverse, DestinationPort, Activity, UserAgent, LogType,\n EventsCount, CanaryEntityName, CanaryEntityIP\n",
"severity": "High",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Exfiltration",
"LateralMovement"
],
"techniques": [
"T1021",
"T1041"
],
"templateVersion": "1.0.2"
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}