From 5952a5cd295c75f0c527464400c5b4c8160597e8 Mon Sep 17 00:00:00 2001 From: Jason Bissict Date: Fri, 21 Aug 2026 10:56:37 +0200 Subject: [PATCH 1/2] Add ThinkstCanary Solution This commit adds the basic solution for Thinkst Canary. --- .../ThinkstCanaryIncidents_CL.json | 121 ++ .../ValidConnectorIds.json | 3 +- Logos/ThinkstCanary.svg | 4 + ...tinelIncidentsFromThinkstCanaryAlerts.yaml | 120 ++ .../ThinkstCanary_ArmTemplate.json | 946 ++++++++++++++ .../ThinkstCanary_ConnectorDefinition.json | 134 ++ .../ThinkstCanary_DCR.json | 166 +++ .../ThinkstCanary_PollingConfig.json | 53 + .../ThinkstCanary_Table.json | 44 + .../Data/Solution_ThinkstCanary.json | 16 + Solutions/ThinkstCanary/Package/3.0.0.zip | Bin 0 -> 10258 bytes .../Package/createUiDefinition.json | 127 ++ .../ThinkstCanary/Package/mainTemplate.json | 1119 +++++++++++++++++ .../ThinkstCanary/Package/testParameters.json | 24 + Solutions/ThinkstCanary/ReleaseNotes.md | 3 + Solutions/ThinkstCanary/SolutionMetadata.json | 36 + 16 files changed, 2915 insertions(+), 1 deletion(-) create mode 100644 .script/tests/KqlvalidationsTests/CustomTables/ThinkstCanaryIncidents_CL.json create mode 100644 Logos/ThinkstCanary.svg create mode 100644 Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml create mode 100644 Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json create mode 100644 Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ConnectorDefinition.json create mode 100644 Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_DCR.json create mode 100644 Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_PollingConfig.json create mode 100644 Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_Table.json create mode 100644 Solutions/ThinkstCanary/Data/Solution_ThinkstCanary.json create mode 100644 Solutions/ThinkstCanary/Package/3.0.0.zip create mode 100644 Solutions/ThinkstCanary/Package/createUiDefinition.json create mode 100644 Solutions/ThinkstCanary/Package/mainTemplate.json create mode 100644 Solutions/ThinkstCanary/Package/testParameters.json create mode 100644 Solutions/ThinkstCanary/ReleaseNotes.md create mode 100644 Solutions/ThinkstCanary/SolutionMetadata.json diff --git a/.script/tests/KqlvalidationsTests/CustomTables/ThinkstCanaryIncidents_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/ThinkstCanaryIncidents_CL.json new file mode 100644 index 00000000000..9d43d5a36fd --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/ThinkstCanaryIncidents_CL.json @@ -0,0 +1,121 @@ +{ + "Name": "ThinkstCanaryIncidents_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "datetime" + }, + { + "Name": "IncidentId", + "Type": "string" + }, + { + "Name": "Description", + "Type": "string" + }, + { + "Name": "Acknowledged", + "Type": "string" + }, + { + "Name": "Created", + "Type": "real" + }, + { + "Name": "CreatedPrintable", + "Type": "string" + }, + { + "Name": "DestinationIP", + "Type": "string" + }, + { + "Name": "DestinationPort", + "Type": "string" + }, + { + "Name": "EventsCount", + "Type": "string" + }, + { + "Name": "Events", + "Type": "dynamic" + }, + { + "Name": "FlockId", + "Type": "string" + }, + { + "Name": "FlockName", + "Type": "string" + }, + { + "Name": "HashId", + "Type": "string" + }, + { + "Name": "Host", + "Type": "dynamic" + }, + { + "Name": "IpAddress", + "Type": "string" + }, + { + "Name": "IncidentUpdated", + "Type": "datetime" + }, + { + "Name": "LocalTime", + "Type": "string" + }, + { + "Name": "Memo", + "Type": "string" + }, + { + "Name": "RawEvent", + "Type": "dynamic" + }, + { + "Name": "LogType", + "Type": "string" + }, + { + "Name": "NodeId", + "Type": "string" + }, + { + "Name": "Notified", + "Type": "string" + }, + { + "Name": "PreviouslySeenCount", + "Type": "real" + }, + { + "Name": "Sensor", + "Type": "string" + }, + { + "Name": "SourceIP", + "Type": "string" + }, + { + "Name": "SrcHostReverse", + "Type": "string" + }, + { + "Name": "SourcePort", + "Type": "string" + }, + { + "Name": "UpdatedId", + "Type": "real" + }, + { + "Name": "UpdatedTimePrintable", + "Type": "string" + } + ] +} diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index afcc3d1d69e..88653cc7b9e 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -337,5 +337,6 @@ "WhisperSecurityConnector", "CayosoftGuardianConnector", "VaronisSaaSAlertsPush", - "RecordedFutureIdentityAlertImporter" + "RecordedFutureIdentityAlertImporter", + "ThinkstCanary" ] diff --git a/Logos/ThinkstCanary.svg b/Logos/ThinkstCanary.svg new file mode 100644 index 00000000000..5c110fea150 --- /dev/null +++ b/Logos/ThinkstCanary.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml b/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml new file mode 100644 index 00000000000..e93fca33c54 --- /dev/null +++ b/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml @@ -0,0 +1,120 @@ +id: 06360572-94a7-42a4-add7-58fb933b2353 +name: Canary alerts to incidents +description: Creates Microsoft Sentinel incidents from Thinkst Canary alerts. +severity: High +status: Available +requiredDataConnectors: + - connectorId: ThinkstCanary + dataTypes: + - ThinkstCanaryIncidents_CL +tactics: + - LateralMovement + - Exfiltration +relevantTechniques: [] +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 +suppressionDuration: 5h +suppressionEnabled: false +eventGroupingSettings: + aggregationKind: AlertPerResult +alertDetailsOverride: + alertDisplayNameFormat: '{{Description}} - {{AssetName}} from {{SourceDisplay}}' + alertDescriptionFormat: 'Thinkst {{AssetType}} {{AssetName}} recorded this activity from {{SourceDisplay}}. Review the mapped entities and custom details for asset, actor, and activity context.' +customDetails: + AssetType: AssetType + AssetName: AssetName + AssetNode: AssetNode + AssetIP: AssetIP + AssetLocation: AssetLocation + FlockName: FlockName + TokenMemo: TokenMemo + TokenType: TokenType + TokenTarget: TokenTarget + ActorUsername: ActorUsername + ActorDomain: ActorDomain + ActorHost: ActorHost + SourceGeo: SourceGeo + IncidentKey: IncidentId + SourceIP: SourceIP + DestinationPort: DestinationPort + Activity: Activity + UserAgent: UserAgent + LogType: LogType + EventsCount: EventsCount +entityMappings: + - entityType: IP + fieldMappings: + - identifier: Address + columnName: SourceIP + - entityType: IP + fieldMappings: + - identifier: Address + columnName: CanaryEntityIP + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: CanaryEntityName + - entityType: Account + fieldMappings: + - identifier: Name + columnName: ActorUsername + - entityType: DNS + fieldMappings: + - identifier: DomainName + columnName: TokenHostname +incidentConfiguration: + createIncident: true + groupingConfiguration: + enabled: false + reopenClosedIncident: false + lookbackDuration: PT5H + matchingMethod: AllEntities +version: 1.0.2 +kind: NRT diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json new file mode 100644 index 00000000000..798a0a1b356 --- /dev/null +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json @@ -0,0 +1,946 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "subscription": { + "defaultValue": "[last(split(subscription().id, '/'))]", + "type": "string", + "metadata": { + "description": "subscription id where Microsoft Sentinel is setup" + } + }, + "resourceGroupName": { + "defaultValue": "[resourceGroup().name]", + "type": "string", + "metadata": { + "description": "resource group name where Microsoft Sentinel is setup" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "clientId": { + "type": "securestring", + "defaultValue": "-NA-" + }, + "clientSecret": { + "type": "securestring", + "defaultValue": "-NA-" + } + }, + "variables": { + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_solutionName": "Thinkst Canary", + "_solutionVersion": "1.0.2", + "_solutionAuthor": "Thinkst Engineering", + "_solutionId": "azuresentinel.azure-sentinel-solution-ThinkstCanaryDefinition", + "dataConnectorVersionConnectorDefinition": "1.0.2", + "dataConnectorVersionConnections": "1.0.2", + "_solutionTier": "Community", + "_dataConnectorContentIdConnections": "ThinkstCanaryDefinitionConnections", + "dataConnectorTemplateNameConnections": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections')))]", + "_dataConnectorContentIdConnectorDefinition": "ThinkstCanaryDefinitionConnectorDefinition", + "dataConnectorTemplateNameConnectorDefinition": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition')))]", + "_logAnalyticsTableId1": "ThinkstCanaryIncidents_CL" + }, + "resources": [ + { + "type": "Microsoft.Insights/dataCollectionEndpoints", + "apiVersion": "2024-03-11", + "name": "[parameters('workspace')]", + "location": "[parameters('workspace-location')]", + "properties": { + "networkAcls": { + "publicNetworkAccess": "Enabled" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnectorDefinition'), variables('dataConnectorVersionConnectorDefinition'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]", + "displayName": "Thinkst Canary", + "contentKind": "DataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersionConnectorDefinition')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersionConnectorDefinition')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "[variables('_solutionAuthor')]" + }, + "support": { + "name": "[variables('_solutionAuthor')]", + "tier": "[variables('_solutionTier')]" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorVersionConnections')]", + "contentId": "[variables('_dataConnectorContentIdConnections')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "ThinkstCanary", + "title": "Thinkst Canary", + "publisher": "Thinkst Engineering", + "descriptionMarkdown": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "graphQueriesTableName": "ThinkstCanaryIncidents_CL", + "graphQueries": [ + { + "metricName": "Total incidents received", + "legend": "Thinkst Canary Incidents", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Thinkst Canary incidents in the last 24 hours", + "query": "ThinkstCanaryIncidents_CL\n| where TimeGenerated > ago(24h)\n| order by TimeGenerated desc" + }, + { + "description": "Top 10 source IPs triggering incidents", + "query": "ThinkstCanaryIncidents_CL\n| summarize IncidentCount = count() by SourceIP\n| where isnotempty(SourceIP)\n| top 10 by IncidentCount desc" + }, + { + "description": "Incidents by type", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by Description\n| order by Count desc" + }, + { + "description": "Incidents with event detail data", + "query": "ThinkstCanaryIncidents_CL\n| where isnotempty(RawEvent)\n| project TimeGenerated, Description, SourceIP, DestinationIP, DestinationPort, RawEvent" + }, + { + "description": "Incidents by flock", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by FlockId\n| order by Count desc" + } + ], + "dataTypes": [ + { + "name": "ThinkstCanaryIncidents_CL", + "lastDataReceivedQuery": "ThinkstCanaryIncidents_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors", + "value": [] + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": false + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Thinkst Canary API Key", + "description": "A Thinkst Canary API authentication token is required. [See the documentation](https://docs.canary.tools/guide/user-settings.html#generating-an-api-key) to learn how to generate an API key." + } + ] + }, + "instructionSteps": [ + { + "title": "Connect Thinkst Canary to Microsoft Sentinel", + "description": "Provide your Thinkst Canary Console domain (e.g. 'yourhash' from yourhash.canary.tools) and API authentication token.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "Canary Console Domain", + "placeholder": "yourhash", + "type": "text", + "name": "clientId", + "validations": { + "required": true + } + } + }, + { + "type": "Textbox", + "parameters": { + "label": "API Authentication Token", + "placeholder": "Enter your Canary API token", + "type": "password", + "name": "clientSecret", + "validations": { + "required": true + } + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "name": "toggle", + "connectLabel": "Connect", + "disconnectLabel": "Disconnect" + } + } + ] + } + ] + } + } + }, + { + "name": "[variables('_logAnalyticsTableId1')]", + "apiVersion": "2021-03-01-privatepreview", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "[variables('_logAnalyticsTableId1')]", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "description": "Timestamp when the incident was last updated" + }, + { + "name": "IncidentId", + "type": "string", + "description": "Unique incident key identifier" + }, + { + "name": "Description", + "type": "string", + "description": "Incident type description (e.g. SSH Login Attempt)" + }, + { + "name": "Acknowledged", + "type": "string", + "description": "Whether the incident has been acknowledged" + }, + { + "name": "Created", + "type": "real", + "description": "Unix timestamp of incident creation" + }, + { + "name": "CreatedPrintable", + "type": "string", + "description": "Human readable creation time" + }, + { + "name": "DestinationIP", + "type": "string", + "description": "Destination IP address (Canary device)" + }, + { + "name": "DestinationPort", + "type": "string", + "description": "Destination port targeted" + }, + { + "name": "EventsCount", + "type": "string", + "description": "Number of events in this incident" + }, + { + "name": "Events", + "type": "dynamic", + "description": "Array of event timestamps in milliseconds" + }, + { + "name": "FlockId", + "type": "string", + "description": "Flock ID the incident belongs to" + }, + { + "name": "FlockName", + "type": "string", + "description": "Flock name the incident belongs to" + }, + { + "name": "HashId", + "type": "string", + "description": "Hash identifier for the incident" + }, + { + "name": "Host", + "type": "dynamic", + "description": "Device details object (name, IP, version, services)" + }, + { + "name": "IpAddress", + "type": "string", + "description": "IP address field" + }, + { + "name": "IncidentUpdated", + "type": "datetime", + "description": "Datetime of last incident update" + }, + { + "name": "LocalTime", + "type": "string", + "description": "Local time of the incident on the device" + }, + { + "name": "Memo", + "type": "string", + "description": "Canarytoken reminder describing where the token was placed" + }, + { + "name": "RawEvent", + "type": "dynamic", + "description": "Array of detailed event log objects" + }, + { + "name": "LogType", + "type": "string", + "description": "Numeric log type identifier" + }, + { + "name": "NodeId", + "type": "string", + "description": "Node ID of the Canary or Canarytoken" + }, + { + "name": "Notified", + "type": "string", + "description": "Whether notification was sent" + }, + { + "name": "PreviouslySeenCount", + "type": "real", + "description": "Number of times this source was previously seen" + }, + { + "name": "Sensor", + "type": "string", + "description": "Sensor type (e.g. thinkstcanary)" + }, + { + "name": "SourceIP", + "type": "string", + "description": "Source IP address of the attacker" + }, + { + "name": "SrcHostReverse", + "type": "string", + "description": "Reverse DNS of the attacker" + }, + { + "name": "SourcePort", + "type": "string", + "description": "Source port of the attacker" + }, + { + "name": "UpdatedId", + "type": "real", + "description": "Incremental update ID for polling" + }, + { + "name": "UpdatedTimePrintable", + "type": "string", + "description": "Human readable last update time" + } + ] + } + } + }, + { + "name": "ThinkstCanaryDCR", + "apiVersion": "2021-09-01-preview", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "[parameters('workspace-location')]", + "kind": "Direct", + "properties": { + "streamDeclarations": { + "Custom-ThinkstCanaryIncidents_CL": { + "columns": [ + { + "name": "acknowledged", + "type": "string" + }, + { + "name": "created", + "type": "string" + }, + { + "name": "created_printable", + "type": "string" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "dst_host", + "type": "string" + }, + { + "name": "dst_port", + "type": "string" + }, + { + "name": "events_count", + "type": "string" + }, + { + "name": "events_list", + "type": "dynamic" + }, + { + "name": "flock_id", + "type": "string" + }, + { + "name": "flock_name", + "type": "string" + }, + { + "name": "hash_id", + "type": "string" + }, + { + "name": "host", + "type": "dynamic" + }, + { + "name": "incident_key", + "type": "string" + }, + { + "name": "ip_address", + "type": "string" + }, + { + "name": "ippers", + "type": "string" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "local_time", + "type": "string" + }, + { + "name": "logdata", + "type": "dynamic" + }, + { + "name": "logtype", + "type": "string" + }, + { + "name": "mac_address", + "type": "string" + }, + { + "name": "memo", + "type": "string" + }, + { + "name": "node_id", + "type": "string" + }, + { + "name": "notified", + "type": "string" + }, + { + "name": "previously_seen_count", + "type": "real" + }, + { + "name": "sensor", + "type": "string" + }, + { + "name": "src_host", + "type": "string" + }, + { + "name": "src_host_reverse", + "type": "string" + }, + { + "name": "src_port", + "type": "string" + }, + { + "name": "updated", + "type": "string" + }, + { + "name": "updated_id", + "type": "real" + }, + { + "name": "updated_time", + "type": "string" + }, + { + "name": "updated_time_printable", + "type": "string" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('workspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-ThinkstCanaryIncidents_CL" + ], + "destinations": [ + "clv2ws1" + ], + "outputStream": "Custom-ThinkstCanaryIncidents_CL", + "transformKql": "source | extend TimeGenerated = datetime_add('second', tolong(updated_time), datetime(1970-01-01)) | project TimeGenerated, IncidentId = tostring(incident_key), Description = tostring(description), Acknowledged = tostring(acknowledged), Created = toreal(created), CreatedPrintable = tostring(created_printable), DestinationIP = tostring(dst_host), DestinationPort = tostring(dst_port), EventsCount = tostring(events_count), Events = todynamic(events_list), FlockId = tostring(flock_id), FlockName = tostring(flock_name), HashId = tostring(hash_id), Host = todynamic(host), IpAddress = tostring(ip_address), IncidentUpdated = TimeGenerated, LocalTime = tostring(local_time), Memo = tostring(memo), RawEvent = todynamic(logdata), LogType = tostring(logtype), NodeId = tostring(node_id), Notified = tostring(notified), PreviouslySeenCount = toreal(previously_seen_count), Sensor = tostring(sensor), SourceIP = tostring(src_host), SrcHostReverse = tostring(src_host_reverse), SourcePort = tostring(src_port), UpdatedId = toreal(updated_id), UpdatedTimePrintable = tostring(updated_time_printable)" + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces/tables', parameters('workspace'), variables('_logAnalyticsTableId1'))]" + ] + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition'),'-', variables('dataConnectorVersionConnectorDefinition'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('_solutionVersion')]" + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "ThinkstCanary", + "title": "Thinkst Canary", + "publisher": "Thinkst Engineering", + "descriptionMarkdown": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "graphQueriesTableName": "ThinkstCanaryIncidents_CL", + "graphQueries": [ + { + "metricName": "Total incidents received", + "legend": "Thinkst Canary Incidents", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Thinkst Canary incidents in the last 24 hours", + "query": "ThinkstCanaryIncidents_CL\n| where TimeGenerated > ago(24h)\n| order by TimeGenerated desc" + }, + { + "description": "Top 10 source IPs triggering incidents", + "query": "ThinkstCanaryIncidents_CL\n| summarize IncidentCount = count() by SourceIP\n| where isnotempty(SourceIP)\n| top 10 by IncidentCount desc" + }, + { + "description": "Incidents by type", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by Description\n| order by Count desc" + }, + { + "description": "Incidents with event detail data", + "query": "ThinkstCanaryIncidents_CL\n| where isnotempty(RawEvent)\n| project TimeGenerated, Description, SourceIP, DestinationIP, DestinationPort, RawEvent" + }, + { + "description": "Incidents by flock", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by FlockId\n| order by Count desc" + } + ], + "dataTypes": [ + { + "name": "ThinkstCanaryIncidents_CL", + "lastDataReceivedQuery": "ThinkstCanaryIncidents_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors", + "value": [] + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": false + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Thinkst Canary API Key", + "description": "A Thinkst Canary API authentication token is required. [See the documentation](https://docs.canary.tools/guide/user-settings.html#generating-an-api-key) to learn how to generate an API key." + } + ] + }, + "instructionSteps": [ + { + "title": "Connect Thinkst Canary to Microsoft Sentinel", + "description": "Provide your Thinkst Canary Console domain (e.g. 'yourhash' from yourhash.canary.tools) and API authentication token.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "Canary Console Domain", + "placeholder": "yourhash", + "type": "text", + "name": "clientId", + "validations": { + "required": true + } + } + }, + { + "type": "Textbox", + "parameters": { + "label": "API Authentication Token", + "placeholder": "Enter your Canary API token", + "type": "password", + "name": "clientSecret", + "validations": { + "required": true + } + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "name": "toggle", + "connectLabel": "Connect", + "disconnectLabel": "Disconnect" + } + } + ] + } + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersionConnectorDefinition')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "[variables('_solutionAuthor')]" + }, + "support": { + "name": "[variables('_solutionAuthor')]", + "tier": "[variables('_solutionTier')]" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorVersionConnections')]", + "contentId": "[variables('_dataConnectorContentIdConnections')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnections'), variables('dataConnectorVersionConnections'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnections')]", + "displayName": "Thinkst Canary", + "contentKind": "ResourcesDataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersionConnections')]", + "parameters": { + "connectorDefinitionName": { + "defaultValue": "connectorDefinitionName", + "type": "string", + "minLength": 1 + }, + "workspace": { + "defaultValue": "[parameters('workspace')]", + "type": "string" + }, + "dcrConfig": { + "defaultValue": { + "dataCollectionEndpoint": "data collection Endpoint", + "dataCollectionRuleImmutableId": "data collection rule immutableId" + }, + "type": "object" + }, + "clientId": { + "defaultValue": "-NA-", + "type": "securestring", + "minLength": 1 + }, + "clientSecret": { + "defaultValue": "-NA-", + "type": "securestring", + "minLength": 1 + }, + "authorizationCode": { + "defaultValue": "-NA-", + "type": "securestring", + "minLength": 1 + } + }, + "variables": { + "_dataConnectorContentIdConnections": "[variables('_dataConnectorContentIdConnections')]" + }, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnections')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentIdConnections'))]", + "contentId": "[variables('_dataConnectorContentIdConnections')]", + "kind": "ResourcesDataConnector", + "version": "[variables('dataConnectorVersionConnections')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "[variables('_solutionAuthor')]" + }, + "support": { + "name": "[variables('_solutionAuthor')]", + "tier": "[variables('_solutionTier')]" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', 'ThinkstCanaryIncidentsConnector')]", + "apiVersion": "2022-12-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "[[parameters('connectorDefinitionName')]", + "dataType": "ThinkstCanaryIncidents_CL", + "dcrConfig": { + "streamName": "Custom-ThinkstCanaryIncidents_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "auth": { + "type": "APIKey", + "apiKey": "not-used-by-canary", + "apiKeyIdentifier": "QueryParameter", + "apiKeyName": "not_used_by_canary" + }, + "request": { + "apiEndpoint": "[[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", + "httpMethod": "GET", + "headers": { + "X-Canary-Auth-Token": "[[parameters('clientSecret')]", + "User-Agent": "Microsoft Sentinel Thinkst Canary Connector - Version 1.0", + "Accept": "application/json" + }, + "rateLimitQPS": 10, + "StartTimeAttributeName": "newer_than", + "queryTimeFormat": "yyyy-MM-dd-HH:mm:ss", + "queryWindowInMin": 5, + "retryCount": 3, + "timeoutInSeconds": 60, + "queryParameters": { + "filter_incident_state": "all", + "limit": "100" + } + }, + "response": { + "eventsJsonPaths": [ + "$.incidents" + ], + "format": "json", + "successStatusJsonPath": "$.result", + "successStatusValue": "success" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor.next", + "NextPageParaName": "cursor", + "pageSize": 100 + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','rdc','-', uniqueString(concat(variables('_solutionId'),'-','ResourcesDataConnector','-',variables('_dataConnectorContentIdConnections'),'-', variables('dataConnectorVersionConnections'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('_solutionVersion')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "[variables('_solutionVersion')]", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "[variables('_solutionName')]", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "[variables('_solutionAuthor')]" + }, + "support": { + "name": "[variables('_solutionAuthor')]", + "tier": "[variables('_solutionTier')]" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition')]", + "version": "[variables('dataConnectorVersionConnectorDefinition')]" + } + ] + }, + "firstPublishDate": "2022-06-24", + "providers": [ + "[variables('_solutionAuthor')]" + ], + "contentKind": "Solution", + "packageId": "[variables('_solutionId')]", + "contentProductId": "[concat(substring(variables('_solutionId'), 0, 50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]", + "displayName": "Thinkst Canary", + "publisherDisplayName": "Thinkst Engineering", + "description": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "descriptionHtml": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "icon": "data:image/png;base64,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", + "parentId": "[variables('_solutionId')]" + } + } + ] +} diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ConnectorDefinition.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ConnectorDefinition.json new file mode 100644 index 00000000000..5cbc614c76d --- /dev/null +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ConnectorDefinition.json @@ -0,0 +1,134 @@ +{ + "name": "ThinkstCanary", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.SecurityInsights/dataConnectorDefinitions", + "location": "{{location}}", + "kind": "Customizable", + "availability": { + "isPreview": true, + "status": 1 + }, + "properties": { + "connectorUiConfig": { + "id": "ThinkstCanary", + "title": "Thinkst Canary", + "publisher": "Thinkst Engineering", + "descriptionMarkdown": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "graphQueriesTableName": "ThinkstCanaryIncidents_CL", + "graphQueries": [ + { + "metricName": "Total incidents received", + "legend": "Thinkst Canary Incidents", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Thinkst Canary incidents in the last 24 hours", + "query": "ThinkstCanaryIncidents_CL\n| where TimeGenerated > ago(24h)\n| order by TimeGenerated desc" + }, + { + "description": "Top 10 source IPs triggering incidents", + "query": "ThinkstCanaryIncidents_CL\n| summarize IncidentCount = count() by SourceIP\n| where isnotempty(SourceIP)\n| top 10 by IncidentCount desc" + }, + { + "description": "Incidents by type", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by Description\n| order by Count desc" + }, + { + "description": "Incidents with event detail data", + "query": "ThinkstCanaryIncidents_CL\n| where isnotempty(RawEvent)\n| project TimeGenerated, Description, SourceIP, DestinationIP, DestinationPort, RawEvent" + }, + { + "description": "Incidents by flock", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by FlockId\n| order by Count desc" + } + ], + "dataTypes": [ + { + "name": "ThinkstCanaryIncidents_CL", + "lastDataReceivedQuery": "ThinkstCanaryIncidents_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": false + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Thinkst Canary API Key", + "description": "A Thinkst Canary API authentication token is required. [See the documentation](https://docs.canary.tools/guide/user-settings.html#generating-an-api-key) to learn how to generate an API key." + } + ] + }, + "instructionSteps": [ + { + "title": "Connect Thinkst Canary to Microsoft Sentinel", + "description": "Provide your Thinkst Canary Console domain (e.g. 'yourhash' from yourhash.canary.tools) and API authentication token.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "Canary Console Domain", + "placeholder": "yourhash", + "type": "text", + "name": "clientId", + "validations": { + "required": true + } + } + }, + { + "type": "Textbox", + "parameters": { + "label": "API Authentication Token", + "placeholder": "Enter your Canary API token", + "type": "password", + "name": "clientSecret", + "validations": { + "required": true + } + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "name": "toggle", + "connectLabel": "Connect", + "disconnectLabel": "Disconnect" + } + } + ] + } + ] + } + } +} diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_DCR.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_DCR.json new file mode 100644 index 00000000000..9ce9da5bb4b --- /dev/null +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_DCR.json @@ -0,0 +1,166 @@ +{ + "name": "ThinkstCanaryDCR", + "apiVersion": "2024-03-11", + "type": "Microsoft.Insights/dataCollectionRules", + "kind": "Direct", + "location": "{{location}}", + "tags": { + "createdBy": "SentinelCodelessConnector" + }, + "properties": { + "streamDeclarations": { + "Custom-ThinkstCanaryIncidents_CL": { + "columns": [ + { + "name": "acknowledged", + "type": "string" + }, + { + "name": "created", + "type": "string" + }, + { + "name": "created_printable", + "type": "string" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "dst_host", + "type": "string" + }, + { + "name": "dst_port", + "type": "string" + }, + { + "name": "events_count", + "type": "string" + }, + { + "name": "events_list", + "type": "dynamic" + }, + { + "name": "flock_id", + "type": "string" + }, + { + "name": "flock_name", + "type": "string" + }, + { + "name": "hash_id", + "type": "string" + }, + { + "name": "host", + "type": "dynamic" + }, + { + "name": "incident_key", + "type": "string" + }, + { + "name": "ip_address", + "type": "string" + }, + { + "name": "ippers", + "type": "string" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "local_time", + "type": "string" + }, + { + "name": "logdata", + "type": "dynamic" + }, + { + "name": "logtype", + "type": "string" + }, + { + "name": "mac_address", + "type": "string" + }, + { + "name": "memo", + "type": "string" + }, + { + "name": "node_id", + "type": "string" + }, + { + "name": "notified", + "type": "string" + }, + { + "name": "previously_seen_count", + "type": "real" + }, + { + "name": "sensor", + "type": "string" + }, + { + "name": "src_host", + "type": "string" + }, + { + "name": "src_host_reverse", + "type": "string" + }, + { + "name": "src_port", + "type": "string" + }, + { + "name": "updated", + "type": "string" + }, + { + "name": "updated_id", + "type": "real" + }, + { + "name": "updated_time", + "type": "string" + }, + { + "name": "updated_time_printable", + "type": "string" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "{{workspaceResourceId}}", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-ThinkstCanaryIncidents_CL" + ], + "destinations": [ + "clv2ws1" + ], + "outputStream": "Custom-ThinkstCanaryIncidents_CL", + "transformKql": "source | extend TimeGenerated = datetime_add('second', tolong(updated_time), datetime(1970-01-01)) | project TimeGenerated, IncidentId = tostring(incident_key), Description = tostring(description), Acknowledged = tostring(acknowledged), Created = toreal(created), CreatedPrintable = tostring(created_printable), DestinationIP = tostring(dst_host), DestinationPort = tostring(dst_port), EventsCount = tostring(events_count), Events = todynamic(events_list), FlockId = tostring(flock_id), FlockName = tostring(flock_name), HashId = tostring(hash_id), Host = todynamic(host), IpAddress = tostring(ip_address), IncidentUpdated = TimeGenerated, LocalTime = tostring(local_time), Memo = tostring(memo), RawEvent = todynamic(logdata), LogType = tostring(logtype), NodeId = tostring(node_id), Notified = tostring(notified), PreviouslySeenCount = toreal(previously_seen_count), Sensor = tostring(sensor), SourceIP = tostring(src_host), SrcHostReverse = tostring(src_host_reverse), SourcePort = tostring(src_port), UpdatedId = toreal(updated_id), UpdatedTimePrintable = tostring(updated_time_printable)" + } + ] + } +} diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_PollingConfig.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_PollingConfig.json new file mode 100644 index 00000000000..f2f89478ed7 --- /dev/null +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_PollingConfig.json @@ -0,0 +1,53 @@ +{ + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "ThinkstCanaryIncidentsConnector", + "location": "{{location}}", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "ThinkstCanary", + "dataType": "ThinkstCanaryIncidents_CL", + "dcrConfig": { + "streamName": "Custom-ThinkstCanaryIncidents_CL", + "dataCollectionEndpoint": "{{dataCollectionEndpoint}}", + "dataCollectionRuleImmutableId": "{{dataCollectionRuleImmutableId}}" + }, + "auth": { + "type": "APIKey", + "apiKey": "not-used-by-canary", + "apiKeyIdentifier": "QueryParameter", + "apiKeyName": "not_used_by_canary" + }, + "request": { + "apiEndpoint": "https://{{clientId}}.canary.tools/api/v1/incidents/search", + "httpMethod": "GET", + "headers": { + "X-Canary-Auth-Token": "{{clientSecret}}", + "User-Agent": "Microsoft Sentinel Thinkst Canary Connector - Version 1.0", + "Accept": "application/json" + }, + "rateLimitQPS": 10, + "StartTimeAttributeName": "newer_than", + "queryTimeFormat": "yyyy-MM-dd-HH:mm:ss", + "queryWindowInMin": 5, + "retryCount": 3, + "timeoutInSeconds": 60, + "queryParameters": { + "filter_incident_state": "all", + "limit": "100" + } + }, + "response": { + "eventsJsonPaths": ["$.incidents"], + "format": "json", + "successStatusJsonPath": "$.result", + "successStatusValue": "success" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor.next", + "NextPageParaName": "cursor", + "pageSize": 100 + } + } +} diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_Table.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_Table.json new file mode 100644 index 00000000000..51514a498e3 --- /dev/null +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_Table.json @@ -0,0 +1,44 @@ +[ + { + "name": "ThinkstCanaryIncidents_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2025-02-01", + "location": "{{location}}", + "properties": { + "schema": { + "name": "ThinkstCanaryIncidents_CL", + "columns": [ + { "name": "TimeGenerated", "type": "datetime", "description": "Timestamp when the incident was last updated" }, + { "name": "IncidentId", "type": "string", "description": "Unique incident key identifier" }, + { "name": "Description", "type": "string", "description": "Incident type description (e.g. SSH Login Attempt)" }, + { "name": "Acknowledged", "type": "string", "description": "Whether the incident has been acknowledged" }, + { "name": "Created", "type": "real", "description": "Unix timestamp of incident creation" }, + { "name": "CreatedPrintable", "type": "string", "description": "Human readable creation time" }, + { "name": "DestinationIP", "type": "string", "description": "Destination IP address (Canary device)" }, + { "name": "DestinationPort", "type": "string", "description": "Destination port targeted" }, + { "name": "EventsCount", "type": "string", "description": "Number of events in this incident" }, + { "name": "Events", "type": "dynamic", "description": "Array of event timestamps in milliseconds" }, + { "name": "FlockId", "type": "string", "description": "Flock ID the incident belongs to" }, + { "name": "FlockName", "type": "string", "description": "Flock name the incident belongs to" }, + { "name": "HashId", "type": "string", "description": "Hash identifier for the incident" }, + { "name": "Host", "type": "dynamic", "description": "Device details object (name, IP, version, services)" }, + { "name": "IpAddress", "type": "string", "description": "IP address field" }, + { "name": "IncidentUpdated", "type": "datetime", "description": "Datetime of last incident update" }, + { "name": "LocalTime", "type": "string", "description": "Local time of the incident on the device" }, + { "name": "Memo", "type": "string", "description": "Canarytoken reminder describing where the token was placed" }, + { "name": "RawEvent", "type": "dynamic", "description": "Array of detailed event log objects" }, + { "name": "LogType", "type": "string", "description": "Numeric log type identifier" }, + { "name": "NodeId", "type": "string", "description": "Node ID of the Canary or Canarytoken" }, + { "name": "Notified", "type": "string", "description": "Whether notification was sent" }, + { "name": "PreviouslySeenCount", "type": "real", "description": "Number of times this source was previously seen" }, + { "name": "Sensor", "type": "string", "description": "Sensor type (e.g. thinkstcanary)" }, + { "name": "SourceIP", "type": "string", "description": "Source IP address of the attacker" }, + { "name": "SrcHostReverse", "type": "string", "description": "Reverse DNS of the attacker" }, + { "name": "SourcePort", "type": "string", "description": "Source port of the attacker" }, + { "name": "UpdatedId", "type": "real", "description": "Incremental update ID for polling" }, + { "name": "UpdatedTimePrintable", "type": "string", "description": "Human readable last update time" } + ] + } + } + } +] diff --git a/Solutions/ThinkstCanary/Data/Solution_ThinkstCanary.json b/Solutions/ThinkstCanary/Data/Solution_ThinkstCanary.json new file mode 100644 index 00000000000..b53dd32e140 --- /dev/null +++ b/Solutions/ThinkstCanary/Data/Solution_ThinkstCanary.json @@ -0,0 +1,16 @@ +{ + "Name": "ThinkstCanary", + "Author": "Thinkst Applied Research - support@canary.tools", + "Logo": "", + "Description": "The Thinkst Canary solution for Microsoft Sentinel ingests Canary and Canarytoken incidents through the Codeless Connector Framework and provides normalized parsers, detections and response automation.", + "BasePath": "Solutions/ThinkstCanary", + "Version": "1.0.0", + "TemplateSpec": true, + "Data Connectors": [ + "Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ConnectorDefinition.json" + ], + "Analytic Rules": [ + "Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml" + ], + "Metadata": "SolutionMetadata.json" +} diff --git a/Solutions/ThinkstCanary/Package/3.0.0.zip b/Solutions/ThinkstCanary/Package/3.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..32ce62bb9fd2fd647d1f6230bfb5fb08d24cb8d3 GIT binary patch literal 10258 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 Q7{tGs{V(cM{rB#_0P_6#H2?qr literal 0 HcmV?d00001 diff --git a/Solutions/ThinkstCanary/Package/createUiDefinition.json b/Solutions/ThinkstCanary/Package/createUiDefinition.json new file mode 100644 index 00000000000..7113dc90122 --- /dev/null +++ b/Solutions/ThinkstCanary/Package/createUiDefinition.json @@ -0,0 +1,127 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "isWizard": false, + "basics": { + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/ThinkstCanary/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe Thinkst Canary solution for Microsoft Sentinel ingests Canary and Canarytoken incidents through the Codeless Connector Framework and provides normalized parsers, detections and response automation.\n\n**Data Connectors:** 1, **Analytic Rules:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "dataconnectors", + "label": "Data Connectors", + "bladeTitle": "Data Connectors", + "elements": [ + { + "name": "dataconnectors1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Solution installs the data connector for Thinkst Canary. You can get Thinkst Canary data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + } + }, + { + "name": "dataconnectors-link1", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more about connecting data sources", + "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" + } + } + } + ] + }, + { + "name": "analytics", + "label": "Analytics", + "subLabel": { + "preValidation": "Configure the analytics", + "postValidation": "Done" + }, + "bladeTitle": "Analytics", + "elements": [ + { + "name": "analytics-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view." + } + }, + { + "name": "analytics-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-detect-threats-custom?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" + } + } + }, + { + "name": "analytic1", + "type": "Microsoft.Common.Section", + "label": "Canary alerts to incidents", + "elements": [ + { + "name": "analytic1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Creates Microsoft Sentinel incidents from Thinkst Canary alerts." + } + } + ] + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} diff --git a/Solutions/ThinkstCanary/Package/mainTemplate.json b/Solutions/ThinkstCanary/Package/mainTemplate.json new file mode 100644 index 00000000000..1968dce163a --- /dev/null +++ b/Solutions/ThinkstCanary/Package/mainTemplate.json @@ -0,0 +1,1119 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "Thinkst Applied Research - support@canary.tools", + "comments": "Solution template for ThinkstCanary" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } + }, + "variables": { + "email": "support@canary.tools", + "_email": "[variables('email')]", + "_solutionName": "ThinkstCanary", + "_solutionVersion": "3.0.0", + "solutionId": "87073660.azure-sentinel-solution-thinkst-canary", + "_solutionId": "[variables('solutionId')]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "dataConnectorCCPVersion": "3.0.0", + "_dataConnectorContentIdConnectorDefinition1": "ThinkstCanary", + "dataConnectorTemplateNameConnectorDefinition1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition1')))]", + "_dataConnectorContentIdConnections1": "ThinkstCanaryConnections", + "dataConnectorTemplateNameConnections1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections1')))]", + "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', parameters('workspace'))]", + "analyticRuleObject1": { + "analyticRuleVersion1": "1.0.2", + "_analyticRulecontentId1": "06360572-94a7-42a4-add7-58fb933b2353", + "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '06360572-94a7-42a4-add7-58fb933b2353')]", + "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('06360572-94a7-42a4-add7-58fb933b2353')))]", + "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','06360572-94a7-42a4-add7-58fb933b2353','-', '1.0.2')))]" + }, + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnectorDefinition1'), variables('dataConnectorCCPVersion'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition1')]", + "displayName": "Thinkst Canary", + "contentKind": "DataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorCCPVersion')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition1'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "ThinkstCanary", + "title": "Thinkst Canary", + "publisher": "Thinkst Engineering", + "descriptionMarkdown": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "graphQueriesTableName": "ThinkstCanaryIncidents_CL", + "graphQueries": [ + { + "metricName": "Total incidents received", + "legend": "Thinkst Canary Incidents", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Thinkst Canary incidents in the last 24 hours", + "query": "ThinkstCanaryIncidents_CL\n| where TimeGenerated > ago(24h)\n| order by TimeGenerated desc" + }, + { + "description": "Top 10 source IPs triggering incidents", + "query": "ThinkstCanaryIncidents_CL\n| summarize IncidentCount = count() by SourceIP\n| where isnotempty(SourceIP)\n| top 10 by IncidentCount desc" + }, + { + "description": "Incidents by type", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by Description\n| order by Count desc" + }, + { + "description": "Incidents with event detail data", + "query": "ThinkstCanaryIncidents_CL\n| where isnotempty(RawEvent)\n| project TimeGenerated, Description, SourceIP, DestinationIP, DestinationPort, RawEvent" + }, + { + "description": "Incidents by flock", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by FlockId\n| order by Count desc" + } + ], + "dataTypes": [ + { + "name": "ThinkstCanaryIncidents_CL", + "lastDataReceivedQuery": "ThinkstCanaryIncidents_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": false + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Thinkst Canary API Key", + "description": "A Thinkst Canary API authentication token is required. [See the documentation](https://docs.canary.tools/guide/user-settings.html#generating-an-api-key) to learn how to generate an API key." + } + ] + }, + "instructionSteps": [ + { + "title": "Connect Thinkst Canary to Microsoft Sentinel", + "description": "Provide your Thinkst Canary Console domain (e.g. 'yourhash' from yourhash.canary.tools) and API authentication token.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "Canary Console Domain", + "placeholder": "yourhash", + "type": "text", + "name": "clientId", + "validations": { + "required": true + } + } + }, + { + "type": "Textbox", + "parameters": { + "label": "API Authentication Token", + "placeholder": "Enter your Canary API token", + "type": "password", + "name": "clientSecret", + "validations": { + "required": true + } + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "name": "toggle", + "connectLabel": "Connect", + "disconnectLabel": "Disconnect" + } + } + ] + } + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition1')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition1'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "[variables('_email')]" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorCCPVersion')]", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "name": "ThinkstCanaryDCR", + "apiVersion": "2022-06-01", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "[parameters('workspace-location')]", + "kind": "Direct", + "properties": { + "streamDeclarations": { + "Custom-ThinkstCanaryIncidents_CL": { + "columns": [ + { + "name": "acknowledged", + "type": "string" + }, + { + "name": "created", + "type": "string" + }, + { + "name": "created_printable", + "type": "string" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "dst_host", + "type": "string" + }, + { + "name": "dst_port", + "type": "string" + }, + { + "name": "events_count", + "type": "string" + }, + { + "name": "events_list", + "type": "dynamic" + }, + { + "name": "flock_id", + "type": "string" + }, + { + "name": "flock_name", + "type": "string" + }, + { + "name": "hash_id", + "type": "string" + }, + { + "name": "host", + "type": "dynamic" + }, + { + "name": "incident_key", + "type": "string" + }, + { + "name": "ip_address", + "type": "string" + }, + { + "name": "ippers", + "type": "string" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "local_time", + "type": "string" + }, + { + "name": "logdata", + "type": "dynamic" + }, + { + "name": "logtype", + "type": "string" + }, + { + "name": "mac_address", + "type": "string" + }, + { + "name": "memo", + "type": "string" + }, + { + "name": "node_id", + "type": "string" + }, + { + "name": "notified", + "type": "string" + }, + { + "name": "previously_seen_count", + "type": "real" + }, + { + "name": "sensor", + "type": "string" + }, + { + "name": "src_host", + "type": "string" + }, + { + "name": "src_host_reverse", + "type": "string" + }, + { + "name": "src_port", + "type": "string" + }, + { + "name": "updated", + "type": "string" + }, + { + "name": "updated_id", + "type": "real" + }, + { + "name": "updated_time", + "type": "string" + }, + { + "name": "updated_time_printable", + "type": "string" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('workspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-ThinkstCanaryIncidents_CL" + ], + "destinations": [ + "clv2ws1" + ], + "outputStream": "Custom-ThinkstCanaryIncidents_CL", + "transformKql": "source | extend TimeGenerated = datetime_add('second', tolong(updated_time), datetime(1970-01-01)) | project TimeGenerated, IncidentId = tostring(incident_key), Description = tostring(description), Acknowledged = tostring(acknowledged), Created = toreal(created), CreatedPrintable = tostring(created_printable), DestinationIP = tostring(dst_host), DestinationPort = tostring(dst_port), EventsCount = tostring(events_count), Events = todynamic(events_list), FlockId = tostring(flock_id), FlockName = tostring(flock_name), HashId = tostring(hash_id), Host = todynamic(host), IpAddress = tostring(ip_address), IncidentUpdated = TimeGenerated, LocalTime = tostring(local_time), Memo = tostring(memo), RawEvent = todynamic(logdata), LogType = tostring(logtype), NodeId = tostring(node_id), Notified = tostring(notified), PreviouslySeenCount = toreal(previously_seen_count), Sensor = tostring(sensor), SourceIP = tostring(src_host), SrcHostReverse = tostring(src_host_reverse), SourcePort = tostring(src_port), UpdatedId = toreal(updated_id), UpdatedTimePrintable = tostring(updated_time_printable)" + } + ], + "dataCollectionEndpointId": "[variables('dataCollectionEndpointId')]" + } + }, + { + "name": "ThinkstCanaryIncidents_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "ThinkstCanaryIncidents_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime", + "description": "Timestamp when the incident was last updated" + }, + { + "name": "IncidentId", + "type": "string", + "description": "Unique incident key identifier" + }, + { + "name": "Description", + "type": "string", + "description": "Incident type description (e.g. SSH Login Attempt)" + }, + { + "name": "Acknowledged", + "type": "string", + "description": "Whether the incident has been acknowledged" + }, + { + "name": "Created", + "type": "real", + "description": "Unix timestamp of incident creation" + }, + { + "name": "CreatedPrintable", + "type": "string", + "description": "Human readable creation time" + }, + { + "name": "DestinationIP", + "type": "string", + "description": "Destination IP address (Canary device)" + }, + { + "name": "DestinationPort", + "type": "string", + "description": "Destination port targeted" + }, + { + "name": "EventsCount", + "type": "string", + "description": "Number of events in this incident" + }, + { + "name": "Events", + "type": "dynamic", + "description": "Array of event timestamps in milliseconds" + }, + { + "name": "FlockId", + "type": "string", + "description": "Flock ID the incident belongs to" + }, + { + "name": "FlockName", + "type": "string", + "description": "Flock name the incident belongs to" + }, + { + "name": "HashId", + "type": "string", + "description": "Hash identifier for the incident" + }, + { + "name": "Host", + "type": "dynamic", + "description": "Device details object (name, IP, version, services)" + }, + { + "name": "IpAddress", + "type": "string", + "description": "IP address field" + }, + { + "name": "IncidentUpdated", + "type": "datetime", + "description": "Datetime of last incident update" + }, + { + "name": "LocalTime", + "type": "string", + "description": "Local time of the incident on the device" + }, + { + "name": "Memo", + "type": "string", + "description": "Canarytoken reminder describing where the token was placed" + }, + { + "name": "RawEvent", + "type": "dynamic", + "description": "Array of detailed event log objects" + }, + { + "name": "LogType", + "type": "string", + "description": "Numeric log type identifier" + }, + { + "name": "NodeId", + "type": "string", + "description": "Node ID of the Canary or Canarytoken" + }, + { + "name": "Notified", + "type": "string", + "description": "Whether notification was sent" + }, + { + "name": "PreviouslySeenCount", + "type": "real", + "description": "Number of times this source was previously seen" + }, + { + "name": "Sensor", + "type": "string", + "description": "Sensor type (e.g. thinkstcanary)" + }, + { + "name": "SourceIP", + "type": "string", + "description": "Source IP address of the attacker" + }, + { + "name": "SrcHostReverse", + "type": "string", + "description": "Reverse DNS of the attacker" + }, + { + "name": "SourcePort", + "type": "string", + "description": "Source port of the attacker" + }, + { + "name": "UpdatedId", + "type": "real", + "description": "Incremental update ID for polling" + }, + { + "name": "UpdatedTimePrintable", + "type": "string", + "description": "Human readable last update time" + } + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition1'),'-', variables('dataConnectorCCPVersion'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('dataConnectorCCPVersion')]" + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition1'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "ThinkstCanary", + "title": "Thinkst Canary", + "publisher": "Thinkst Engineering", + "descriptionMarkdown": "The Thinkst Canary connector allows you to ingest security incidents from your Thinkst Canary honeypot network into Microsoft Sentinel. Canary devices detect unauthorized access attempts including SSH logins, RDP sessions, HTTP requests, database queries, file share access, and Canarytoken triggers. This connector automatically pulls all incident data for analysis and alerting.", + "graphQueriesTableName": "ThinkstCanaryIncidents_CL", + "graphQueries": [ + { + "metricName": "Total incidents received", + "legend": "Thinkst Canary Incidents", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Thinkst Canary incidents in the last 24 hours", + "query": "ThinkstCanaryIncidents_CL\n| where TimeGenerated > ago(24h)\n| order by TimeGenerated desc" + }, + { + "description": "Top 10 source IPs triggering incidents", + "query": "ThinkstCanaryIncidents_CL\n| summarize IncidentCount = count() by SourceIP\n| where isnotempty(SourceIP)\n| top 10 by IncidentCount desc" + }, + { + "description": "Incidents by type", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by Description\n| order by Count desc" + }, + { + "description": "Incidents with event detail data", + "query": "ThinkstCanaryIncidents_CL\n| where isnotempty(RawEvent)\n| project TimeGenerated, Description, SourceIP, DestinationIP, DestinationPort, RawEvent" + }, + { + "description": "Incidents by flock", + "query": "ThinkstCanaryIncidents_CL\n| summarize Count = count() by FlockId\n| order by Count desc" + } + ], + "dataTypes": [ + { + "name": "ThinkstCanaryIncidents_CL", + "lastDataReceivedQuery": "ThinkstCanaryIncidents_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": false + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Thinkst Canary API Key", + "description": "A Thinkst Canary API authentication token is required. [See the documentation](https://docs.canary.tools/guide/user-settings.html#generating-an-api-key) to learn how to generate an API key." + } + ] + }, + "instructionSteps": [ + { + "title": "Connect Thinkst Canary to Microsoft Sentinel", + "description": "Provide your Thinkst Canary Console domain (e.g. 'yourhash' from yourhash.canary.tools) and API authentication token.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "Canary Console Domain", + "placeholder": "yourhash", + "type": "text", + "name": "clientId", + "validations": { + "required": true + } + } + }, + { + "type": "Textbox", + "parameters": { + "label": "API Authentication Token", + "placeholder": "Enter your Canary API token", + "type": "password", + "name": "clientSecret", + "validations": { + "required": true + } + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "name": "toggle", + "connectLabel": "Connect", + "disconnectLabel": "Disconnect" + } + } + ] + } + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition1')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition1'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "[variables('_email')]" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorCCPVersion')]", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnections1'), variables('dataConnectorCCPVersion'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "displayName": "Thinkst Canary", + "contentKind": "ResourcesDataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorCCPVersion')]", + "parameters": { + "guidValue": { + "defaultValue": "[[newGuid()]", + "type": "securestring" + }, + "innerWorkspace": { + "defaultValue": "[parameters('workspace')]", + "type": "securestring" + }, + "connectorDefinitionName": { + "defaultValue": "Thinkst Canary", + "type": "securestring", + "minLength": 1 + }, + "workspace": { + "defaultValue": "[parameters('workspace')]", + "type": "securestring" + }, + "dcrConfig": { + "defaultValue": { + "dataCollectionEndpoint": "data collection Endpoint", + "dataCollectionRuleImmutableId": "data collection rule immutableId" + }, + "type": "object" + }, + "clientId": { + "defaultValue": "clientId", + "type": "securestring", + "minLength": 1 + }, + "clientSecret": { + "defaultValue": "clientSecret", + "type": "securestring", + "minLength": 1 + } + }, + "variables": { + "_dataConnectorContentIdConnections1": "[variables('_dataConnectorContentIdConnections1')]" + }, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnections1')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentIdConnections1'))]", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "kind": "ResourcesDataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "[variables('_email')]" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + } + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'ThinkstCanaryIncidentsConnector', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "ThinkstCanary", + "dataType": "ThinkstCanaryIncidents_CL", + "dcrConfig": { + "streamName": "Custom-ThinkstCanaryIncidents_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "auth": { + "type": "APIKey", + "apiKey": "not-used-by-canary", + "apiKeyIdentifier": "QueryParameter", + "apiKeyName": "not_used_by_canary" + }, + "request": { + "apiEndpoint": "[[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", + "httpMethod": "GET", + "headers": { + "X-Canary-Auth-Token": "[[parameters('clientSecret')]", + "User-Agent": "Microsoft Sentinel Thinkst Canary Connector - Version 1.0", + "Accept": "application/json" + }, + "rateLimitQPS": 10, + "StartTimeAttributeName": "newer_than", + "queryTimeFormat": "yyyy-MM-dd-HH:mm:ss", + "queryWindowInMin": 5, + "retryCount": 3, + "timeoutInSeconds": 60, + "queryParameters": { + "filter_incident_state": "all", + "limit": "100" + } + }, + "response": { + "eventsJsonPaths": [ + "$.incidents" + ], + "format": "json", + "successStatusJsonPath": "$.result", + "successStatusValue": "success" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor.next", + "NextPageParaName": "cursor", + "pageSize": 100 + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','rdc','-', uniqueString(concat(variables('_solutionId'),'-','ResourcesDataConnector','-',variables('_dataConnectorContentIdConnections1'),'-', variables('dataConnectorCCPVersion'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('dataConnectorCCPVersion')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "SentinelIncidentsFromThinkstCanaryAlerts_AnalyticalRules Analytics Rule with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "apiVersion": "2023-02-01-preview", + "kind": "NRT", + "location": "[parameters('workspace-location')]", + "properties": { + "description": "Creates Microsoft Sentinel incidents from Thinkst Canary alerts.", + "displayName": "Canary alerts to incidents", + "enabled": false, + "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", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "status": "Available", + "requiredDataConnectors": [ + { + "connectorId": "ThinkstCanary", + "dataTypes": [ + "ThinkstCanaryIncidents_CL" + ] + } + ], + "tactics": [ + "LateralMovement", + "Exfiltration" + ], + "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" + }, + "customDetails": { + "TokenTarget": "TokenTarget", + "FlockName": "FlockName", + "ActorUsername": "ActorUsername", + "IncidentKey": "IncidentId", + "EventsCount": "EventsCount", + "AssetLocation": "AssetLocation", + "ActorHost": "ActorHost", + "Activity": "Activity", + "TokenMemo": "TokenMemo", + "UserAgent": "UserAgent", + "AssetType": "AssetType", + "AssetNode": "AssetNode", + "LogType": "LogType", + "ActorDomain": "ActorDomain", + "DestinationPort": "DestinationPort", + "SourceGeo": "SourceGeo", + "TokenType": "TokenType", + "AssetIP": "AssetIP", + "SourceIP": "SourceIP", + "AssetName": "AssetName" + }, + "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}}" + }, + "incidentConfiguration": { + "groupingConfiguration": { + "matchingMethod": "AllEntities", + "enabled": false, + "reopenClosedIncident": false, + "lookbackDuration": "PT5H" + }, + "createIncident": true + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject1').analyticRuleId1,'/'))))]", + "properties": { + "description": "ThinkstCanary Analytics Rule 1", + "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", + "source": { + "kind": "Solution", + "name": "ThinkstCanary", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "[variables('_email')]" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "contentKind": "AnalyticsRule", + "displayName": "Canary alerts to incidents", + "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "ThinkstCanary", + "publisherDisplayName": "Thinkst Applied Research", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

The Thinkst Canary solution for Microsoft Sentinel ingests Canary and Canarytoken incidents through the Codeless Connector Framework and provides normalized parsers, detections and response automation.

\n

Data Connectors: 1, Analytic Rules: 1

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "ThinkstCanary", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "[variables('_email')]" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "version": "[variables('dataConnectorCCPVersion')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + } + ] + }, + "firstPublishDate": "2026-08-18", + "lastPublishDate": "2026-08-18", + "providers": [ + "Thinkst Applied Research" + ], + "categories": { + "domains": [ + "Security - Threat Protection" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/ThinkstCanary/Package/testParameters.json b/Solutions/ThinkstCanary/Package/testParameters.json new file mode 100644 index 00000000000..e55ec41a9ac --- /dev/null +++ b/Solutions/ThinkstCanary/Package/testParameters.json @@ -0,0 +1,24 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + } +} diff --git a/Solutions/ThinkstCanary/ReleaseNotes.md b/Solutions/ThinkstCanary/ReleaseNotes.md new file mode 100644 index 00000000000..50004aaa390 --- /dev/null +++ b/Solutions/ThinkstCanary/ReleaseNotes.md @@ -0,0 +1,3 @@ +| Version | Date | Notes | +|---------|------|-------| +| 1.0.0 | 2026-08-18 | Initial CCF connector, parsers, ASIM mappings, analytics rules, hunting queries, workbook, and response playbooks. | diff --git a/Solutions/ThinkstCanary/SolutionMetadata.json b/Solutions/ThinkstCanary/SolutionMetadata.json new file mode 100644 index 00000000000..8f2b28a518b --- /dev/null +++ b/Solutions/ThinkstCanary/SolutionMetadata.json @@ -0,0 +1,36 @@ +{ + "version": "1.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "contentId": "thinkst-canary", + "parentId": "thinkst-canary", + "source": { + "kind": "Solution", + "name": "Thinkst Canary", + "sourceId": "thinkst-canary" + }, + "author": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools" + }, + "support": { + "name": "Thinkst Applied Research", + "email": "support@canary.tools", + "tier": "Partner", + "link": "https://help.canary.tools/" + }, + "dependencies": {}, + "firstPublishDate": "2026-08-18", + "lastPublishDate": "2026-08-18", + "providers": [ + "Thinkst Applied Research" + ], + "categories": { + "domains": [ + "Security - Threat Protection" + ], + "verticals": [] + }, + "offerId": "azure-sentinel-solution-thinkst-canary", + "publisherId": "87073660" +} From cecab39aedd674a76f102091e756629c98fb10a8 Mon Sep 17 00:00:00 2001 From: Jason Bissict Date: Mon, 24 Aug 2026 10:58:52 +0200 Subject: [PATCH 2/2] Fixes from review --- ...tinelIncidentsFromThinkstCanaryAlerts.yaml | 2 +- .../ThinkstCanary_ArmTemplate.json | 10 +++--- Solutions/ThinkstCanary/Package/3.0.0.zip | Bin 10258 -> 10313 bytes .../ThinkstCanary/Package/mainTemplate.json | 30 +++++++++++++----- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml b/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml index e93fca33c54..95ca39946dd 100644 --- a/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml +++ b/Solutions/ThinkstCanary/Analytic Rules/SentinelIncidentsFromThinkstCanaryAlerts.yaml @@ -60,7 +60,7 @@ query: | TokenHostname, ActorUsername, ActorDomain, ActorHost, SourceGeo, SourceIP, SourceDisplay, SrcHostReverse, DestinationPort, Activity, UserAgent, LogType, EventsCount, CanaryEntityName, CanaryEntityIP -suppressionDuration: 5h +suppressionDuration: 1h suppressionEnabled: false eventGroupingSettings: aggregationKind: AlertPerResult diff --git a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json index 798a0a1b356..86b81c54238 100644 --- a/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json +++ b/Solutions/ThinkstCanary/Data Connectors/ThinkstCanaryLogs_ccp/ThinkstCanary_ArmTemplate.json @@ -836,12 +836,12 @@ "location": "[parameters('workspace-location')]", "kind": "RestApiPoller", "properties": { - "connectorDefinitionName": "[[parameters('connectorDefinitionName')]", + "connectorDefinitionName": "[parameters('connectorDefinitionName')]", "dataType": "ThinkstCanaryIncidents_CL", "dcrConfig": { "streamName": "Custom-ThinkstCanaryIncidents_CL", - "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", - "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + "dataCollectionEndpoint": "[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[parameters('dcrConfig').dataCollectionRuleImmutableId]" }, "auth": { "type": "APIKey", @@ -850,10 +850,10 @@ "apiKeyName": "not_used_by_canary" }, "request": { - "apiEndpoint": "[[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", + "apiEndpoint": "[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", "httpMethod": "GET", "headers": { - "X-Canary-Auth-Token": "[[parameters('clientSecret')]", + "X-Canary-Auth-Token": "[parameters('clientSecret')]", "User-Agent": "Microsoft Sentinel Thinkst Canary Connector - Version 1.0", "Accept": "application/json" }, diff --git a/Solutions/ThinkstCanary/Package/3.0.0.zip b/Solutions/ThinkstCanary/Package/3.0.0.zip index 32ce62bb9fd2fd647d1f6230bfb5fb08d24cb8d3..d113b729c7f50a4d429bedabf323b0e46468a274 100644 GIT binary patch delta 8317 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 H00000ZOKzi delta 8261 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 DN3}VD diff --git a/Solutions/ThinkstCanary/Package/mainTemplate.json b/Solutions/ThinkstCanary/Package/mainTemplate.json index 1968dce163a..b6c87466cd5 100644 --- a/Solutions/ThinkstCanary/Package/mainTemplate.json +++ b/Solutions/ThinkstCanary/Package/mainTemplate.json @@ -33,7 +33,7 @@ "email": "support@canary.tools", "_email": "[variables('email')]", "_solutionName": "ThinkstCanary", - "_solutionVersion": "3.0.0", + "_solutionVersion": "1.0.0", "solutionId": "87073660.azure-sentinel-solution-thinkst-canary", "_solutionId": "[variables('solutionId')]", "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", @@ -236,12 +236,26 @@ } } }, + { + "name": "[parameters('workspace')]", + "apiVersion": "2024-03-11", + "type": "Microsoft.Insights/dataCollectionEndpoints", + "location": "[parameters('workspace-location')]", + "properties": { + "networkAcls": { + "publicNetworkAccess": "Enabled" + } + } + }, { "name": "ThinkstCanaryDCR", "apiVersion": "2022-06-01", "type": "Microsoft.Insights/dataCollectionRules", "location": "[parameters('workspace-location')]", "kind": "Direct", + "dependsOn": [ + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', parameters('workspace'))]" + ], "properties": { "streamDeclarations": { "Custom-ThinkstCanaryIncidents_CL": { @@ -752,7 +766,7 @@ "contentVersion": "[variables('dataConnectorCCPVersion')]", "parameters": { "guidValue": { - "defaultValue": "[[newGuid()]", + "defaultValue": "[newGuid()]", "type": "securestring" }, "innerWorkspace": { @@ -817,7 +831,7 @@ } }, { - "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'ThinkstCanaryIncidentsConnector', parameters('guidValue'))]", + "name": "[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'ThinkstCanaryIncidentsConnector', parameters('guidValue'))]", "apiVersion": "2023-02-01-preview", "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", "location": "[parameters('workspace-location')]", @@ -827,8 +841,8 @@ "dataType": "ThinkstCanaryIncidents_CL", "dcrConfig": { "streamName": "Custom-ThinkstCanaryIncidents_CL", - "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", - "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + "dataCollectionEndpoint": "[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[parameters('dcrConfig').dataCollectionRuleImmutableId]" }, "auth": { "type": "APIKey", @@ -837,10 +851,10 @@ "apiKeyName": "not_used_by_canary" }, "request": { - "apiEndpoint": "[[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", + "apiEndpoint": "[concat('https://',parameters('clientId'),'.canary.tools/api/v1/incidents/search')]", "httpMethod": "GET", "headers": { - "X-Canary-Auth-Token": "[[parameters('clientSecret')]", + "X-Canary-Auth-Token": "[parameters('clientSecret')]", "User-Agent": "Microsoft Sentinel Thinkst Canary Connector - Version 1.0", "Accept": "application/json" }, @@ -1059,7 +1073,7 @@ "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.0.0", + "version": "1.0.0", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "ThinkstCanary",