diff --git a/.script/tests/KqlvalidationsTests/CustomFunctions/get_Spycloud_enriched_data.json b/.script/tests/KqlvalidationsTests/CustomFunctions/get_Spycloud_enriched_data.json new file mode 100644 index 00000000000..70b74086e05 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomFunctions/get_Spycloud_enriched_data.json @@ -0,0 +1,315 @@ +{ + "FunctionName": "get_Spycloud_enriched_data", + "FunctionParameters": [ + { + "Name": "lookback", + "Type": "timespan" + } + ], + "FunctionResultColumns": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "SourceId", + "Type": "Int" + }, + { + "Name": "InfectedPath", + "Type": "String" + }, + { + "Name": "UserHostName", + "Type": "String" + }, + { + "Name": "IPAddresses", + "Type": "Dynamic" + }, + { + "Name": "TimeZone", + "Type": "String" + }, + { + "Name": "TargetUrl", + "Type": "String" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "TargetDomain", + "Type": "String" + }, + { + "Name": "UserSysRegisteredOwner", + "Type": "String" + }, + { + "Name": "DisplayResolution", + "Type": "String" + }, + { + "Name": "Password", + "Type": "String" + }, + { + "Name": "Email", + "Type": "String" + }, + { + "Name": "Severity", + "Type": "Int" + }, + { + "Name": "AVSoftwares", + "Type": "Dynamic" + }, + { + "Name": "LogId", + "Type": "String" + }, + { + "Name": "UserOS", + "Type": "String" + }, + { + "Name": "EmailUsername", + "Type": "String" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "String" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "PasswordPlaintext", + "Type": "String" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "CountryCode", + "Type": "String" + }, + { + "Name": "KeyboardLanguages", + "Type": "String" + }, + { + "Name": "PasswordType", + "Type": "String" + }, + { + "Name": "Domain", + "Type": "String" + }, + { + "Name": "EmailDomain", + "Type": "String" + }, + { + "Name": "TargetSubdomain", + "Type": "String" + }, + { + "Name": "Sighting", + "Type": "Int" + }, + { + "Name": "AccountLastActivityTime", + "Type": "String" + }, + { + "Name": "AccountNotes", + "Type": "String" + }, + { + "Name": "AccountSignupTime", + "Type": "String" + }, + { + "Name": "Username", + "Type": "String" + }, + { + "Name": "Homepage", + "Type": "String" + }, + { + "Name": "Salt", + "Type": "String" + }, + { + "Name": "AccountLoginTime", + "Type": "String" + }, + { + "Name": "SocialOther", + "Type": "Dynamic" + }, + { + "Name": "LastName", + "Type": "String" + }, + { + "Name": "FullName", + "Type": "String" + }, + { + "Name": "Phone", + "Type": "String" + }, + { + "Name": "FirstName", + "Type": "String" + }, + { + "Name": "Address1", + "Type": "String" + }, + { + "Name": "AccountModificationTime", + "Type": "String" + }, + { + "Name": "Gender", + "Type": "String" + }, + { + "Name": "City", + "Type": "String" + }, + { + "Name": "BirthYear", + "Type": "String" + }, + { + "Name": "DOB", + "Type": "String" + }, + { + "Name": "CompanyWebsite", + "Type": "String" + }, + { + "Name": "Industry", + "Type": "String" + }, + { + "Name": "AccountStatus", + "Type": "String" + }, + { + "Name": "SocialCrunchbase", + "Type": "Dynamic" + }, + { + "Name": "CompanyName", + "Type": "String" + }, + { + "Name": "SocialLinkedIn", + "Type": "Dynamic" + }, + { + "Name": "SocialTwitter", + "Type": "Dynamic" + }, + { + "Name": "AccountCaption", + "Type": "String" + }, + { + "Name": "Address2", + "Type": "String" + }, + { + "Name": "SSNLastFour", + "Type": "String" + }, + { + "Name": "SocialSecurityNumber", + "Type": "String" + }, + { + "Name": "HealthInsuranceId", + "Type": "String" + }, + { + "Name": "PostalCode", + "Type": "String" + }, + { + "Name": "Age", + "Type": "String" + }, + { + "Name": "TaxId", + "Type": "String" + }, + { + "Name": "State", + "Type": "String" + }, + { + "Name": "AccountType", + "Type": "String" + }, + { + "Name": "DeviceName", + "Type": "Dynamic" + }, + { + "Name": "BankNumber", + "Type": "String" + }, + { + "Name": "MobileEquipmentId", + "Type": "String" + }, + { + "Name": "Country", + "Type": "String" + }, + { + "Name": "EducationalInstitution", + "Type": "String" + }, + { + "Name": "JobTitle", + "Type": "String" + }, + { + "Name": "AccountImageUrl", + "Type": "String" + }, + { + "Name": "StudentId", + "Type": "String" + }, + { + "Name": "AccountId", + "Type": "String" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "CatalogDescription", + "Type": "String" + }, + { + "Name": "CatalogStatus", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomFunctions/get_spycloud_compass_data.json b/.script/tests/KqlvalidationsTests/CustomFunctions/get_spycloud_compass_data.json new file mode 100644 index 00000000000..c9265b742e8 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomFunctions/get_spycloud_compass_data.json @@ -0,0 +1,67 @@ +{ + "FunctionName": "get_spycloud_compass_data", + "FunctionParameters": [ + { + "Name": "startTime", + "Type": "timespan" + } + ], + "FunctionResultColumns": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "SourceId", + "Type": "Int" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "String" + }, + { + "Name": "Email", + "Type": "String" + }, + { + "Name": "Domain", + "Type": "String" + }, + { + "Name": "Password", + "Type": "String" + }, + { + "Name": "PasswordPlaintext", + "Type": "String" + }, + { + "Name": "Severity", + "Type": "Int" + }, + { + "Name": "IPAddresses", + "Type": "Dynamic" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "BreachCategory", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachCatalogV2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachCatalogV2_CL.json new file mode 100644 index 00000000000..8314d11b5fc --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachCatalogV2_CL.json @@ -0,0 +1,25 @@ +{ + "Name": "SpyCloudBreachCatalogV2_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "SourceId", + "Type": "Int" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "Description", + "Type": "String" + }, + { + "Name": "Status", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachWatchlistV2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachWatchlistV2_CL.json new file mode 100644 index 00000000000..1a6bafb092f --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloudBreachWatchlistV2_CL.json @@ -0,0 +1,297 @@ +{ + "Name": "SpyCloudBreachWatchlistV2_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "InfectedPath", + "Type": "String" + }, + { + "Name": "UserHostName", + "Type": "String" + }, + { + "Name": "IPAddresses", + "Type": "Dynamic" + }, + { + "Name": "TimeZone", + "Type": "String" + }, + { + "Name": "TargetUrl", + "Type": "String" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "TargetDomain", + "Type": "String" + }, + { + "Name": "UserSysRegisteredOwner", + "Type": "String" + }, + { + "Name": "DisplayResolution", + "Type": "String" + }, + { + "Name": "Password", + "Type": "String" + }, + { + "Name": "Email", + "Type": "String" + }, + { + "Name": "Severity", + "Type": "Int" + }, + { + "Name": "AVSoftwares", + "Type": "Dynamic" + }, + { + "Name": "LogId", + "Type": "String" + }, + { + "Name": "UserOS", + "Type": "String" + }, + { + "Name": "EmailUsername", + "Type": "String" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "String" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "PasswordPlaintext", + "Type": "String" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "CountryCode", + "Type": "String" + }, + { + "Name": "KeyboardLanguages", + "Type": "String" + }, + { + "Name": "PasswordType", + "Type": "String" + }, + { + "Name": "Domain", + "Type": "String" + }, + { + "Name": "EmailDomain", + "Type": "String" + }, + { + "Name": "SourceId", + "Type": "Int" + }, + { + "Name": "TargetSubdomain", + "Type": "String" + }, + { + "Name": "Sighting", + "Type": "Int" + }, + { + "Name": "AccountLastActivityTime", + "Type": "String" + }, + { + "Name": "AccountNotes", + "Type": "String" + }, + { + "Name": "AccountSignupTime", + "Type": "String" + }, + { + "Name": "Username", + "Type": "String" + }, + { + "Name": "Homepage", + "Type": "String" + }, + { + "Name": "Salt", + "Type": "String" + }, + { + "Name": "AccountLoginTime", + "Type": "String" + }, + { + "Name": "SocialOther", + "Type": "Dynamic" + }, + { + "Name": "LastName", + "Type": "String" + }, + { + "Name": "FullName", + "Type": "String" + }, + { + "Name": "Phone", + "Type": "String" + }, + { + "Name": "FirstName", + "Type": "String" + }, + { + "Name": "Address1", + "Type": "String" + }, + { + "Name": "AccountModificationTime", + "Type": "String" + }, + { + "Name": "Gender", + "Type": "String" + }, + { + "Name": "City", + "Type": "String" + }, + { + "Name": "BirthYear", + "Type": "String" + }, + { + "Name": "DOB", + "Type": "String" + }, + { + "Name": "CompanyWebsite", + "Type": "String" + }, + { + "Name": "Industry", + "Type": "String" + }, + { + "Name": "AccountStatus", + "Type": "String" + }, + { + "Name": "SocialCrunchbase", + "Type": "Dynamic" + }, + { + "Name": "CompanyName", + "Type": "String" + }, + { + "Name": "SocialLinkedIn", + "Type": "Dynamic" + }, + { + "Name": "SocialTwitter", + "Type": "Dynamic" + }, + { + "Name": "AccountCaption", + "Type": "String" + }, + { + "Name": "Address2", + "Type": "String" + }, + { + "Name": "SSNLastFour", + "Type": "String" + }, + { + "Name": "SocialSecurityNumber", + "Type": "String" + }, + { + "Name": "HealthInsuranceId", + "Type": "String" + }, + { + "Name": "PostalCode", + "Type": "String" + }, + { + "Name": "Age", + "Type": "String" + }, + { + "Name": "TaxId", + "Type": "String" + }, + { + "Name": "State", + "Type": "String" + }, + { + "Name": "AccountType", + "Type": "String" + }, + { + "Name": "DeviceName", + "Type": "Dynamic" + }, + { + "Name": "BankNumber", + "Type": "String" + }, + { + "Name": "MobileEquipmentId", + "Type": "String" + }, + { + "Name": "Country", + "Type": "String" + }, + { + "Name": "EducationalInstitution", + "Type": "String" + }, + { + "Name": "JobTitle", + "Type": "String" + }, + { + "Name": "AccountImageUrl", + "Type": "String" + }, + { + "Name": "StudentId", + "Type": "String" + }, + { + "Name": "AccountId", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/SpyCloud_ConditionalAccessLogsV2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloud_ConditionalAccessLogsV2_CL.json new file mode 100644 index 00000000000..35bdc72701a --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/SpyCloud_ConditionalAccessLogsV2_CL.json @@ -0,0 +1,61 @@ +{ + "Name": "SpyCloud_ConditionalAccessLogsV2_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "IncidentId", + "Type": "String" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "DateTime" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "Username", + "Type": "String" + }, + { + "Name": "UserEmail", + "Type": "String" + }, + { + "Name": "ForcedPasswordResetOnNextSignIn", + "Type": "Boolean" + }, + { + "Name": "UserSessionsRevoked", + "Type": "Boolean" + }, + { + "Name": "CAgroup", + "Type": "Boolean" + }, + { + "Name": "UserDisabled", + "Type": "Boolean" + }, + { + "Name": "PlaybookName", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/Spycloud_MDE_LogsV2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/Spycloud_MDE_LogsV2_CL.json new file mode 100644 index 00000000000..ea743cc70ce --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/Spycloud_MDE_LogsV2_CL.json @@ -0,0 +1,81 @@ +{ + "Name": "Spycloud_MDE_LogsV2_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "IncidentId", + "Type": "String" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "DateTime" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "HostName", + "Type": "String" + }, + { + "Name": "NormalizedHostName", + "Type": "String" + }, + { + "Name": "DeviceId", + "Type": "String" + }, + { + "Name": "OSPlatform", + "Type": "String" + }, + { + "Name": "RiskScore", + "Type": "String" + }, + { + "Name": "ExposureLevel", + "Type": "String" + }, + { + "Name": "IsolationRequested", + "Type": "Boolean" + }, + { + "Name": "IsolationStatus", + "Type": "Boolean" + }, + { + "Name": "MachineTagAdded", + "Type": "Boolean" + }, + { + "Name": "MachineTagName", + "Type": "String" + }, + { + "Name": "AddedIOCsToDefender", + "Type": "Boolean" + }, + { + "Name": "PlaybookName", + "Type": "String" + } + ] +} diff --git a/.script/tests/KqlvalidationsTests/CustomTables/spycloud_compassV2_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/spycloud_compassV2_CL.json new file mode 100644 index 00000000000..3460e46f8c7 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/spycloud_compassV2_CL.json @@ -0,0 +1,117 @@ +{ + "Name": "spycloud_compassV2_CL", + "Properties": [ + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "SourceId", + "Type": "Int" + }, + { + "Name": "DocumentId", + "Type": "String" + }, + { + "Name": "LogId", + "Type": "String" + }, + { + "Name": "Severity", + "Type": "Int" + }, + { + "Name": "Email", + "Type": "String" + }, + { + "Name": "EmailDomain", + "Type": "String" + }, + { + "Name": "EmailUsername", + "Type": "String" + }, + { + "Name": "Password", + "Type": "String" + }, + { + "Name": "PasswordType", + "Type": "String" + }, + { + "Name": "PasswordPlaintext", + "Type": "String" + }, + { + "Name": "TargetUrl", + "Type": "String" + }, + { + "Name": "TargetDomain", + "Type": "String" + }, + { + "Name": "TargetSubdomain", + "Type": "String" + }, + { + "Name": "InfectedMachineId", + "Type": "String" + }, + { + "Name": "InfectedTime", + "Type": "String" + }, + { + "Name": "InfectedPath", + "Type": "String" + }, + { + "Name": "UserOS", + "Type": "String" + }, + { + "Name": "UserSysRegisteredOwner", + "Type": "String" + }, + { + "Name": "AVSoftwares", + "Type": "Dynamic" + }, + { + "Name": "CountryCode", + "Type": "String" + }, + { + "Name": "DisplayResolution", + "Type": "String" + }, + { + "Name": "IPAddresses", + "Type": "Dynamic" + }, + { + "Name": "TimeZone", + "Type": "String" + }, + { + "Name": "Domain", + "Type": "String" + }, + { + "Name": "SpyCloudPublishDate", + "Type": "String" + }, + { + "Name": "BreachTitle", + "Type": "String" + }, + { + "Name": "BreachCategory", + "Type": "String" + } + ] +} diff --git a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json index c7d6dc90898..23a6b5d38f8 100644 --- a/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json +++ b/.script/tests/detectionTemplateSchemaValidation/ValidConnectorIds.json @@ -190,6 +190,7 @@ "SophosCloudOptix", "SophosXGFirewall", "StealthTalkAnomalousAuth", + "SpyCloudEnterpriseProtectionCCF", "SquadraTechnologiesSecRmm", "SquidProxy", "Symantec", diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_Breached_Users_20.yaml b/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_Breached_Users_20.yaml new file mode 100644 index 00000000000..14b0d3d909e --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_Breached_Users_20.yaml @@ -0,0 +1,44 @@ +id: a25eba0e-ff42-4c97-a379-d76bdb2aa1e3 +name: SpyCloud plaintext credential exposure detected +description: | + 'Identifies user accounts exposed with a plaintext password in a third-party data breach. + Unremediated exposures of this kind can lead directly to account takeover.' +severity: High +requiredDataConnectors: + - connectorId: SpyCloudEnterpriseProtectionCCF + dataTypes: + - SpyCloudBreachWatchlistV2_CL +queryFrequency: 1h +queryPeriod: 2d +triggerOperator: gt +triggerThreshold: 0 +tactics: + - Collection +relevantTechniques: + - T1589.001 +query: | + // Human-readable constant for the severity threshold used below + let severityThreshold = 20; + SpyCloudBreachWatchlistV2_CL + | where Severity == severityThreshold + | mv-expand IPAddress = IPAddresses to typeof(string) + | extend AccountName = Username, AccountEmail = Email + | project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail, + TargetDomain, PasswordPlaintext, AccountName, IPAddress +eventGroupingSettings: + aggregationKind: SingleAlert +entityMappings: + - entityType: Account + fieldMappings: + - identifier: Name + columnName: AccountName + - entityType: IP + fieldMappings: + - identifier: Address + columnName: IPAddress + - entityType: Mailbox + fieldMappings: + - identifier: MailboxPrimaryAddress + columnName: AccountEmail +version: 1.0.0 +kind: scheduled diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_malware_25.yaml b/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_malware_25.yaml new file mode 100644 index 00000000000..6e84a82afd5 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Analytic Rules/AR_malware_25.yaml @@ -0,0 +1,47 @@ +id: ead4deed-9d48-4646-aee0-6b46c2dd1ae6 +name: SpyCloud infostealer malware credential exposure +description: | + 'Identifies credentials harvested by infostealer malware on a compromised device. This + exposure may indicate an actively compromised endpoint with associated command-and-control + risk.' +severity: High +requiredDataConnectors: + - connectorId: SpyCloudEnterpriseProtectionCCF + dataTypes: + - SpyCloudBreachWatchlistV2_CL +queryFrequency: 1h +queryPeriod: 1d +triggerOperator: gt +triggerThreshold: 0 +tactics: + - CredentialAccess + - CommandAndControl +relevantTechniques: + - T1555 + - T1071 +query: | + // Human-readable constant for the severity threshold used below + let severityThreshold = 25; + SpyCloudBreachWatchlistV2_CL + | where Severity == severityThreshold + | mv-expand IPAddress = IPAddresses to typeof(string) + | extend AccountName = Username, AccountEmail = Email, HostName = UserHostName + | project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail, + AccountName, HostName, InfectedMachineId, InfectedTime, UserOS, IPAddress +eventGroupingSettings: + aggregationKind: SingleAlert +entityMappings: + - entityType: Account + fieldMappings: + - identifier: Name + columnName: AccountName + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: HostName + - entityType: IP + fieldMappings: + - identifier: Address + columnName: IPAddress +version: 1.0.0 +kind: scheduled diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_DCR.json b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_DCR.json new file mode 100644 index 00000000000..2a23ebc7eb1 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_DCR.json @@ -0,0 +1,637 @@ +[ + { + "name": "SpyCloudwatchlist-DCR", + "apiVersion": "2021-09-01-preview", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "{{location}}", + "properties": { + "dataCollectionEndpointId": "{{dataCollectionEndpointId}}", + "streamDeclarations": { + "Custom-SpyCloudBreachWatchlistV2_CL": { + "columns": [ + { + "name": "infected_path", + "type": "string" + }, + { + "name": "user_hostname", + "type": "string" + }, + { + "name": "ip_addresses", + "type": "dynamic" + }, + { + "name": "timezone", + "type": "string" + }, + { + "name": "target_url", + "type": "string" + }, + { + "name": "document_id", + "type": "string" + }, + { + "name": "target_domain", + "type": "string" + }, + { + "name": "user_sys_registered_owner", + "type": "string" + }, + { + "name": "display_resolution", + "type": "string" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "severity", + "type": "int" + }, + { + "name": "av_softwares", + "type": "dynamic" + }, + { + "name": "log_id", + "type": "string" + }, + { + "name": "user_os", + "type": "string" + }, + { + "name": "email_username", + "type": "string" + }, + { + "name": "spycloud_publish_date", + "type": "string" + }, + { + "name": "infected_machine_id", + "type": "string" + }, + { + "name": "password_plaintext", + "type": "string" + }, + { + "name": "infected_time", + "type": "string" + }, + { + "name": "country_code", + "type": "string" + }, + { + "name": "keyboard_languages", + "type": "string" + }, + { + "name": "password_type", + "type": "string" + }, + { + "name": "domain", + "type": "string" + }, + { + "name": "email_domain", + "type": "string" + }, + { + "name": "source_id", + "type": "int" + }, + { + "name": "target_subdomain", + "type": "string" + }, + { + "name": "sighting", + "type": "int" + }, + { + "name": "account_last_activity_time", + "type": "string" + }, + { + "name": "account_notes", + "type": "string" + }, + { + "name": "account_signup_time", + "type": "string" + }, + { + "name": "username", + "type": "string" + }, + { + "name": "homepage", + "type": "string" + }, + { + "name": "salt", + "type": "string" + }, + { + "name": "account_login_time", + "type": "string" + }, + { + "name": "social_other", + "type": "dynamic" + }, + { + "name": "last_name", + "type": "string" + }, + { + "name": "full_name", + "type": "string" + }, + { + "name": "phone", + "type": "string" + }, + { + "name": "first_name", + "type": "string" + }, + { + "name": "address_1", + "type": "string" + }, + { + "name": "account_modification_time", + "type": "string" + }, + { + "name": "gender", + "type": "string" + }, + { + "name": "city", + "type": "string" + }, + { + "name": "birth_year", + "type": "string" + }, + { + "name": "dob", + "type": "string" + }, + { + "name": "company_website", + "type": "string" + }, + { + "name": "industry", + "type": "string" + }, + { + "name": "account_status", + "type": "string" + }, + { + "name": "social_crunchbase", + "type": "dynamic" + }, + { + "name": "company_name", + "type": "string" + }, + { + "name": "social_linkedin", + "type": "dynamic" + }, + { + "name": "social_twitter", + "type": "dynamic" + }, + { + "name": "account_caption", + "type": "string" + }, + { + "name": "address_2", + "type": "string" + }, + { + "name": "ssn_last_four", + "type": "string" + }, + { + "name": "social_security_number", + "type": "string" + }, + { + "name": "health_insurance_id", + "type": "string" + }, + { + "name": "postal_code", + "type": "string" + }, + { + "name": "age", + "type": "string" + }, + { + "name": "taxid", + "type": "string" + }, + { + "name": "state", + "type": "string" + }, + { + "name": "account_type", + "type": "string" + }, + { + "name": "device_name", + "type": "dynamic" + }, + { + "name": "bank_number", + "type": "string" + }, + { + "name": "mobile_equipment_id", + "type": "string" + }, + { + "name": "country", + "type": "string" + }, + { + "name": "educational_institution", + "type": "string" + }, + { + "name": "job_title", + "type": "string" + }, + { + "name": "account_image_url", + "type": "string" + }, + { + "name": "student_id", + "type": "string" + }, + { + "name": "account_id", + "type": "string" + } + ] + }, + "Custom-SpyCloudBreachCatalogV2_CL": { + "columns": [ + { + "name": "id", + "type": "int" + }, + { + "name": "title", + "type": "string" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "status", + "type": "string" + } + ] + }, + "Custom-spycloud_compassV2_CL": { + "columns": [ + { + "name": "source_id", + "type": "int" + }, + { + "name": "document_id", + "type": "string" + }, + { + "name": "log_id", + "type": "string" + }, + { + "name": "severity", + "type": "int" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "email_domain", + "type": "string" + }, + { + "name": "email_username", + "type": "string" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "password_type", + "type": "string" + }, + { + "name": "password_plaintext", + "type": "string" + }, + { + "name": "target_url", + "type": "string" + }, + { + "name": "target_domain", + "type": "string" + }, + { + "name": "target_subdomain", + "type": "string" + }, + { + "name": "infected_machine_id", + "type": "string" + }, + { + "name": "infected_time", + "type": "string" + }, + { + "name": "infected_path", + "type": "string" + }, + { + "name": "user_os", + "type": "string" + }, + { + "name": "user_sys_registered_owner", + "type": "string" + }, + { + "name": "av_softwares", + "type": "dynamic" + }, + { + "name": "country_code", + "type": "string" + }, + { + "name": "display_resolution", + "type": "string" + }, + { + "name": "ip_addresses", + "type": "dynamic" + }, + { + "name": "timezone", + "type": "string" + }, + { + "name": "domain", + "type": "string" + }, + { + "name": "spycloud_publish_date", + "type": "string" + }, + { + "name": "breach_title", + "type": "string" + }, + { + "name": "breach_category", + "type": "string" + } + ] + }, + "Custom-Spycloud_MDE_LogsV2_CL": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "HostName", + "type": "string" + }, + { + "name": "NormalizedHostName", + "type": "string" + }, + { + "name": "DeviceId", + "type": "string" + }, + { + "name": "OSPlatform", + "type": "string" + }, + { + "name": "RiskScore", + "type": "string" + }, + { + "name": "ExposureLevel", + "type": "string" + }, + { + "name": "IsolationRequested", + "type": "boolean" + }, + { + "name": "IsolationStatus", + "type": "boolean" + }, + { + "name": "MachineTagAdded", + "type": "boolean" + }, + { + "name": "MachineTagName", + "type": "string" + }, + { + "name": "AddedIOCsToDefender", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + }, + "Custom-SpyCloud_ConditionalAccessLogsV2_CL": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "UserEmail", + "type": "string" + }, + { + "name": "ForcedPasswordResetOnNextSignIn", + "type": "boolean" + }, + { + "name": "UserSessionsRevoked", + "type": "boolean" + }, + { + "name": "CAgroup", + "type": "boolean" + }, + { + "name": "UserDisabled", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "{{workspaceResourceId}}", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-SpyCloudBreachWatchlistV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename InfectedPath = infected_path, UserHostName = user_hostname, IPAddresses = ip_addresses, TimeZone = timezone, TargetUrl = target_url, DocumentId = document_id, TargetDomain = target_domain, UserSysRegisteredOwner = user_sys_registered_owner, DisplayResolution = display_resolution, Password = password, Email = email, Severity = severity, AVSoftwares = av_softwares, LogId = log_id, UserOS = user_os, EmailUsername = email_username, SpyCloudPublishDate = spycloud_publish_date, InfectedMachineId = infected_machine_id, PasswordPlaintext = password_plaintext, InfectedTime = infected_time, CountryCode = country_code, KeyboardLanguages = keyboard_languages, PasswordType = password_type, Domain = domain, EmailDomain = email_domain, SourceId = source_id, TargetSubdomain = target_subdomain, Sighting = sighting, AccountLastActivityTime = account_last_activity_time, AccountNotes = account_notes, AccountSignupTime = account_signup_time, Username = username, Homepage = homepage, Salt = salt, AccountLoginTime = account_login_time, SocialOther = social_other, LastName = last_name, FullName = full_name, Phone = phone, FirstName = first_name, Address1 = address_1, AccountModificationTime = account_modification_time, Gender = gender, City = city, BirthYear = birth_year, DOB = dob, CompanyWebsite = company_website, Industry = industry, AccountStatus = account_status, SocialCrunchbase = social_crunchbase, CompanyName = company_name, SocialLinkedIn = social_linkedin, SocialTwitter = social_twitter, AccountCaption = account_caption, Address2 = address_2, SSNLastFour = ssn_last_four, SocialSecurityNumber = social_security_number, HealthInsuranceId = health_insurance_id, PostalCode = postal_code, Age = age, TaxId = taxid, State = state, AccountType = account_type, DeviceName = device_name, BankNumber = bank_number, MobileEquipmentId = mobile_equipment_id, Country = country, EducationalInstitution = educational_institution, JobTitle = job_title, AccountImageUrl = account_image_url, StudentId = student_id, AccountId = account_id\n", + "outputStream": "Custom-SpyCloudBreachWatchlistV2_CL" + }, + { + "streams": [ + "Custom-SpyCloudBreachCatalogV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename SourceId = id, BreachTitle = title, Description = description, Status = status\n| project TimeGenerated, SourceId, BreachTitle, Description, Status\n", + "outputStream": "Custom-SpyCloudBreachCatalogV2_CL" + }, + { + "streams": [ + "Custom-spycloud_compassV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename SourceId = source_id, DocumentId = document_id, LogId = log_id, Severity = severity, Email = email, EmailDomain = email_domain, EmailUsername = email_username, Password = password, PasswordType = password_type, PasswordPlaintext = password_plaintext, TargetUrl = target_url, TargetDomain = target_domain, TargetSubdomain = target_subdomain, InfectedMachineId = infected_machine_id, InfectedTime = infected_time, InfectedPath = infected_path, UserOS = user_os, UserSysRegisteredOwner = user_sys_registered_owner, AVSoftwares = av_softwares, CountryCode = country_code, DisplayResolution = display_resolution, IPAddresses = ip_addresses, TimeZone = timezone, Domain = domain, SpyCloudPublishDate = spycloud_publish_date, BreachTitle = breach_title, BreachCategory = breach_category\n", + "outputStream": "Custom-spycloud_compassV2_CL" + }, + { + "streams": [ + "Custom-Spycloud_MDE_LogsV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend\n TimeGenerated = todatetime(TimeGenerated),\n IncidentId = tostring(IncidentId),\n DocumentId = tostring(DocumentId),\n SpyCloudPublishDate = todatetime(SpyCloudPublishDate),\n InfectedTime = tostring(InfectedTime),\n BreachTitle = tostring(BreachTitle),\n InfectedMachineId = tostring(InfectedMachineId),\n HostName = tostring(HostName),\n NormalizedHostName = tostring(NormalizedHostName),\n DeviceId = tostring(DeviceId),\n OSPlatform = tostring(OSPlatform),\n RiskScore = tostring(RiskScore),\n ExposureLevel = tostring(ExposureLevel),\n IsolationRequested = tobool(IsolationRequested),\n IsolationStatus = tobool(IsolationStatus),\n MachineTagAdded = tobool(MachineTagAdded),\n MachineTagName = tostring(MachineTagName),\n AddedIOCsToDefender = tobool(AddedIOCsToDefender),\n PlaybookName = tostring(PlaybookName)\n| project\n TimeGenerated,\n IncidentId,\n DocumentId,\n SpyCloudPublishDate,\n InfectedTime,\n BreachTitle,\n InfectedMachineId,\n HostName,\n NormalizedHostName,\n DeviceId,\n OSPlatform,\n RiskScore,\n ExposureLevel,\n IsolationRequested,\n IsolationStatus,\n MachineTagAdded,\n MachineTagName,\n AddedIOCsToDefender,\n PlaybookName\n", + "outputStream": "Custom-Spycloud_MDE_LogsV2_CL" + }, + { + "streams": [ + "Custom-SpyCloud_ConditionalAccessLogsV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend\n TimeGenerated = todatetime(TimeGenerated),\n IncidentId = tostring(IncidentId),\n DocumentId = tostring(DocumentId),\n SpyCloudPublishDate = todatetime(SpyCloudPublishDate),\n InfectedTime = tostring(InfectedTime),\n BreachTitle = tostring(BreachTitle),\n InfectedMachineId = tostring(InfectedMachineId),\n Username = tostring(Username),\n UserEmail = tostring(UserEmail),\n ForcedPasswordResetOnNextSignIn = tobool(ForcedPasswordResetOnNextSignIn),\n UserSessionsRevoked = tobool(UserSessionsRevoked),\n CAgroup = tobool(CAgroup),\n UserDisabled = tobool(UserDisabled),\n PlaybookName = tostring(PlaybookName)\n| project\n TimeGenerated,\n IncidentId,\n DocumentId,\n SpyCloudPublishDate,\n InfectedTime,\n BreachTitle,\n InfectedMachineId,\n Username,\n UserEmail,\n ForcedPasswordResetOnNextSignIn,\n UserSessionsRevoked,\n CAgroup,\n UserDisabled,\n PlaybookName\n", + "outputStream": "Custom-SpyCloud_ConditionalAccessLogsV2_CL" + } + ] + } + } +] \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_PollerConfig.json b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_PollerConfig.json new file mode 100644 index 00000000000..b37c3e0871e --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_PollerConfig.json @@ -0,0 +1,246 @@ +[ + { + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "SpyCloudWatchlistConnector", + "kind": "RestApiPoller", + "location": "{{location}}", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "{{apiKey}}" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/watchlist", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-ddTHH:mm:ssZ", + "startTimeAttributeName": "since", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "severity": "{{severity}}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "SpyCloudWatchlistConnectorModified", + "kind": "RestApiPoller", + "location": "{{location}}", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "{{apiKey}}" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/watchlist", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-dd", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "since_modification_date": "{_QueryWindowStartTime}", + "until_modification_date": "{_QueryWindowStartTime}", + "severity": "{{severity}}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "SpyCloudUsernameConnector", + "kind": "RestApiPoller", + "location": "{{location}}", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "{{apiKey}}" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/usernames/username", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-dd", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "since_modification_date": "{_QueryWindowStartTime}", + "until_modification_date": "{_QueryWindowStartTime}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "SpyCloudBreachCatalogConnector", + "kind": "RestApiPoller", + "location": "{{location}}", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachCatalogV2_CL" + }, + "dataType": "SpyCloudBreachCatalogV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "{{apiKey}}" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/catalog", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-ddTHH:mm:ssZ", + "startTimeAttributeName": "since", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "condition": "[[equals(parameters('compassEnabled'),'true')]", + "type": "Microsoft.SecurityInsights/dataConnectors", + "apiVersion": "2023-02-01-preview", + "name": "SpyCloudCompassConnector", + "kind": "RestApiPoller", + "location": "{{location}}", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-spycloud_compassV2_CL" + }, + "dataType": "spycloud_compassV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "{{apiKey}}" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/compass/data", + "httpMethod": "GET", + "rateLimitQPS": 1, + "queryTimeFormat": "yyyy-MM-dd", + "startTimeAttributeName": "since", + "queryWindowInMin": 1440, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "until": "{_QueryWindowStartTime}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + } +] \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_Tables.json b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_Tables.json new file mode 100644 index 00000000000..ef84ec3ef6b --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_Tables.json @@ -0,0 +1,618 @@ +[ + { + "name": "SpyCloudBreachWatchlistV2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "properties": { + "schema": { + "name": "SpyCloudBreachWatchlistV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "InfectedPath", + "type": "string" + }, + { + "name": "UserHostName", + "type": "string" + }, + { + "name": "IPAddresses", + "type": "dynamic" + }, + { + "name": "TimeZone", + "type": "string" + }, + { + "name": "TargetUrl", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "TargetDomain", + "type": "string" + }, + { + "name": "UserSysRegisteredOwner", + "type": "string" + }, + { + "name": "DisplayResolution", + "type": "string" + }, + { + "name": "Password", + "type": "string" + }, + { + "name": "Email", + "type": "string" + }, + { + "name": "Severity", + "type": "int" + }, + { + "name": "AVSoftwares", + "type": "dynamic" + }, + { + "name": "LogId", + "type": "string" + }, + { + "name": "UserOS", + "type": "string" + }, + { + "name": "EmailUsername", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "PasswordPlaintext", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "CountryCode", + "type": "string" + }, + { + "name": "KeyboardLanguages", + "type": "string" + }, + { + "name": "PasswordType", + "type": "string" + }, + { + "name": "Domain", + "type": "string" + }, + { + "name": "EmailDomain", + "type": "string" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "TargetSubdomain", + "type": "string" + }, + { + "name": "Sighting", + "type": "int" + }, + { + "name": "AccountLastActivityTime", + "type": "string" + }, + { + "name": "AccountNotes", + "type": "string" + }, + { + "name": "AccountSignupTime", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "Homepage", + "type": "string" + }, + { + "name": "Salt", + "type": "string" + }, + { + "name": "AccountLoginTime", + "type": "string" + }, + { + "name": "SocialOther", + "type": "dynamic" + }, + { + "name": "LastName", + "type": "string" + }, + { + "name": "FullName", + "type": "string" + }, + { + "name": "Phone", + "type": "string" + }, + { + "name": "FirstName", + "type": "string" + }, + { + "name": "Address1", + "type": "string" + }, + { + "name": "AccountModificationTime", + "type": "string" + }, + { + "name": "Gender", + "type": "string" + }, + { + "name": "City", + "type": "string" + }, + { + "name": "BirthYear", + "type": "string" + }, + { + "name": "DOB", + "type": "string" + }, + { + "name": "CompanyWebsite", + "type": "string" + }, + { + "name": "Industry", + "type": "string" + }, + { + "name": "AccountStatus", + "type": "string" + }, + { + "name": "SocialCrunchbase", + "type": "dynamic" + }, + { + "name": "CompanyName", + "type": "string" + }, + { + "name": "SocialLinkedIn", + "type": "dynamic" + }, + { + "name": "SocialTwitter", + "type": "dynamic" + }, + { + "name": "AccountCaption", + "type": "string" + }, + { + "name": "Address2", + "type": "string" + }, + { + "name": "SSNLastFour", + "type": "string" + }, + { + "name": "SocialSecurityNumber", + "type": "string" + }, + { + "name": "HealthInsuranceId", + "type": "string" + }, + { + "name": "PostalCode", + "type": "string" + }, + { + "name": "Age", + "type": "string" + }, + { + "name": "TaxId", + "type": "string" + }, + { + "name": "State", + "type": "string" + }, + { + "name": "AccountType", + "type": "string" + }, + { + "name": "DeviceName", + "type": "dynamic" + }, + { + "name": "BankNumber", + "type": "string" + }, + { + "name": "MobileEquipmentId", + "type": "string" + }, + { + "name": "Country", + "type": "string" + }, + { + "name": "EducationalInstitution", + "type": "string" + }, + { + "name": "JobTitle", + "type": "string" + }, + { + "name": "AccountImageUrl", + "type": "string" + }, + { + "name": "StudentId", + "type": "string" + }, + { + "name": "AccountId", + "type": "string" + } + ] + } + } + }, + { + "name": "SpyCloudBreachCatalogV2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "properties": { + "schema": { + "name": "SpyCloudBreachCatalogV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "Description", + "type": "string" + }, + { + "name": "Status", + "type": "string" + } + ] + } + } + }, + { + "name": "spycloud_compassV2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "properties": { + "schema": { + "name": "spycloud_compassV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "LogId", + "type": "string" + }, + { + "name": "Severity", + "type": "int" + }, + { + "name": "Email", + "type": "string" + }, + { + "name": "EmailDomain", + "type": "string" + }, + { + "name": "EmailUsername", + "type": "string" + }, + { + "name": "Password", + "type": "string" + }, + { + "name": "PasswordType", + "type": "string" + }, + { + "name": "PasswordPlaintext", + "type": "string" + }, + { + "name": "TargetUrl", + "type": "string" + }, + { + "name": "TargetDomain", + "type": "string" + }, + { + "name": "TargetSubdomain", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "InfectedPath", + "type": "string" + }, + { + "name": "UserOS", + "type": "string" + }, + { + "name": "UserSysRegisteredOwner", + "type": "string" + }, + { + "name": "AVSoftwares", + "type": "dynamic" + }, + { + "name": "CountryCode", + "type": "string" + }, + { + "name": "DisplayResolution", + "type": "string" + }, + { + "name": "IPAddresses", + "type": "dynamic" + }, + { + "name": "TimeZone", + "type": "string" + }, + { + "name": "Domain", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "BreachCategory", + "type": "string" + } + ] + } + } + }, + { + "name": "Spycloud_MDE_LogsV2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "properties": { + "schema": { + "name": "Spycloud_MDE_LogsV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "HostName", + "type": "string" + }, + { + "name": "NormalizedHostName", + "type": "string" + }, + { + "name": "DeviceId", + "type": "string" + }, + { + "name": "OSPlatform", + "type": "string" + }, + { + "name": "RiskScore", + "type": "string" + }, + { + "name": "ExposureLevel", + "type": "string" + }, + { + "name": "IsolationRequested", + "type": "boolean" + }, + { + "name": "IsolationStatus", + "type": "boolean" + }, + { + "name": "MachineTagAdded", + "type": "boolean" + }, + { + "name": "MachineTagName", + "type": "string" + }, + { + "name": "AddedIOCsToDefender", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + } + }, + { + "name": "SpyCloud_ConditionalAccessLogsV2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "properties": { + "schema": { + "name": "SpyCloud_ConditionalAccessLogsV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "UserEmail", + "type": "string" + }, + { + "name": "ForcedPasswordResetOnNextSignIn", + "type": "boolean" + }, + { + "name": "UserSessionsRevoked", + "type": "boolean" + }, + { + "name": "CAgroup", + "type": "boolean" + }, + { + "name": "UserDisabled", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + } + } +] \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_connectorDefinition.json b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_connectorDefinition.json new file mode 100644 index 00000000000..c3f343cdff1 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_connectorDefinition.json @@ -0,0 +1,144 @@ +{ + "type": "Microsoft.SecurityInsights/dataConnectorDefinitions", + "apiVersion": "2022-09-01-preview", + "name": "SpyCloudEnterpriseProtectionCCF", + "location": "{{location}}", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "SpyCloudEnterpriseProtectionCCF", + "title": "SpyCloud Enterprise Protection Connector", + "publisher": "SpyCloud", + "descriptionMarkdown": "Ingests SpyCloud Watchlist exposure data into Microsoft Sentinel, including compromised credentials and infected machine records associated with monitored assets. Also includes SpyCloud breach catalog metadata for contextual enrichment and correlation.", + "graphQueriesTableName": "SpyCloudBreachWatchlistV2_CL", + "graphQueries": [ + { + "metricName": "Total Watchlist", + "legend": "SpyCloud Watchlist", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Watchlists", + "query": "{{graphQueriesTableName}}\n| sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "{{graphQueriesTableName}}", + "lastDataReceivedQuery": "{{graphQueriesTableName}}\n |summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "Read and write permissions are required to ingest data into the Log Analytics workspace.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "read": true, + "write": true, + "delete": true + } + } + ], + "customs": [ + { + "name": "Microsoft Sentinel Contributor", + "description": "Microsoft Sentinel Contributor role is required to manage data connectors." + } + ] + }, + "instructionSteps": [ + { + "title": "Configure SpyCloud API", + "description": "Enter your SpyCloud API key.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "API Key", + "name": "apiKey", + "type": "password", + "placeholder": "Enter your SpyCloud API Key", + "validations": { + "required": true + } + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Severity", + "name": "severity", + "options": [ + { + "key": "2", + "text": "2" + }, + { + "key": "5", + "text": "5" + }, + { + "key": "20", + "text": "20" + }, + { + "key": "25", + "text": "25" + }, + { + "key": "30", + "text": "30" + } + ], + "placeholder": "You can Select Multiple Severity", + "isMultiSelect": true, + "required": true, + "defaultAllSelected": false + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Ingest Compass Data (once daily, yesterday data)", + "name": "compassEnabled", + "options": [ + { + "key": "true", + "text": "On" + }, + { + "key": "false", + "text": "Off" + } + ], + "placeholder": "Enable or disable Compass ingestion", + "isMultiSelect": false, + "required": true + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "connectLabel": "connect", + "name": "toggle" + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Data/Solution_SpyCloudEnterpriseProtection.json b/Solutions/SpyCloud Enterprise Protection CCF/Data/Solution_SpyCloudEnterpriseProtection.json new file mode 100644 index 00000000000..169411ab7db --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Data/Solution_SpyCloudEnterpriseProtection.json @@ -0,0 +1,27 @@ +{ + "Name": "SpyCloud Enterprise Protection CCF", + "Author": "SpyCloud - support@spycloud.com", + "Logo": "", + "Description": "The [SpyCloud Enterprise Protection](https://spycloud.com/) solution for Microsoft Sentinel ingests SpyCloud breach watchlist and catalog data via the Codeless Connector Framework (CCF), including an optional Compass daily feed. The solution includes two built-in analytic rules, two KQL parsers, and two automation playbooks for Microsoft Defender for Endpoint and Azure AD / Entra ID Conditional Access response.\r\n\r\n**Underlying Microsoft Technologies used:**\r\n\r\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\r\n\n a. [Codeless Connector Framework (CCF)](https://learn.microsoft.com/en-us/azure/sentinel/create-codeless-connector)\r\n\n b. [Azure Logic Apps](https://azure.microsoft.com/services/logic-apps/)\r\n\n c. [Microsoft Defender for Endpoint](https://www.microsoft.com/en-us/security/business/endpoint-security/microsoft-defender-endpoint)", + "Analytic Rules": [ + "Analytic Rules/AR_Breached_Users_20.yaml", + "Analytic Rules/AR_malware_25.yaml" + ], + "Data Connectors": [ + "Data Connectors/SpyCloudEnterpriseProtectionLogsV2_ccp/SpyCloudEnterpriseProtectionLogsV2_connectorDefinition.json" + ], + "Parsers": [ + "Parsers/get_Spycloud_enriched_data.yaml", + "Parsers/get_spycloud_compass_data.yaml" + ], + "Playbooks": [ + "Playbooks/SpyCloud_MDE_Automation/azuredeploy.json", + "Playbooks/SpyCloud_Conditional_Access_Playbook/azuredeploy.json", + "Playbooks/SpyCloud_AutomationRules/azuredeploy.json" + ], + "Metadata": "SolutionMetadata.json", + "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\SpyCloud Enterprise ProtectionV2\\", + "Version": "3.0.0", + "TemplateSpec": true, + "Is1PConnector": false +} \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Package/3.0.0.zip b/Solutions/SpyCloud Enterprise Protection CCF/Package/3.0.0.zip new file mode 100644 index 00000000000..10eb78321c3 Binary files /dev/null and b/Solutions/SpyCloud Enterprise Protection CCF/Package/3.0.0.zip differ diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Package/createUiDefinition.json b/Solutions/SpyCloud Enterprise Protection CCF/Package/createUiDefinition.json new file mode 100644 index 00000000000..097344bbd71 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Package/createUiDefinition.json @@ -0,0 +1,169 @@ +{ + "$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/SpyCloud%20Enterprise%20Protection%20CCF/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 [SpyCloud Enterprise Protection](https://spycloud.com/) solution for Microsoft Sentinel ingests SpyCloud breach watchlist and catalog data via the Codeless Connector Framework (CCF), including an optional Compass daily feed. The solution includes two built-in analytic rules, two KQL parsers, and two automation playbooks for Microsoft Defender for Endpoint and Azure AD / Entra ID Conditional Access response.\r\n\r\n**Underlying Microsoft Technologies used:**\r\n\r\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\r\n\n a. [Codeless Connector Framework (CCF)](https://learn.microsoft.com/en-us/azure/sentinel/create-codeless-connector)\r\n\n b. [Azure Logic Apps](https://azure.microsoft.com/services/logic-apps/)\r\n\n c. [Microsoft Defender for Endpoint](https://www.microsoft.com/en-us/security/business/endpoint-security/microsoft-defender-endpoint)\n\n**Data Connectors:** 1, **Parsers:** 2, **Analytic Rules:** 2, **Playbooks:** 3\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 SpyCloud Enterprise Protection Connector. You can get SpyCloud Enterprise Protection Connector 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": "SpyCloud plaintext credential exposure detected", + "elements": [ + { + "name": "analytic1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Identifies user accounts exposed with a plaintext password in a third-party data breach.\nUnremediated exposures of this kind can lead directly to account takeover." + } + } + ] + }, + { + "name": "analytic2", + "type": "Microsoft.Common.Section", + "label": "SpyCloud infostealer malware credential exposure", + "elements": [ + { + "name": "analytic2-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Identifies credentials harvested by infostealer malware on a compromised device. This\nexposure may indicate an actively compromised endpoint with associated command-and-control\nrisk." + } + } + ] + } + ] + }, + { + "name": "playbooks", + "label": "Playbooks", + "subLabel": { + "preValidation": "Configure the playbooks", + "postValidation": "Done" + }, + "bladeTitle": "Playbooks", + "elements": [ + { + "name": "playbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub." + } + }, + { + "name": "playbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef" + } + } + } + ] + } + ], + "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/SpyCloud Enterprise Protection CCF/Package/mainTemplate.json b/Solutions/SpyCloud Enterprise Protection CCF/Package/mainTemplate.json new file mode 100644 index 00000000000..c6f49b50a9d --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Package/mainTemplate.json @@ -0,0 +1,4837 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "SpyCloud - support@spycloud.com", + "comments": "Solution template for SpyCloud Enterprise Protection CCF" + }, + "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" + } + }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "resource group name where Microsoft Sentinel is setup" + } + }, + "subscription": { + "type": "string", + "defaultValue": "[last(split(subscription().id, '/'))]", + "metadata": { + "description": "subscription id where Microsoft Sentinel is setup" + } + } + }, + "variables": { + "email": "support@spycloud.com", + "_email": "[variables('email')]", + "_solutionName": "SpyCloud Enterprise Protection CCF", + "_solutionVersion": "3.0.0", + "solutionId": "spycloud.azure-sentinel-solution-spycloud-enterprise-protection", + "_solutionId": "[variables('solutionId')]", + "analyticRuleObject1": { + "analyticRuleVersion1": "1.0.0", + "_analyticRulecontentId1": "a25eba0e-ff42-4c97-a379-d76bdb2aa1e3", + "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'a25eba0e-ff42-4c97-a379-d76bdb2aa1e3')]", + "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('a25eba0e-ff42-4c97-a379-d76bdb2aa1e3')))]", + "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','a25eba0e-ff42-4c97-a379-d76bdb2aa1e3','-', '1.0.0')))]" + }, + "analyticRuleObject2": { + "analyticRuleVersion2": "1.0.0", + "_analyticRulecontentId2": "ead4deed-9d48-4646-aee0-6b46c2dd1ae6", + "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', 'ead4deed-9d48-4646-aee0-6b46c2dd1ae6')]", + "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('ead4deed-9d48-4646-aee0-6b46c2dd1ae6')))]", + "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','ead4deed-9d48-4646-aee0-6b46c2dd1ae6','-', '1.0.0')))]" + }, + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "dataConnectorCCPVersion": "3.0.0", + "_dataConnectorContentIdConnectorDefinition1": "SpyCloudEnterpriseProtectionCCF", + "dataConnectorTemplateNameConnectorDefinition1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition1')))]", + "_dataConnectorContentIdConnections1": "SpyCloudEnterpriseProtectionCCFConnections", + "dataConnectorTemplateNameConnections1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections1')))]", + "dataCollectionEndpointId1": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]", + "blanks": "[replace('b', 'b', '')]", + "parserObject1": { + "_parserName1": "[concat(parameters('workspace'),'/','get_Spycloud_enriched_data')]", + "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_Spycloud_enriched_data')]", + "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('get_Spycloud_enriched_data-Parser')))]", + "parserVersion1": "1.0.0", + "parserContentId1": "get_Spycloud_enriched_data-Parser" + }, + "parserObject2": { + "_parserName2": "[concat(parameters('workspace'),'/','get_spycloud_compass_data')]", + "_parserId2": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_spycloud_compass_data')]", + "parserTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('get_spycloud_compass_data-Parser')))]", + "parserVersion2": "1.0.0", + "parserContentId2": "get_spycloud_compass_data-Parser" + }, + "SpyCloud_MDE_Automation": "SpyCloud_MDE_Automation", + "_SpyCloud_MDE_Automation": "[variables('SpyCloud_MDE_Automation')]", + "TemplateEmptyArray": "[json('[]')]", + "playbookVersion1": "1.0", + "playbookContentId1": "SpyCloud_MDE_Automation", + "_playbookContentId1": "[variables('playbookContentId1')]", + "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]", + "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]", + "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]", + "SpyCloud_Conditional_Access_Playbook": "SpyCloud_Conditional_Access_Playbook", + "_SpyCloud_Conditional_Access_Playbook": "[variables('SpyCloud_Conditional_Access_Playbook')]", + "playbookVersion2": "1.0", + "playbookContentId2": "SpyCloud_Conditional_Access_Playbook", + "_playbookContentId2": "[variables('playbookContentId2')]", + "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]", + "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]", + "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]", + "SpyCloud_AutomationRules": "SpyCloud_AutomationRules", + "_SpyCloud_AutomationRules": "[variables('SpyCloud_AutomationRules')]", + "playbookVersion3": "1.0", + "playbookContentId3": "SpyCloud_AutomationRules", + "_playbookContentId3": "[variables('playbookContentId3')]", + "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]", + "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]", + "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]", + "_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": "[variables('analyticRuleObject1').analyticRuleTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "AR_Breached_Users_20_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": "scheduled", + "location": "[parameters('workspace-location')]", + "properties": { + "description": "Identifies user accounts exposed with a plaintext password in a third-party data breach.\nUnremediated exposures of this kind can lead directly to account takeover.", + "displayName": "SpyCloud plaintext credential exposure detected", + "enabled": false, + "query": "// Human-readable constant for the severity threshold used below\nlet severityThreshold = 20;\nSpyCloudBreachWatchlistV2_CL\n| where Severity == severityThreshold\n| mv-expand IPAddress = IPAddresses to typeof(string)\n| extend AccountName = Username, AccountEmail = Email\n| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,\n TargetDomain, PasswordPlaintext, AccountName, IPAddress\n", + "queryFrequency": "PT1H", + "queryPeriod": "P2D", + "severity": "High", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ + { + "connectorId": "SpyCloudEnterpriseProtectionCCF", + "dataTypes": [ + "SpyCloudBreachWatchlistV2_CL" + ] + } + ], + "tactics": [ + "Collection" + ], + "subTechniques": [ + "T1589.001" + ], + "techniques": [ + "T1589" + ], + "entityMappings": [ + { + "entityType": "Account", + "fieldMappings": [ + { + "identifier": "Name", + "columnName": "AccountName" + } + ] + }, + { + "entityType": "IP", + "fieldMappings": [ + { + "identifier": "Address", + "columnName": "IPAddress" + } + ] + }, + { + "entityType": "Mailbox", + "fieldMappings": [ + { + "identifier": "MailboxPrimaryAddress", + "columnName": "AccountEmail" + } + ] + } + ], + "eventGroupingSettings": { + "aggregationKind": "SingleAlert" + } + } + }, + { + "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": "SpyCloud Enterprise Protection CCF Analytics Rule 1", + "parentId": "[variables('analyticRuleObject1').analyticRuleId1]", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "contentKind": "AnalyticsRule", + "displayName": "SpyCloud plaintext credential exposure detected", + "contentProductId": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "id": "[variables('analyticRuleObject1')._analyticRulecontentProductId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleObject2').analyticRuleTemplateSpecName2]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "AR_malware_25_AnalyticalRules Analytics Rule with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "apiVersion": "2023-02-01-preview", + "kind": "scheduled", + "location": "[parameters('workspace-location')]", + "properties": { + "description": "Identifies credentials harvested by infostealer malware on a compromised device. This\nexposure may indicate an actively compromised endpoint with associated command-and-control\nrisk.", + "displayName": "SpyCloud infostealer malware credential exposure", + "enabled": false, + "query": "// Human-readable constant for the severity threshold used below\nlet severityThreshold = 25;\nSpyCloudBreachWatchlistV2_CL\n| where Severity == severityThreshold\n| mv-expand IPAddress = IPAddresses to typeof(string)\n| extend AccountName = Username, AccountEmail = Email, HostName = UserHostName\n| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,\n AccountName, HostName, InfectedMachineId, InfectedTime, UserOS, IPAddress\n", + "queryFrequency": "PT1H", + "queryPeriod": "P1D", + "severity": "High", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ + { + "connectorId": "SpyCloudEnterpriseProtectionCCF", + "dataTypes": [ + "SpyCloudBreachWatchlistV2_CL" + ] + } + ], + "tactics": [ + "CredentialAccess", + "CommandAndControl" + ], + "techniques": [ + "T1555", + "T1071" + ], + "entityMappings": [ + { + "entityType": "Account", + "fieldMappings": [ + { + "identifier": "Name", + "columnName": "AccountName" + } + ] + }, + { + "entityType": "Host", + "fieldMappings": [ + { + "identifier": "HostName", + "columnName": "HostName" + } + ] + }, + { + "entityType": "IP", + "fieldMappings": [ + { + "identifier": "Address", + "columnName": "IPAddress" + } + ] + } + ], + "eventGroupingSettings": { + "aggregationKind": "SingleAlert" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleObject2').analyticRuleId2,'/'))))]", + "properties": { + "description": "SpyCloud Enterprise Protection CCF Analytics Rule 2", + "parentId": "[variables('analyticRuleObject2').analyticRuleId2]", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "contentKind": "AnalyticsRule", + "displayName": "SpyCloud infostealer malware credential exposure", + "contentProductId": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", + "id": "[variables('analyticRuleObject2')._analyticRulecontentProductId2]", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" + } + }, + { + "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": "SpyCloud Enterprise Protection Connector", + "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": "SpyCloudEnterpriseProtectionCCF", + "title": "SpyCloud Enterprise Protection Connector", + "publisher": "SpyCloud", + "descriptionMarkdown": "Ingests SpyCloud Watchlist exposure data into Microsoft Sentinel, including compromised credentials and infected machine records associated with monitored assets. Also includes SpyCloud breach catalog metadata for contextual enrichment and correlation.", + "graphQueriesTableName": "SpyCloudBreachWatchlistV2_CL", + "graphQueries": [ + { + "metricName": "Total Watchlist", + "legend": "SpyCloud Watchlist", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Watchlists", + "query": "{{graphQueriesTableName}}\n| sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "{{graphQueriesTableName}}", + "lastDataReceivedQuery": "{{graphQueriesTableName}}\n |summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "Read and write permissions are required to ingest data into the Log Analytics workspace.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "read": true, + "write": true, + "delete": true + } + } + ], + "customs": [ + { + "name": "Microsoft Sentinel Contributor", + "description": "Microsoft Sentinel Contributor role is required to manage data connectors." + } + ] + }, + "instructionSteps": [ + { + "title": "Configure SpyCloud API", + "description": "Enter your SpyCloud API key.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "API Key", + "name": "apiKey", + "type": "password", + "placeholder": "Enter your SpyCloud API Key", + "validations": { + "required": true + } + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Severity", + "name": "severity", + "options": [ + { + "key": "2", + "text": "2" + }, + { + "key": "5", + "text": "5" + }, + { + "key": "20", + "text": "20" + }, + { + "key": "25", + "text": "25" + }, + { + "key": "30", + "text": "30" + } + ], + "placeholder": "You can Select Multiple Severity", + "isMultiSelect": true, + "required": true, + "defaultAllSelected": false + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Ingest Compass Data (once daily, yesterday data)", + "name": "compassEnabled", + "options": [ + { + "key": "true", + "text": "On" + }, + { + "key": "false", + "text": "Off" + } + ], + "placeholder": "Enable or disable Compass ingestion", + "isMultiSelect": false, + "required": true + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "connectLabel": "connect", + "name": "toggle" + } + } + ] + } + ] + } + } + }, + { + "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": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorCCPVersion')]", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "name": "SpyCloudwatchlist-DCR", + "apiVersion": "2022-06-01", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "[parameters('workspace-location')]", + "kind": "[variables('blanks')]", + "properties": { + "dataCollectionEndpointId": "[variables('dataCollectionEndpointId1')]", + "streamDeclarations": { + "Custom-SpyCloudBreachWatchlistV2_CL": { + "columns": [ + { + "name": "infected_path", + "type": "string" + }, + { + "name": "user_hostname", + "type": "string" + }, + { + "name": "ip_addresses", + "type": "dynamic" + }, + { + "name": "timezone", + "type": "string" + }, + { + "name": "target_url", + "type": "string" + }, + { + "name": "document_id", + "type": "string" + }, + { + "name": "target_domain", + "type": "string" + }, + { + "name": "user_sys_registered_owner", + "type": "string" + }, + { + "name": "display_resolution", + "type": "string" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "severity", + "type": "int" + }, + { + "name": "av_softwares", + "type": "dynamic" + }, + { + "name": "log_id", + "type": "string" + }, + { + "name": "user_os", + "type": "string" + }, + { + "name": "email_username", + "type": "string" + }, + { + "name": "spycloud_publish_date", + "type": "string" + }, + { + "name": "infected_machine_id", + "type": "string" + }, + { + "name": "password_plaintext", + "type": "string" + }, + { + "name": "infected_time", + "type": "string" + }, + { + "name": "country_code", + "type": "string" + }, + { + "name": "keyboard_languages", + "type": "string" + }, + { + "name": "password_type", + "type": "string" + }, + { + "name": "domain", + "type": "string" + }, + { + "name": "email_domain", + "type": "string" + }, + { + "name": "source_id", + "type": "int" + }, + { + "name": "target_subdomain", + "type": "string" + }, + { + "name": "sighting", + "type": "int" + }, + { + "name": "account_last_activity_time", + "type": "string" + }, + { + "name": "account_notes", + "type": "string" + }, + { + "name": "account_signup_time", + "type": "string" + }, + { + "name": "username", + "type": "string" + }, + { + "name": "homepage", + "type": "string" + }, + { + "name": "salt", + "type": "string" + }, + { + "name": "account_login_time", + "type": "string" + }, + { + "name": "social_other", + "type": "dynamic" + }, + { + "name": "last_name", + "type": "string" + }, + { + "name": "full_name", + "type": "string" + }, + { + "name": "phone", + "type": "string" + }, + { + "name": "first_name", + "type": "string" + }, + { + "name": "address_1", + "type": "string" + }, + { + "name": "account_modification_time", + "type": "string" + }, + { + "name": "gender", + "type": "string" + }, + { + "name": "city", + "type": "string" + }, + { + "name": "birth_year", + "type": "string" + }, + { + "name": "dob", + "type": "string" + }, + { + "name": "company_website", + "type": "string" + }, + { + "name": "industry", + "type": "string" + }, + { + "name": "account_status", + "type": "string" + }, + { + "name": "social_crunchbase", + "type": "dynamic" + }, + { + "name": "company_name", + "type": "string" + }, + { + "name": "social_linkedin", + "type": "dynamic" + }, + { + "name": "social_twitter", + "type": "dynamic" + }, + { + "name": "account_caption", + "type": "string" + }, + { + "name": "address_2", + "type": "string" + }, + { + "name": "ssn_last_four", + "type": "string" + }, + { + "name": "social_security_number", + "type": "string" + }, + { + "name": "health_insurance_id", + "type": "string" + }, + { + "name": "postal_code", + "type": "string" + }, + { + "name": "age", + "type": "string" + }, + { + "name": "taxid", + "type": "string" + }, + { + "name": "state", + "type": "string" + }, + { + "name": "account_type", + "type": "string" + }, + { + "name": "device_name", + "type": "dynamic" + }, + { + "name": "bank_number", + "type": "string" + }, + { + "name": "mobile_equipment_id", + "type": "string" + }, + { + "name": "country", + "type": "string" + }, + { + "name": "educational_institution", + "type": "string" + }, + { + "name": "job_title", + "type": "string" + }, + { + "name": "account_image_url", + "type": "string" + }, + { + "name": "student_id", + "type": "string" + }, + { + "name": "account_id", + "type": "string" + } + ] + }, + "Custom-SpyCloudBreachCatalogV2_CL": { + "columns": [ + { + "name": "id", + "type": "int" + }, + { + "name": "title", + "type": "string" + }, + { + "name": "description", + "type": "string" + }, + { + "name": "status", + "type": "string" + } + ] + }, + "Custom-spycloud_compassV2_CL": { + "columns": [ + { + "name": "source_id", + "type": "int" + }, + { + "name": "document_id", + "type": "string" + }, + { + "name": "log_id", + "type": "string" + }, + { + "name": "severity", + "type": "int" + }, + { + "name": "email", + "type": "string" + }, + { + "name": "email_domain", + "type": "string" + }, + { + "name": "email_username", + "type": "string" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "password_type", + "type": "string" + }, + { + "name": "password_plaintext", + "type": "string" + }, + { + "name": "target_url", + "type": "string" + }, + { + "name": "target_domain", + "type": "string" + }, + { + "name": "target_subdomain", + "type": "string" + }, + { + "name": "infected_machine_id", + "type": "string" + }, + { + "name": "infected_time", + "type": "string" + }, + { + "name": "infected_path", + "type": "string" + }, + { + "name": "user_os", + "type": "string" + }, + { + "name": "user_sys_registered_owner", + "type": "string" + }, + { + "name": "av_softwares", + "type": "dynamic" + }, + { + "name": "country_code", + "type": "string" + }, + { + "name": "display_resolution", + "type": "string" + }, + { + "name": "ip_addresses", + "type": "dynamic" + }, + { + "name": "timezone", + "type": "string" + }, + { + "name": "domain", + "type": "string" + }, + { + "name": "spycloud_publish_date", + "type": "string" + }, + { + "name": "breach_title", + "type": "string" + }, + { + "name": "breach_category", + "type": "string" + } + ] + }, + "Custom-Spycloud_MDE_LogsV2_CL": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "HostName", + "type": "string" + }, + { + "name": "NormalizedHostName", + "type": "string" + }, + { + "name": "DeviceId", + "type": "string" + }, + { + "name": "OSPlatform", + "type": "string" + }, + { + "name": "RiskScore", + "type": "string" + }, + { + "name": "ExposureLevel", + "type": "string" + }, + { + "name": "IsolationRequested", + "type": "boolean" + }, + { + "name": "IsolationStatus", + "type": "boolean" + }, + { + "name": "MachineTagAdded", + "type": "boolean" + }, + { + "name": "MachineTagName", + "type": "string" + }, + { + "name": "AddedIOCsToDefender", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + }, + "Custom-SpyCloud_ConditionalAccessLogsV2_CL": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "UserEmail", + "type": "string" + }, + { + "name": "ForcedPasswordResetOnNextSignIn", + "type": "boolean" + }, + { + "name": "UserSessionsRevoked", + "type": "boolean" + }, + { + "name": "CAgroup", + "type": "boolean" + }, + { + "name": "UserDisabled", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('workspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-SpyCloudBreachWatchlistV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename InfectedPath = infected_path, UserHostName = user_hostname, IPAddresses = ip_addresses, TimeZone = timezone, TargetUrl = target_url, DocumentId = document_id, TargetDomain = target_domain, UserSysRegisteredOwner = user_sys_registered_owner, DisplayResolution = display_resolution, Password = password, Email = email, Severity = severity, AVSoftwares = av_softwares, LogId = log_id, UserOS = user_os, EmailUsername = email_username, SpyCloudPublishDate = spycloud_publish_date, InfectedMachineId = infected_machine_id, PasswordPlaintext = password_plaintext, InfectedTime = infected_time, CountryCode = country_code, KeyboardLanguages = keyboard_languages, PasswordType = password_type, Domain = domain, EmailDomain = email_domain, SourceId = source_id, TargetSubdomain = target_subdomain, Sighting = sighting, AccountLastActivityTime = account_last_activity_time, AccountNotes = account_notes, AccountSignupTime = account_signup_time, Username = username, Homepage = homepage, Salt = salt, AccountLoginTime = account_login_time, SocialOther = social_other, LastName = last_name, FullName = full_name, Phone = phone, FirstName = first_name, Address1 = address_1, AccountModificationTime = account_modification_time, Gender = gender, City = city, BirthYear = birth_year, DOB = dob, CompanyWebsite = company_website, Industry = industry, AccountStatus = account_status, SocialCrunchbase = social_crunchbase, CompanyName = company_name, SocialLinkedIn = social_linkedin, SocialTwitter = social_twitter, AccountCaption = account_caption, Address2 = address_2, SSNLastFour = ssn_last_four, SocialSecurityNumber = social_security_number, HealthInsuranceId = health_insurance_id, PostalCode = postal_code, Age = age, TaxId = taxid, State = state, AccountType = account_type, DeviceName = device_name, BankNumber = bank_number, MobileEquipmentId = mobile_equipment_id, Country = country, EducationalInstitution = educational_institution, JobTitle = job_title, AccountImageUrl = account_image_url, StudentId = student_id, AccountId = account_id\n", + "outputStream": "Custom-SpyCloudBreachWatchlistV2_CL" + }, + { + "streams": [ + "Custom-SpyCloudBreachCatalogV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename SourceId = id, BreachTitle = title, Description = description, Status = status\n| project TimeGenerated, SourceId, BreachTitle, Description, Status\n", + "outputStream": "Custom-SpyCloudBreachCatalogV2_CL" + }, + { + "streams": [ + "Custom-spycloud_compassV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend TimeGenerated = now()\n| project-rename SourceId = source_id, DocumentId = document_id, LogId = log_id, Severity = severity, Email = email, EmailDomain = email_domain, EmailUsername = email_username, Password = password, PasswordType = password_type, PasswordPlaintext = password_plaintext, TargetUrl = target_url, TargetDomain = target_domain, TargetSubdomain = target_subdomain, InfectedMachineId = infected_machine_id, InfectedTime = infected_time, InfectedPath = infected_path, UserOS = user_os, UserSysRegisteredOwner = user_sys_registered_owner, AVSoftwares = av_softwares, CountryCode = country_code, DisplayResolution = display_resolution, IPAddresses = ip_addresses, TimeZone = timezone, Domain = domain, SpyCloudPublishDate = spycloud_publish_date, BreachTitle = breach_title, BreachCategory = breach_category\n", + "outputStream": "Custom-spycloud_compassV2_CL" + }, + { + "streams": [ + "Custom-Spycloud_MDE_LogsV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend\n TimeGenerated = todatetime(TimeGenerated),\n IncidentId = tostring(IncidentId),\n DocumentId = tostring(DocumentId),\n SpyCloudPublishDate = todatetime(SpyCloudPublishDate),\n InfectedTime = tostring(InfectedTime),\n BreachTitle = tostring(BreachTitle),\n InfectedMachineId = tostring(InfectedMachineId),\n HostName = tostring(HostName),\n NormalizedHostName = tostring(NormalizedHostName),\n DeviceId = tostring(DeviceId),\n OSPlatform = tostring(OSPlatform),\n RiskScore = tostring(RiskScore),\n ExposureLevel = tostring(ExposureLevel),\n IsolationRequested = tobool(IsolationRequested),\n IsolationStatus = tobool(IsolationStatus),\n MachineTagAdded = tobool(MachineTagAdded),\n MachineTagName = tostring(MachineTagName),\n AddedIOCsToDefender = tobool(AddedIOCsToDefender),\n PlaybookName = tostring(PlaybookName)\n| project\n TimeGenerated,\n IncidentId,\n DocumentId,\n SpyCloudPublishDate,\n InfectedTime,\n BreachTitle,\n InfectedMachineId,\n HostName,\n NormalizedHostName,\n DeviceId,\n OSPlatform,\n RiskScore,\n ExposureLevel,\n IsolationRequested,\n IsolationStatus,\n MachineTagAdded,\n MachineTagName,\n AddedIOCsToDefender,\n PlaybookName\n", + "outputStream": "Custom-Spycloud_MDE_LogsV2_CL" + }, + { + "streams": [ + "Custom-SpyCloud_ConditionalAccessLogsV2_CL" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n| extend\n TimeGenerated = todatetime(TimeGenerated),\n IncidentId = tostring(IncidentId),\n DocumentId = tostring(DocumentId),\n SpyCloudPublishDate = todatetime(SpyCloudPublishDate),\n InfectedTime = tostring(InfectedTime),\n BreachTitle = tostring(BreachTitle),\n InfectedMachineId = tostring(InfectedMachineId),\n Username = tostring(Username),\n UserEmail = tostring(UserEmail),\n ForcedPasswordResetOnNextSignIn = tobool(ForcedPasswordResetOnNextSignIn),\n UserSessionsRevoked = tobool(UserSessionsRevoked),\n CAgroup = tobool(CAgroup),\n UserDisabled = tobool(UserDisabled),\n PlaybookName = tostring(PlaybookName)\n| project\n TimeGenerated,\n IncidentId,\n DocumentId,\n SpyCloudPublishDate,\n InfectedTime,\n BreachTitle,\n InfectedMachineId,\n Username,\n UserEmail,\n ForcedPasswordResetOnNextSignIn,\n UserSessionsRevoked,\n CAgroup,\n UserDisabled,\n PlaybookName\n", + "outputStream": "Custom-SpyCloud_ConditionalAccessLogsV2_CL" + } + ] + } + }, + { + "name": "SpyCloudBreachWatchlistV2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "SpyCloudBreachWatchlistV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "InfectedPath", + "type": "string" + }, + { + "name": "UserHostName", + "type": "string" + }, + { + "name": "IPAddresses", + "type": "dynamic" + }, + { + "name": "TimeZone", + "type": "string" + }, + { + "name": "TargetUrl", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "TargetDomain", + "type": "string" + }, + { + "name": "UserSysRegisteredOwner", + "type": "string" + }, + { + "name": "DisplayResolution", + "type": "string" + }, + { + "name": "Password", + "type": "string" + }, + { + "name": "Email", + "type": "string" + }, + { + "name": "Severity", + "type": "int" + }, + { + "name": "AVSoftwares", + "type": "dynamic" + }, + { + "name": "LogId", + "type": "string" + }, + { + "name": "UserOS", + "type": "string" + }, + { + "name": "EmailUsername", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "PasswordPlaintext", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "CountryCode", + "type": "string" + }, + { + "name": "KeyboardLanguages", + "type": "string" + }, + { + "name": "PasswordType", + "type": "string" + }, + { + "name": "Domain", + "type": "string" + }, + { + "name": "EmailDomain", + "type": "string" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "TargetSubdomain", + "type": "string" + }, + { + "name": "Sighting", + "type": "int" + }, + { + "name": "AccountLastActivityTime", + "type": "string" + }, + { + "name": "AccountNotes", + "type": "string" + }, + { + "name": "AccountSignupTime", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "Homepage", + "type": "string" + }, + { + "name": "Salt", + "type": "string" + }, + { + "name": "AccountLoginTime", + "type": "string" + }, + { + "name": "SocialOther", + "type": "dynamic" + }, + { + "name": "LastName", + "type": "string" + }, + { + "name": "FullName", + "type": "string" + }, + { + "name": "Phone", + "type": "string" + }, + { + "name": "FirstName", + "type": "string" + }, + { + "name": "Address1", + "type": "string" + }, + { + "name": "AccountModificationTime", + "type": "string" + }, + { + "name": "Gender", + "type": "string" + }, + { + "name": "City", + "type": "string" + }, + { + "name": "BirthYear", + "type": "string" + }, + { + "name": "DOB", + "type": "string" + }, + { + "name": "CompanyWebsite", + "type": "string" + }, + { + "name": "Industry", + "type": "string" + }, + { + "name": "AccountStatus", + "type": "string" + }, + { + "name": "SocialCrunchbase", + "type": "dynamic" + }, + { + "name": "CompanyName", + "type": "string" + }, + { + "name": "SocialLinkedIn", + "type": "dynamic" + }, + { + "name": "SocialTwitter", + "type": "dynamic" + }, + { + "name": "AccountCaption", + "type": "string" + }, + { + "name": "Address2", + "type": "string" + }, + { + "name": "SSNLastFour", + "type": "string" + }, + { + "name": "SocialSecurityNumber", + "type": "string" + }, + { + "name": "HealthInsuranceId", + "type": "string" + }, + { + "name": "PostalCode", + "type": "string" + }, + { + "name": "Age", + "type": "string" + }, + { + "name": "TaxId", + "type": "string" + }, + { + "name": "State", + "type": "string" + }, + { + "name": "AccountType", + "type": "string" + }, + { + "name": "DeviceName", + "type": "dynamic" + }, + { + "name": "BankNumber", + "type": "string" + }, + { + "name": "MobileEquipmentId", + "type": "string" + }, + { + "name": "Country", + "type": "string" + }, + { + "name": "EducationalInstitution", + "type": "string" + }, + { + "name": "JobTitle", + "type": "string" + }, + { + "name": "AccountImageUrl", + "type": "string" + }, + { + "name": "StudentId", + "type": "string" + }, + { + "name": "AccountId", + "type": "string" + } + ] + } + } + }, + { + "name": "SpyCloudBreachCatalogV2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "SpyCloudBreachCatalogV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "Description", + "type": "string" + }, + { + "name": "Status", + "type": "string" + } + ] + } + } + }, + { + "name": "spycloud_compassV2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "spycloud_compassV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "SourceId", + "type": "int" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "LogId", + "type": "string" + }, + { + "name": "Severity", + "type": "int" + }, + { + "name": "Email", + "type": "string" + }, + { + "name": "EmailDomain", + "type": "string" + }, + { + "name": "EmailUsername", + "type": "string" + }, + { + "name": "Password", + "type": "string" + }, + { + "name": "PasswordType", + "type": "string" + }, + { + "name": "PasswordPlaintext", + "type": "string" + }, + { + "name": "TargetUrl", + "type": "string" + }, + { + "name": "TargetDomain", + "type": "string" + }, + { + "name": "TargetSubdomain", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "InfectedPath", + "type": "string" + }, + { + "name": "UserOS", + "type": "string" + }, + { + "name": "UserSysRegisteredOwner", + "type": "string" + }, + { + "name": "AVSoftwares", + "type": "dynamic" + }, + { + "name": "CountryCode", + "type": "string" + }, + { + "name": "DisplayResolution", + "type": "string" + }, + { + "name": "IPAddresses", + "type": "dynamic" + }, + { + "name": "TimeZone", + "type": "string" + }, + { + "name": "Domain", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "BreachCategory", + "type": "string" + } + ] + } + } + }, + { + "name": "Spycloud_MDE_LogsV2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "Spycloud_MDE_LogsV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "HostName", + "type": "string" + }, + { + "name": "NormalizedHostName", + "type": "string" + }, + { + "name": "DeviceId", + "type": "string" + }, + { + "name": "OSPlatform", + "type": "string" + }, + { + "name": "RiskScore", + "type": "string" + }, + { + "name": "ExposureLevel", + "type": "string" + }, + { + "name": "IsolationRequested", + "type": "boolean" + }, + { + "name": "IsolationStatus", + "type": "boolean" + }, + { + "name": "MachineTagAdded", + "type": "boolean" + }, + { + "name": "MachineTagName", + "type": "string" + }, + { + "name": "AddedIOCsToDefender", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + } + }, + { + "name": "SpyCloud_ConditionalAccessLogsV2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "schema": { + "name": "SpyCloud_ConditionalAccessLogsV2_CL", + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "IncidentId", + "type": "string" + }, + { + "name": "DocumentId", + "type": "string" + }, + { + "name": "SpyCloudPublishDate", + "type": "datetime" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "Username", + "type": "string" + }, + { + "name": "UserEmail", + "type": "string" + }, + { + "name": "ForcedPasswordResetOnNextSignIn", + "type": "boolean" + }, + { + "name": "UserSessionsRevoked", + "type": "boolean" + }, + { + "name": "CAgroup", + "type": "boolean" + }, + { + "name": "UserDisabled", + "type": "boolean" + }, + { + "name": "PlaybookName", + "type": "string" + } + ] + } + } + } + ] + }, + "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": "SpyCloudEnterpriseProtectionCCF", + "title": "SpyCloud Enterprise Protection Connector", + "publisher": "SpyCloud", + "descriptionMarkdown": "Ingests SpyCloud Watchlist exposure data into Microsoft Sentinel, including compromised credentials and infected machine records associated with monitored assets. Also includes SpyCloud breach catalog metadata for contextual enrichment and correlation.", + "graphQueriesTableName": "SpyCloudBreachWatchlistV2_CL", + "graphQueries": [ + { + "metricName": "Total Watchlist", + "legend": "SpyCloud Watchlist", + "baseQuery": "{{graphQueriesTableName}}" + } + ], + "sampleQueries": [ + { + "description": "All Watchlists", + "query": "{{graphQueriesTableName}}\n| sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "{{graphQueriesTableName}}", + "lastDataReceivedQuery": "{{graphQueriesTableName}}\n |summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "HasDataConnectors" + } + ], + "availability": { + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "Read and write permissions are required to ingest data into the Log Analytics workspace.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "read": true, + "write": true, + "delete": true + } + } + ], + "customs": [ + { + "name": "Microsoft Sentinel Contributor", + "description": "Microsoft Sentinel Contributor role is required to manage data connectors." + } + ] + }, + "instructionSteps": [ + { + "title": "Configure SpyCloud API", + "description": "Enter your SpyCloud API key.", + "instructions": [ + { + "type": "Textbox", + "parameters": { + "label": "API Key", + "name": "apiKey", + "type": "password", + "placeholder": "Enter your SpyCloud API Key", + "validations": { + "required": true + } + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Severity", + "name": "severity", + "options": [ + { + "key": "2", + "text": "2" + }, + { + "key": "5", + "text": "5" + }, + { + "key": "20", + "text": "20" + }, + { + "key": "25", + "text": "25" + }, + { + "key": "30", + "text": "30" + } + ], + "placeholder": "You can Select Multiple Severity", + "isMultiSelect": true, + "required": true, + "defaultAllSelected": false + } + }, + { + "type": "Dropdown", + "parameters": { + "label": "Ingest Compass Data (once daily, yesterday data)", + "name": "compassEnabled", + "options": [ + { + "key": "true", + "text": "On" + }, + { + "key": "false", + "text": "Off" + } + ], + "placeholder": "Enable or disable Compass ingestion", + "isMultiSelect": false, + "required": true + } + }, + { + "type": "ConnectionToggleButton", + "parameters": { + "connectLabel": "connect", + "name": "toggle" + } + } + ] + } + ] + } + } + }, + { + "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": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + }, + "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": "SpyCloud Enterprise Protection Connector", + "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": "SpyCloud Enterprise Protection Connector", + "type": "securestring", + "minLength": 1 + }, + "workspace": { + "defaultValue": "[parameters('workspace')]", + "type": "securestring" + }, + "dcrConfig": { + "defaultValue": { + "dataCollectionEndpoint": "data collection Endpoint", + "dataCollectionRuleImmutableId": "data collection rule immutableId" + }, + "type": "object" + }, + "apiKey": { + "defaultValue": "apiKey", + "type": "securestring", + "minLength": 1 + }, + "severity": { + "defaultValue": "severity", + "type": "array" + }, + "compassEnabled": { + "defaultValue": "compassEnabled", + "type": "array" + } + }, + "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": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'SpyCloudWatchlistConnector', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "[[parameters('apiKey')]" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/watchlist", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-ddTHH:mm:ssZ", + "startTimeAttributeName": "since", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "severity": "[[parameters('severity')]" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'SpyCloudWatchlistConnectorModified', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "[[parameters('apiKey')]" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/watchlist", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-dd", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "since_modification_date": "{_QueryWindowStartTime}", + "until_modification_date": "{_QueryWindowStartTime}", + "severity": "[[parameters('severity')]" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'SpyCloudUsernameConnector', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachWatchlistV2_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "dataType": "SpyCloudBreachWatchlistV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "[[parameters('apiKey')]" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/data/usernames/username", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-dd", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "since_modification_date": "{_QueryWindowStartTime}", + "until_modification_date": "{_QueryWindowStartTime}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'SpyCloudBreachCatalogConnector', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-SpyCloudBreachCatalogV2_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "dataType": "SpyCloudBreachCatalogV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "[[parameters('apiKey')]" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/breach/catalog", + "httpMethod": "GET", + "rateLimitQPS": 2, + "queryTimeFormat": "yyyy-MM-ddTHH:mm:ssZ", + "startTimeAttributeName": "since", + "queryWindowInMin": 60, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + } + }, + { + "name": "[[concat(parameters('innerWorkspace'),'/Microsoft.SecurityInsights/', 'SpyCloudCompassConnector', parameters('guidValue'))]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "RestApiPoller", + "properties": { + "connectorDefinitionName": "SpyCloudEnterpriseProtectionCCF", + "dcrConfig": { + "streamName": "Custom-spycloud_compassV2_CL", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "dataType": "spycloud_compassV2_CL", + "auth": { + "type": "APIKey", + "ApiKeyName": "X-API-KEY", + "ApiKey": "[[parameters('apiKey')]" + }, + "request": { + "apiEndpoint": "https://api.spycloud.io/enterprise-v2/compass/data", + "httpMethod": "GET", + "rateLimitQPS": 1, + "queryTimeFormat": "yyyy-MM-dd", + "startTimeAttributeName": "since", + "queryWindowInMin": 1440, + "headers": { + "Accept": "application/json", + "User-Agent": "spycloud_microsoftccf/1.0.0" + }, + "queryParameters": { + "until": "{_QueryWindowStartTime}" + }, + "retryCount": 3, + "timeoutInSeconds": 60 + }, + "response": { + "eventsJsonPaths": [ + "$.results[*]" + ], + "format": "json" + }, + "paging": { + "pagingType": "NextPageToken", + "nextPageTokenJsonPath": "$.cursor", + "nextPageParaName": "cursor", + "pagingInfoPlacement": "QueryString" + }, + "isActive": true + }, + "condition": "[[equals(parameters('compassEnabled'),'true')]" + } + ] + }, + "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('parserObject1').parserTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "get_Spycloud_enriched_data Data Parser with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('parserObject1').parserVersion1]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[variables('parserObject1')._parserName1]", + "apiVersion": "2025-07-01", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SpyCloud Enriched Data Parser", + "category": "Microsoft Sentinel Parser", + "functionAlias": "get_Spycloud_enriched_data", + "query": "let _lookback = coalesce(lookback, 1d);\nlet LatestBreachCatalog =\n SpyCloudBreachCatalogV2_CL\n | summarize arg_max(TimeGenerated, BreachTitle, Description, Status) by SourceId\n | project\n SourceId,\n BreachTitle,\n CatalogDescription = Description,\n CatalogStatus = Status;\nSpyCloudBreachWatchlistV2_CL\n| where TimeGenerated >= ago(_lookback)\n| join kind=leftouter LatestBreachCatalog on SourceId\n| project\n TimeGenerated,\n SourceId,\n InfectedPath,\n UserHostName,\n IPAddresses,\n TimeZone,\n TargetUrl,\n DocumentId,\n TargetDomain,\n UserSysRegisteredOwner,\n DisplayResolution,\n Password,\n Email,\n Severity,\n AVSoftwares,\n LogId,\n UserOS,\n EmailUsername,\n SpyCloudPublishDate,\n InfectedMachineId,\n PasswordPlaintext,\n InfectedTime,\n CountryCode,\n KeyboardLanguages,\n PasswordType,\n Domain,\n EmailDomain,\n TargetSubdomain,\n Sighting,\n AccountLastActivityTime,\n AccountNotes,\n AccountSignupTime,\n Username,\n Homepage,\n Salt,\n AccountLoginTime,\n SocialOther,\n LastName,\n FullName,\n Phone,\n FirstName,\n Address1,\n AccountModificationTime,\n Gender,\n City,\n BirthYear,\n DOB,\n CompanyWebsite,\n Industry,\n AccountStatus,\n SocialCrunchbase,\n CompanyName,\n SocialLinkedIn,\n SocialTwitter,\n AccountCaption,\n Address2,\n SSNLastFour,\n SocialSecurityNumber,\n HealthInsuranceId,\n PostalCode,\n Age,\n TaxId,\n State,\n AccountType,\n DeviceName,\n BankNumber,\n MobileEquipmentId,\n Country,\n EducationalInstitution,\n JobTitle,\n AccountImageUrl,\n StudentId,\n AccountId,\n BreachTitle,\n CatalogDescription,\n CatalogStatus\n", + "functionParameters": "lookback:timespan=1d", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]", + "dependsOn": [ + "[variables('parserObject1')._parserId1]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_Spycloud_enriched_data')]", + "contentId": "[variables('parserObject1').parserContentId1]", + "kind": "Parser", + "version": "[variables('parserObject1').parserVersion1]", + "source": { + "name": "SpyCloud Enterprise Protection CCF", + "kind": "Solution", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('parserObject1').parserContentId1]", + "contentKind": "Parser", + "displayName": "SpyCloud Enriched Data Parser", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]", + "version": "[variables('parserObject1').parserVersion1]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2025-07-01", + "name": "[variables('parserObject1')._parserName1]", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SpyCloud Enriched Data Parser", + "category": "Microsoft Sentinel Parser", + "functionAlias": "get_Spycloud_enriched_data", + "query": "let _lookback = coalesce(lookback, 1d);\nlet LatestBreachCatalog =\n SpyCloudBreachCatalogV2_CL\n | summarize arg_max(TimeGenerated, BreachTitle, Description, Status) by SourceId\n | project\n SourceId,\n BreachTitle,\n CatalogDescription = Description,\n CatalogStatus = Status;\nSpyCloudBreachWatchlistV2_CL\n| where TimeGenerated >= ago(_lookback)\n| join kind=leftouter LatestBreachCatalog on SourceId\n| project\n TimeGenerated,\n SourceId,\n InfectedPath,\n UserHostName,\n IPAddresses,\n TimeZone,\n TargetUrl,\n DocumentId,\n TargetDomain,\n UserSysRegisteredOwner,\n DisplayResolution,\n Password,\n Email,\n Severity,\n AVSoftwares,\n LogId,\n UserOS,\n EmailUsername,\n SpyCloudPublishDate,\n InfectedMachineId,\n PasswordPlaintext,\n InfectedTime,\n CountryCode,\n KeyboardLanguages,\n PasswordType,\n Domain,\n EmailDomain,\n TargetSubdomain,\n Sighting,\n AccountLastActivityTime,\n AccountNotes,\n AccountSignupTime,\n Username,\n Homepage,\n Salt,\n AccountLoginTime,\n SocialOther,\n LastName,\n FullName,\n Phone,\n FirstName,\n Address1,\n AccountModificationTime,\n Gender,\n City,\n BirthYear,\n DOB,\n CompanyWebsite,\n Industry,\n AccountStatus,\n SocialCrunchbase,\n CompanyName,\n SocialLinkedIn,\n SocialTwitter,\n AccountCaption,\n Address2,\n SSNLastFour,\n SocialSecurityNumber,\n HealthInsuranceId,\n PostalCode,\n Age,\n TaxId,\n State,\n AccountType,\n DeviceName,\n BankNumber,\n MobileEquipmentId,\n Country,\n EducationalInstitution,\n JobTitle,\n AccountImageUrl,\n StudentId,\n AccountId,\n BreachTitle,\n CatalogDescription,\n CatalogStatus\n", + "functionParameters": "lookback:timespan=1d", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "location": "[parameters('workspace-location')]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]", + "dependsOn": [ + "[variables('parserObject1')._parserId1]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_Spycloud_enriched_data')]", + "contentId": "[variables('parserObject1').parserContentId1]", + "kind": "Parser", + "version": "[variables('parserObject1').parserVersion1]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('parserObject2').parserTemplateSpecName2]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "get_spycloud_compass_data Data Parser with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('parserObject2').parserVersion2]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[variables('parserObject2')._parserName2]", + "apiVersion": "2025-07-01", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SpyCloud Compass Data Parser", + "category": "Microsoft Sentinel Parser", + "functionAlias": "get_spycloud_compass_data", + "query": "let _startTime = coalesce(startTime, 1d);\nspycloud_compassV2_CL\n| where TimeGenerated > ago(_startTime)\n| project\n TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, Email, Domain,\n Password, PasswordPlaintext, Severity, IPAddresses, InfectedMachineId,\n InfectedTime, BreachTitle, BreachCategory\n", + "functionParameters": "startTime:timespan=1d", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject2')._parserId2,'/'))))]", + "dependsOn": [ + "[variables('parserObject2')._parserId2]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_spycloud_compass_data')]", + "contentId": "[variables('parserObject2').parserContentId2]", + "kind": "Parser", + "version": "[variables('parserObject2').parserVersion2]", + "source": { + "name": "SpyCloud Enterprise Protection CCF", + "kind": "Solution", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('parserObject2').parserContentId2]", + "contentKind": "Parser", + "displayName": "SpyCloud Compass Data Parser", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject2').parserContentId2,'-', '1.0.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject2').parserContentId2,'-', '1.0.0')))]", + "version": "[variables('parserObject2').parserVersion2]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2025-07-01", + "name": "[variables('parserObject2')._parserName2]", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "SpyCloud Compass Data Parser", + "category": "Microsoft Sentinel Parser", + "functionAlias": "get_spycloud_compass_data", + "query": "let _startTime = coalesce(startTime, 1d);\nspycloud_compassV2_CL\n| where TimeGenerated > ago(_startTime)\n| project\n TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, Email, Domain,\n Password, PasswordPlaintext, Severity, IPAddresses, InfectedMachineId,\n InfectedTime, BreachTitle, BreachCategory\n", + "functionParameters": "startTime:timespan=1d", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "location": "[parameters('workspace-location')]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject2')._parserId2,'/'))))]", + "dependsOn": [ + "[variables('parserObject2')._parserId2]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'get_spycloud_compass_data')]", + "contentId": "[variables('parserObject2').parserContentId2]", + "kind": "Parser", + "version": "[variables('parserObject2').parserVersion2]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "SpyCloud_MDE_Automation Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion1')]", + "parameters": { + "PlaybookName": { + "defaultValue": "SpyCloud_MDE_Automation", + "type": "string" + } + }, + "variables": { + "loginUrl": "[[environment().authentication.loginEndpoint]", + "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]", + "Office365V1": "[[concat('office365-', parameters('PlaybookName'))]", + "WDATPConnection": "[[concat('wdatp-', parameters('PlaybookName'))]", + "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]", + "_connection-1": "[[variables('connection-1')]", + "connection-2": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/wdatp')]", + "_connection-2": "[[variables('connection-2')]", + "connection-3": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]", + "_connection-3": "[[variables('connection-3')]", + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('Office365V1')]", + "location": "[[variables('workspace-location-inline')]", + "properties": { + "displayName": "[[variables('Office365V1')]", + "api": { + "id": "[[variables('_connection-1')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('WDATPConnection')]", + "location": "[[variables('workspace-location-inline')]", + "properties": { + "displayName": "WDATP Connection", + "api": { + "id": "[[variables('_connection-2')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('AzureSentinelConnectionName')]", + "location": "[[variables('workspace-location-inline')]", + "kind": "V1", + "properties": { + "displayName": "[[variables('AzureSentinelConnectionName')]", + "parameterValueType": "Alternative", + "api": { + "id": "[[variables('_connection-3')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2017-07-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[variables('workspace-location-inline')]", + "identity": { + "type": "SystemAssigned" + }, + "dependsOn": [ + "[[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "[[resourceId('Microsoft.Web/connections', variables('WDATPConnection'))]", + "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]" + ], + "properties": { + "state": "Disabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "type": "Object" + }, + "PlaybookName": { + "defaultValue": "[[parameters('PlaybookName')]", + "type": "String" + }, + "Isolate_Machine": { + "type": "Bool", + "defaultValue": false + }, + "Machine_Tag_Value": { + "type": "String" + }, + "Save_IOCs_Defender": { + "type": "Bool", + "defaultValue": false + }, + "IOC_Expiration_Days": { + "type": "Int", + "defaultValue": 30 + }, + "Spycloud_Defender_DCE_Endpoint": { + "type": "String" + }, + "Spycloud_Defender_DCE_Immutable_ID": { + "type": "String" + }, + "TenantID": { + "type": "String" + }, + "ClientID": { + "type": "String" + }, + "Client_Secret": { + "type": "String" + }, + "Ingestion_Table_Name": { + "type": "String", + "defaultValue": "Spycloud_MDE_LogsV2_CL" + }, + "create_incident_in_sentinel": { + "type": "Bool", + "defaultValue": false + }, + "Workspace_Name": { + "type": "String", + "defaultValue": "Your workspace name" + }, + "Defender_IOC_Action_Type": { + "type": "String", + "defaultValue": "Alert" + }, + "notification_email": { + "type": "String" + } + }, + "triggers": { + "Microsoft_Sentinel_incident": { + "type": "ApiConnectionWebhook", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "body": { + "callback_url": "@listCallbackUrl()" + }, + "path": "/incident-creation" + } + } + }, + "actions": { + "Entities_-_Get_Hosts": { + "runAfter": { + "For_each_incident_alert": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/host" + } + }, + "For_each": { + "foreach": "@body('Entities_-_Get_Hosts')?['Hosts']", + "actions": { + "Machines_-_Get_single_machine": { + "runAfter": { + "Set_host_name": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "get", + "path": "/api/machines/@variables('host_name')" + } + }, + "GetAccessToken": { + "runAfter": { + "Send_an_email_(V2)": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('Client_Secret')}&scope=https://monitor.azure.com/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Log_ingestion": { + "runAfter": { + "GetAccessToken": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@variables('log_ingestion_api')", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('GetAccessToken')?['access_token']}", + "Content-Type": "application/json" + }, + "body": [ + { + "TimeGenerated": "@{utcNow()}", + "IncidentId": "@{body('Create_incident')?['properties']?['providerIncidentId']}", + "DocumentId": "@{variables('DocumentID')}", + "SpyCloudPublishDate": "@{variables('SpyCloudPublishDate')}", + "InfectedTime": "@{variables('InfectedTime')}", + "BreachTitle": "@{variables('BreachTitle')}", + "InfectedMachineId": "@{variables('InfectedMachineId')}", + "HostName": "@{coalesce(body('Machines_-_Get_single_machine')?['computerDnsName'], '')}", + "NormalizedHostName": "@{toLower(coalesce(body('Machines_-_Get_single_machine')?['computerDnsName'], ''))}", + "DeviceId": "@{coalesce(body('Machines_-_Get_single_machine')?['id'], '')}", + "OSPlatform": "@{coalesce(body('Machines_-_Get_single_machine')?['osPlatform'], '')}", + "RiskScore": "@{coalesce(body('Machines_-_Get_single_machine')?['riskScore'], '')}", + "ExposureLevel": "@{coalesce(body('Machines_-_Get_single_machine')?['exposureLevel'], '')}", + "IsolationRequested": "@variables('machine_isolated')", + "IsolationStatus": "@variables('machine_isolated')", + "MachineTagAdded": "@variables('machine_tag_added')", + "MachineTagName": "@{parameters('Machine_Tag_Value')}", + "AddedIOCsToDefender": "@variables('defender_iocs_added')", + "PlaybookName": "[[parameters('PlaybookName')]" + } + ] + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_host_name": { + "type": "SetVariable", + "inputs": { + "name": "host_name", + "value": "@item()?['HostName']" + } + }, + "Check_Create_Sentinel_Incident": { + "actions": { + "Create_incident": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "put", + "body": { + "title": "Spycloud MDE Alert - Machine Compromised @{variables('host_name')}", + "severity": "High", + "status": "Active", + "description": "The Incident is created from Spycloud MDE Automation Playbook" + }, + "path": "[[concat('/Incidents/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/workspaces/', parameters('Workspace_Name'))]" + } + } + }, + "runAfter": { + "Machines_-_Get_single_machine": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('create_incident_in_sentinel')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_Isolate_Machine": { + "actions": { + "Condition_-_Check_Machine_is_Active": { + "actions": { + "Set_-_machine_active_to_true": { + "type": "SetVariable", + "inputs": { + "name": "is_machine_active", + "value": true + } + } + }, + "else": { + "actions": { + "Set_machine_active_to_false": { + "type": "SetVariable", + "inputs": { + "name": "is_machine_active", + "value": false + } + } + } + }, + "expression": { + "and": [ + { + "equals": [ + "@body('Machines_-_Get_single_machine')?['healthStatus']", + "Active" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Check_if_the_machine_is_lastseen_in_the_last_6_hours": { + "actions": { + "Set_last_active": { + "type": "SetVariable", + "inputs": { + "name": "is_last_sees_satisfied", + "value": true + } + } + }, + "runAfter": { + "Condition_-_Check_Machine_is_Active": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "greater": [ + "@ticks(body('Machines_-_Get_single_machine')?['lastSeen'])", + "@ticks(addHours(utcNow(), -6))" + ] + } + ] + }, + "type": "If" + }, + "Condition_If_we_can_Isolate_the_machine": { + "actions": { + "Actions_-_Isolate_machine": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "post", + "body": { + "Comment": "This machine has found comprised - SpyCloud", + "IsolationType": "Selective" + }, + "path": "/api/machines/@{encodeURIComponent(body('Machines_-_Get_single_machine')?['id'])}/isolate" + } + }, + "set_machine_isolatyed": { + "runAfter": { + "Actions_-_Isolate_machine": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "machine_isolated", + "value": true + } + } + }, + "runAfter": { + "Condition_-_Check_if_the_machine_is_lastseen_in_the_last_6_hours": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@variables('is_machine_active')", + "@true" + ] + }, + { + "equals": [ + "@variables('is_last_sees_satisfied')", + "@true" + ] + } + ] + }, + "type": "If" + } + }, + "runAfter": { + "Check_Create_Sentinel_Incident": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Isolate_Machine')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Add_Machine_Tag": { + "actions": { + "Machines_-_Tag_machine": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "post", + "body": { + "Value": "@parameters('Machine_Tag_Value')", + "Action": "Add" + }, + "path": "/api/machines/@{encodeURIComponent(body('Machines_-_Get_single_machine')?['id'])}/tags" + } + }, + "Set_machine_tag_added": { + "runAfter": { + "Machines_-_Tag_machine": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "machine_tag_added", + "value": true + } + } + }, + "runAfter": { + "Condition_Isolate_Machine": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "greater": [ + "@length(parameters('Machine_Tag_Value'))", + 0 + ] + } + ] + }, + "type": "If" + }, + "Send_an_email_(V2)": { + "runAfter": { + "Condition_-_Add_Machine_Tag": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['office365']['connectionId']" + } + }, + "method": "post", + "body": { + "To": "@parameters('notification_email')", + "Subject": "@{variables('host_name')} - Security Risk", + "Body": "

Security notification! This is automated email sent by Microsoft Sentinel SpyCloud Automation!


For Host @{variables('host_name')} the following actions were taken


Machine Tag Added : @{variables('machine_tag_added')},

Machine Tag Value : @{parameters('Machine_Tag_Value')},

Machine Isolated: @{variables('machine_isolated')}

", + "Importance": "Normal" + }, + "path": "/v2/Mail" + } + } + }, + "runAfter": { + "Condition_Save_IOCS_in_Defender": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "Variables_Section": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "log_ingestion_api", + "type": "string", + "value": "@{concat(concat(concat(parameters('Spycloud_Defender_DCE_Endpoint'),'/dataCollectionRules/'),parameters('Spycloud_Defender_DCE_Immutable_ID') ),concat('/streams/Custom-',concat(parameters('Ingestion_Table_Name'), '?api-version=2023-01-01') ))}" + }, + { + "name": "access_token_url", + "type": "string", + "value": "test" + }, + { + "name": "log_ingestion_url", + "type": "string", + "value": "test" + }, + { + "name": "host_name", + "type": "string", + "value": " " + }, + { + "name": "defender_iocs_object", + "type": "array", + "value": "[variables('TemplateEmptyArray')]" + }, + { + "name": "machine_isolated", + "type": "boolean", + "value": false + }, + { + "name": "machine_tag_added", + "type": "boolean", + "value": false + }, + { + "name": "defender_iocs_added", + "type": "boolean", + "value": false + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "DocumentID", + "type": "string" + }, + { + "name": "incident_custom_details_object", + "type": "object" + }, + { + "name": "is_machine_onboarded", + "type": "boolean" + }, + { + "name": "is_machine_active", + "type": "boolean", + "value": false + }, + { + "name": "is_machine_excluded", + "type": "boolean", + "value": false + }, + { + "name": "is_last_sees_satisfied", + "type": "boolean", + "value": false + } + ] + } + }, + "Condition_Save_IOCS_in_Defender": { + "actions": { + "Entities_-_Get_DNS": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/dnsresolution" + } + }, + "Entities_-_Get_IPs": { + "runAfter": { + "For_each_Domains_in_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/ip" + } + }, + "Entities_-_Get_URLs": { + "runAfter": { + "For_each_IPs_in_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/url" + } + }, + "For_each_Domains_in_incident": { + "foreach": "@body('Entities_-_Get_DNS')?['Dnsresolutions']", + "actions": { + "Domain_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "@parameters('Defender_IOC_Action_Type')", + "description": "SpyCloud MDE Playbook", + "indicatorType": "DomainName", + "indicatorValue": "@item()?['DomainName']", + "title": "SpyCloud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object": { + "runAfter": { + "Domain_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('Domain_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_DNS": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_IPs_in_incident": { + "foreach": "@body('Entities_-_Get_IPs')?['IPs']", + "actions": { + "IP_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "Block", + "description": "SpyCloiud MDE Playbook", + "indicatorType": "IpAddress", + "indicatorValue": "@item()?['Address']", + "title": "SpyCloiud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object_1": { + "runAfter": { + "IP_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('IP_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_IPs": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_Url_in_incident": { + "foreach": "@body('Entities_-_Get_URLs')?['URLs']", + "actions": { + "Url_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "Block", + "description": "SpyCloiud MDE Playbook", + "indicatorType": "Url", + "indicatorValue": "@item()?['Url']", + "title": "SpyCloiud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object_2": { + "runAfter": { + "Url_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('Url_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_URLs": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "Auth_MDE": { + "runAfter": { + "For_each_Url_in_incident": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('Client_Secret')}&scope=https://securitycenter.onmicrosoft.com/windowsatpservice/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "HTTP_-_Create_Indicator": { + "runAfter": { + "Auth_MDE": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "https://api.security.microsoft.com/api/indicators/import", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('Auth_MDE')?['access_token']}" + }, + "body": { + "Indicators": "@variables('defender_iocs_object')" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_defender_iocs_variable": { + "runAfter": { + "HTTP_-_Create_Indicator": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "defender_iocs_added", + "value": true + } + } + }, + "runAfter": { + "Entities_-_Get_Hosts": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Save_IOCs_Defender')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "For_each_incident_alert": { + "foreach": "@triggerBody()?['object']?['properties']?['Alerts']", + "actions": { + "Set_custom_details_object": { + "type": "SetVariable", + "inputs": { + "name": "incident_custom_details_object", + "value": "@json(items('For_each_incident_alert')?['properties']?['additionalData']?['Custom Details'])" + } + }, + "Set_Spycloud_publish_date": { + "runAfter": { + "Set_custom_details_object": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SpyCloudPublishDate", + "value": "@first(coalesce(variables('incident_custom_details_object')?['SpyCloudPublishDate'], createArray('')))" + } + }, + "Set_Infected_Time": { + "runAfter": { + "Set_Spycloud_publish_date": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedTime", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedTime'], createArray('')))" + } + }, + "Set_Breach_Title": { + "runAfter": { + "Set_Infected_Time": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "BreachTitle", + "value": "@first(coalesce(variables('incident_custom_details_object')?['BreachTitle'], createArray('')))\r\n" + } + }, + "Set_Infected_Machine_ID": { + "runAfter": { + "Set_Breach_Title": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedMachineId", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedMachineId'], createArray('')))" + } + }, + "Set_Document_ID": { + "runAfter": { + "Set_Infected_Machine_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "DocumentID", + "value": "@first(coalesce(variables('incident_custom_details_object')?['DocumentID'], createArray('')))" + } + } + }, + "runAfter": { + "Variables_Section": [ + "Succeeded" + ] + }, + "type": "Foreach" + } + } + }, + "parameters": { + "$connections": { + "value": { + "wdatp": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('WDATPConnection'))]", + "connectionName": "[[variables('WDATPConnection')]", + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/wdatp')]" + }, + "azuresentinel": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]", + "connectionName": "[[variables('AzureSentinelConnectionName')]", + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + } + }, + "office365": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "connectionName": "[[variables('Office365V1')]", + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]" + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId1')]", + "contentId": "[variables('_playbookContentId1')]", + "kind": "Playbook", + "version": "[variables('playbookVersion1')]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId1')]", + "contentKind": "Playbook", + "displayName": "SpyCloud_MDE_Automation", + "contentProductId": "[variables('_playbookcontentProductId1')]", + "id": "[variables('_playbookcontentProductId1')]", + "version": "[variables('playbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName2')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "SpyCloud_Conditional_Access_Playbook Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion2')]", + "parameters": { + "PlaybookName": { + "defaultValue": "SpyCloud_Conditional_Access_Playbook", + "type": "string" + } + }, + "variables": { + "loginUrl": "[[environment().authentication.loginEndpoint]", + "AzureSentinelConnectionName": "[[concat('azuresentinel-', parameters('PlaybookName'))]", + "Office365V1": "[[concat('office365-', parameters('PlaybookName'))]", + "subscription": "[[last(split(subscription().id, '/'))]", + "resourceGroupName": "[[resourceGroup().name]", + "connection-1": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]", + "_connection-1": "[[variables('connection-1')]", + "connection-2": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]", + "_connection-2": "[[variables('connection-2')]", + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('Office365V1')]", + "location": "[[variables('workspace-location-inline')]", + "properties": { + "displayName": "[[variables('Office365V1')]", + "api": { + "id": "[[variables('_connection-1')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[[variables('AzureSentinelConnectionName')]", + "location": "[[variables('workspace-location-inline')]", + "kind": "V1", + "properties": { + "displayName": "[[variables('AzureSentinelConnectionName')]", + "parameterValueType": "Alternative", + "api": { + "id": "[[variables('_connection-2')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2017-07-01", + "name": "[[parameters('PlaybookName')]", + "location": "[[variables('workspace-location-inline')]", + "identity": { + "type": "SystemAssigned" + }, + "dependsOn": [ + "[[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]" + ], + "properties": { + "state": "Disabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "type": "Object" + }, + "PlaybookName": { + "defaultValue": "[[parameters('PlaybookName')]", + "type": "String" + }, + "Notify_Users_Emails": { + "type": "String" + }, + "Force_Password_Reset_On_Next_SignIn": { + "type": "Bool", + "defaultValue": false + }, + "Disable_User": { + "type": "Bool", + "defaultValue": false + }, + "Add_User_To_Azure_CA_Group": { + "type": "Bool", + "defaultValue": false + }, + "Azure_CA_Group_Object_ID": { + "type": "String" + }, + "Revoke_User_Sessions": { + "type": "Bool", + "defaultValue": false + }, + "ClientID": { + "type": "String" + }, + "TenantID": { + "type": "String" + }, + "ClientSecret": { + "type": "String" + }, + "DCE_Endpoint": { + "type": "String" + }, + "DCE_Immutable_ID": { + "type": "String" + }, + "Custom_Table_Name": { + "type": "String", + "defaultValue": "SpyCloud_ConditionalAccessLogsV2_CL" + } + }, + "triggers": { + "Microsoft_Sentinel_incident": { + "type": "ApiConnectionWebhook", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "body": { + "callback_url": "@{listCallbackUrl()}" + }, + "path": "/incident-creation" + } + } + }, + "actions": { + "Entities_-_Get_Accounts": { + "runAfter": { + "For_each_incident_alert": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/account" + } + }, + "For_each": { + "foreach": "@body('Entities_-_Get_Accounts')?['Accounts']", + "actions": { + "Get_User_Details": { + "runAfter": { + "Set_user": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}?$select=id,displayName,accountEnabled,lastPasswordChangeDateTime,userPrincipalName", + "method": "GET", + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_user": { + "type": "SetVariable", + "inputs": { + "name": "user_email", + "value": "@{concat(items('For_each')?['Name'],'@',items('for_each')?['UPNSuffix'])}" + } + }, + "Condition_-_Check_if_user_is_enabled": { + "actions": { + "Condition_Check_if_password_has_not_been_reset_since_7_days": { + "actions": { + "Condition_-_Check_if_user_needs_to_be_added_to_CA_group_": { + "actions": { + "Add_user_to_Conditional_Access_Group": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/groups/@{parameters('Azure_CA_Group_Object_ID')}/members/$ref", + "method": "POST", + "body": { + "@@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/@{body('Get_User_Details')?['id']}" + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_Added_To_CA_Group_Enforced": { + "runAfter": { + "Add_user_to_Conditional_Access_Group": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AddedToCAGroupEnforced", + "value": true + } + }, + "Set_Added_To_CA_Group_Enforced_Text": { + "runAfter": { + "Set_Added_To_CA_Group_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AddedToCAGroupText", + "value": "Successfully added the user to Conditional Access Group." + } + } + }, + "runAfter": { + "Condition_-_Check_Revoke_User_Sessions": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Add_User_To_Azure_CA_Group')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_If_User_needs_to_be_disabled": { + "actions": { + "HTTP_-_Disable_User": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}", + "method": "PATCH", + "body": { + "accountEnabled": false + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + } + }, + "Set_Account_Disabled_": { + "runAfter": { + "HTTP_-_Disable_User": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountDisabledEnforced", + "value": true + } + }, + "Set_Account_Disabled_Text": { + "runAfter": { + "Set_Account_Disabled_": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountDisabledText", + "value": "The User has been successfully Disabled." + } + } + }, + "runAfter": { + "Condition_-_Check_if_user_needs_to_be_added_to_CA_group_": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Disable_User')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Check_Revoke_User_Sessions": { + "actions": { + "HTTP_-_Revoke_User_Sessions": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}/revokeSignInSessions", + "method": "POST", + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_User_Session_Enforced": { + "runAfter": { + "HTTP_-_Revoke_User_Sessions": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "UserSessionsRevokeEnforced", + "value": true + } + }, + "Set_User_Session_Revoke_Text": { + "runAfter": { + "Set_User_Session_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "UserSessionRevokeText", + "value": "User sessions has been successfully revoked." + } + } + }, + "runAfter": { + "Condition-Check_for_Password_Reset": [ + "Succeeded" + ] + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Revoke_User_Sessions')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition-Check_for_Password_Reset": { + "actions": { + "Force_Password_Reset": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}", + "method": "PATCH", + "body": { + "passwordProfile": { + "forceChangePasswordNextSignIn": true + } + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_Passwod_Reset_Enforced": { + "runAfter": { + "Force_Password_Reset": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PasswordResetEnforced", + "value": true + } + }, + "Set_Password_Reset_Text": { + "runAfter": { + "Set_Passwod_Reset_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PasswordResetText", + "value": "Password has been successfully reset" + } + } + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Force_Password_Reset_On_Next_SignIn')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Add_comment_to_incident": { + "runAfter": { + "Condition_-_If_User_needs_to_be_disabled": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) the following actions were done from the Spycloud playbook. Manager () is notified.

@{variables('PasswordResetText')}

@{variables('AddedToCAGroupText')}

@{variables('UserSessionRevokeText')}

@{variables('AccountDisabledText')}


" + }, + "path": "/Incidents/Comment" + } + }, + "Send_an_email_-_to_manager_": { + "runAfter": { + "Add_comment_to_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['office365']['connectionId']" + } + }, + "method": "post", + "body": { + "To": "@parameters('Notify_Users_Emails')", + "Subject": "@{items('For_each')?['Name']} - security risk!", + "Body": "

Security notification! This is automated email sent by Microsoft Sentinel SpyCloud Automation!

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) the following actions were done from the Spycloud playbook.
@{variables('PasswordResetText')}
@{variables('AddedToCAGroupText')}
@{variables('UserSessionRevokeText')}
@{variables('AccountDisabledText')}




Can you please notify the user and work with him to reach our support.


", + "Importance": "High" + }, + "path": "/v2/Mail" + } + } + }, + "else": { + "actions": { + "Add_comment_to_incident_-_Password_Latest": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) no actions were done from the Spycloud playbook.


Reason: Password has been reset after the breached date by the user.





" + }, + "path": "/Incidents/Comment" + } + } + } + }, + "expression": { + "and": [ + { + "less": [ + "@addToDateTime(parseDateTime(body('Get_User_Details')?['lastPasswordChangeDateTime']), 7, 'Day')", + "@parseDateTime(variables('SpyCloudPublishDate'))" + ] + } + ] + }, + "type": "If" + }, + "GetAccessToken": { + "runAfter": { + "Condition_Check_if_password_has_not_been_reset_since_7_days": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('ClientSecret')}&scope=https://monitor.azure.com/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Log_ingestion": { + "runAfter": { + "GetAccessToken": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@variables('log_ingestion_api')", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('GetAccessToken')?['access_token']}", + "Content-Type": "application/json" + }, + "body": [ + { + "TimeGenerated": "@{utcNow()}", + "IncidentId": "@{triggerBody()?['object']?['properties']?['providerIncidentId']}", + "DocumentId": "@{variables('DocumentID')}", + "SpyCloudPublishDate": "@{variables('SpyCloudPublishDate')}", + "InfectedTime": "@{variables('InfectedTime')}", + "BreachTitle": "@{variables('BreachTitle')}", + "InfectedMachineId": "@{variables('InfectedMachineId')}", + "Username": "@{variables('user_email')}", + "UserEmail": "@{variables('user_email')}", + "ForcedPasswordResetOnNextSignIn": "@variables('PasswordResetEnforced')", + "UserSessionsRevoked": "@variables('UserSessionsRevokeEnforced')", + "CAgroup": "@variables('AddedToCAGroupEnforced')", + "UserDisabled": "@variables('AccountDisabledEnforced')", + "PlaybookName": "SpyCloud_Conditonal_Access_Automation" + } + ] + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + } + }, + "runAfter": { + "Get_User_Details": [ + "Succeeded" + ] + }, + "else": { + "actions": { + "Add_comment_to_incident_-_user_disable": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) no actions were done from the Spycloud playbook.


Reason: The user is currently disabled..



" + }, + "path": "/Incidents/Comment" + } + } + } + }, + "expression": { + "and": [ + { + "equals": [ + "@body('Get_User_Details')?['accountEnabled']", + "@true" + ] + } + ] + }, + "type": "If" + } + }, + "runAfter": { + "Entities_-_Get_Accounts": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_incident_alert": { + "foreach": "@triggerBody()?['object']?['properties']?['Alerts']", + "actions": { + "Set_custom_details_object": { + "type": "SetVariable", + "inputs": { + "name": "incident_custom_details_object", + "value": "@json(items('For_each_incident_alert')?['properties']?['additionalData']?['Custom Details'])" + } + }, + "Set_Spycloud_publish_date": { + "runAfter": { + "Set_custom_details_object": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SpyCloudPublishDate", + "value": "@first(coalesce(variables('incident_custom_details_object')?['SpyCloudPublishDate'], createArray('')))" + } + }, + "Set_Infected_Time": { + "runAfter": { + "Set_Spycloud_publish_date": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedTime", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedTime'], createArray('')))" + } + }, + "Set_Breach_Title": { + "runAfter": { + "Set_Infected_Time": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "BreachTitle", + "value": "@first(coalesce(variables('incident_custom_details_object')?['BreachTitle'], createArray('')))\n" + } + }, + "Set_Infected_Machine_ID": { + "runAfter": { + "Set_Breach_Title": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedMachineId", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedMachineId'], createArray('')))" + } + }, + "Set_Document_ID": { + "runAfter": { + "Set_Infected_Machine_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "DocumentID", + "value": "@first(coalesce(variables('incident_custom_details_object')?['DocumentID'], createArray('')))" + } + }, + "Set_log_ingestion_api_url": { + "runAfter": { + "Set_Document_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "log_ingestion_api", + "value": "@concat(concat(concat(parameters('DCE_Endpoint'),'/dataCollectionRules/'),parameters('DCE_Immutable_ID') ),concat('/streams/Custom-',concat(parameters('Custom_Table_Name'), '?api-version=2023-01-01') ))" + } + } + }, + "runAfter": { + "variables_Section": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "variables_Section": { + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "incident_custom_details_object", + "type": "object" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "DocumentID", + "type": "string" + }, + { + "name": "last_password_reset_date", + "type": "string" + }, + { + "name": "Authority", + "type": "string", + "value": "[[variables('loginUrl')]" + }, + { + "name": "Audience", + "type": "string", + "value": "https://graph.microsoft.com" + }, + { + "name": "user_email", + "type": "string" + }, + { + "name": "log_ingestion_api", + "type": "string" + }, + { + "name": "PasswordResetEnforced", + "type": "boolean", + "value": false + }, + { + "name": "AccountDisabledEnforced", + "type": "boolean", + "value": false + }, + { + "name": "AddedToCAGroupEnforced", + "type": "boolean", + "value": false + }, + { + "name": "PasswordResetText", + "type": "string" + }, + { + "name": "AccountDisabledText", + "type": "string" + }, + { + "name": "AddedToCAGroupText", + "type": "string" + }, + { + "name": "UserSessionsRevokeEnforced", + "type": "boolean", + "value": false + }, + { + "name": "UserSessionRevokeText", + "type": "string" + } + ] + } + } + } + }, + "parameters": { + "$connections": { + "value": { + "azuresentinel": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]", + "connectionName": "[[variables('AzureSentinelConnectionName')]", + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/azuresentinel')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + } + }, + "office365": { + "connectionId": "[[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "connectionName": "[[variables('Office365V1')]", + "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', variables('workspace-location-inline'), '/managedApis/office365')]" + } + } + } + } + }, + "tags": { + "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId2')]", + "contentId": "[variables('_playbookContentId2')]", + "kind": "Playbook", + "version": "[variables('playbookVersion2')]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ], + "metadata": { + "title": "SpyCloud Conditional Access Playbook", + "description": "Spycloud Conditional access playbook", + "prerequisites": "Create an App in App registration and provide permissions and create a client secret", + "lastUpdateTime": "2026-03-11T00:00:00Z", + "entities": [ + "account" + ], + "releaseNotes": { + "version": "1.0", + "title": "[variables('blanks')]", + "notes": [ + "Initial version" + ] + } + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId2')]", + "contentKind": "Playbook", + "displayName": "SpyCloud_Conditional_Access_Playbook", + "contentProductId": "[variables('_playbookcontentProductId2')]", + "id": "[variables('_playbookcontentProductId2')]", + "version": "[variables('playbookVersion2')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('playbookTemplateSpecName3')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "SpyCloud_AutomationRules Playbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('playbookVersion3')]", + "parameters": { + "Sentinel_Workspace_Resource_Id": { + "type": "string", + "metadata": { + "description": "Full resource ID of the Log Analytics workspace with Microsoft Sentinel enabled (e.g., /subscriptions/.../resourceGroups/.../providers/Microsoft.OperationalInsights/workspaces/...)" + } + }, + "MDE_PlaybookName": { + "type": "string", + "defaultValue": "SpyCloud_MDE_Automation", + "metadata": { + "description": "Name of the SpyCloud_MDE_Automation Logic App" + } + }, + "ConditionalAccess_PlaybookName": { + "type": "string", + "defaultValue": "SpyCloud_Conditional_Access_Playbook", + "metadata": { + "description": "Name of the SpyCloud_Conditional_Access_Playbook Logic App" + } + }, + "MalwareAnalyticRuleId": { + "type": "string", + "defaultValue": "ead4deed-9d48-4646-aee0-6b46c2dd1ae6", + "metadata": { + "description": "GUID of the SpyCloud infostealer malware credential exposure analytic rule (AR_malware_25) that triggers the MDE automation rule" + } + }, + "BreachedUsersAnalyticRuleId": { + "type": "string", + "defaultValue": "a25eba0e-ff42-4c97-a379-d76bdb2aa1e3", + "metadata": { + "description": "GUID of the SpyCloud plaintext credential exposure analytic rule (AR_Breached_Users_20) that triggers the Conditional Access automation rule" + } + }, + "MDE_Automation_Rule_Order": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Execution order of the MDE automation rule (lower = higher priority)" + } + }, + "ConditionalAccess_Automation_Rule_Order": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Execution order of the Conditional Access automation rule (lower = higher priority)" + } + } + }, + "variables": { + "mdeAutomationRuleName": "[[guid('SpyCloud-MDE-Rule', parameters('Sentinel_Workspace_Resource_Id'))]", + "conditionalAccessAutomationRuleName": "[[guid('SpyCloud-ConditionalAccess-Rule', parameters('Sentinel_Workspace_Resource_Id'))]", + "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]", + "workspace-name": "[parameters('workspace')]", + "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]" + }, + "resources": [ + { + "type": "Microsoft.SecurityInsights/automationRules", + "name": "[[variables('mdeAutomationRuleName')]", + "scope": "[[parameters('Sentinel_Workspace_Resource_Id')]", + "apiVersion": "2023-02-01-preview", + "properties": { + "displayName": "SpyCloud - Isolate compromised device on malware exposure", + "order": "[[parameters('MDE_Automation_Rule_Order')]", + "triggeringLogic": { + "isEnabled": true, + "triggersOn": "Incidents", + "triggersWhen": "Created", + "conditions": [ + { + "conditionType": "Property", + "conditionProperties": { + "propertyName": "IncidentRelatedAnalyticRuleIds", + "operator": "Contains", + "propertyValues": [ + "[[extensionResourceId(parameters('Sentinel_Workspace_Resource_Id'), 'Microsoft.SecurityInsights/alertRules', parameters('MalwareAnalyticRuleId'))]" + ] + } + } + ] + }, + "actions": [ + { + "order": 1, + "actionType": "RunPlaybook", + "actionConfiguration": { + "logicAppResourceId": "[[resourceId('Microsoft.Logic/workflows', parameters('MDE_PlaybookName'))]", + "tenantId": "[[subscription().tenantId]" + } + } + ] + } + }, + { + "type": "Microsoft.SecurityInsights/automationRules", + "name": "[[variables('conditionalAccessAutomationRuleName')]", + "scope": "[[parameters('Sentinel_Workspace_Resource_Id')]", + "apiVersion": "2023-02-01-preview", + "properties": { + "displayName": "SpyCloud - Enforce Conditional Access on credential exposure", + "order": "[[parameters('ConditionalAccess_Automation_Rule_Order')]", + "triggeringLogic": { + "isEnabled": true, + "triggersOn": "Incidents", + "triggersWhen": "Created", + "conditions": [ + { + "conditionType": "Property", + "conditionProperties": { + "propertyName": "IncidentRelatedAnalyticRuleIds", + "operator": "Contains", + "propertyValues": [ + "[[extensionResourceId(parameters('Sentinel_Workspace_Resource_Id'), 'Microsoft.SecurityInsights/alertRules', parameters('BreachedUsersAnalyticRuleId'))]" + ] + } + } + ] + }, + "actions": [ + { + "order": 1, + "actionType": "RunPlaybook", + "actionConfiguration": { + "logicAppResourceId": "[[resourceId('Microsoft.Logic/workflows', parameters('ConditionalAccess_PlaybookName'))]", + "tenantId": "[[subscription().tenantId]" + } + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]", + "properties": { + "parentId": "[variables('playbookId3')]", + "contentId": "[variables('_playbookContentId3')]", + "kind": "Playbook", + "version": "[variables('playbookVersion3')]", + "source": { + "kind": "Solution", + "name": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } + } + } + ], + "metadata": { + "title": "SpyCloud Enterprise Protection - Automation Rules", + "description": "Deploys automation rules that trigger the SpyCloud MDE Automation and SpyCloud Conditional Access playbooks when a matching SpyCloud analytic rule creates an incident.", + "prerequisites": [ + "1. The SpyCloud_MDE_Automation and SpyCloud_Conditional_Access_Playbook playbooks must be deployed in the same resource group.", + "2. The SpyCloud analytic rules (AR_malware_25, AR_Breached_Users_20) must be deployed to the same Microsoft Sentinel workspace.", + "3. Microsoft Sentinel must be enabled on the target Log Analytics workspace." + ], + "postDeployment": [ + "1. Verify the automation rules are visible in Microsoft Sentinel > Automation.", + "2. Grant each playbook's Managed Identity the Microsoft Sentinel Responder role if not already done." + ], + "lastUpdateTime": "2026-07-15T00:00:00Z", + "tags": [ + "Automation" + ], + "source": { + "type": "solution", + "name": "SpyCloud Enterprise Protection" + }, + "releaseNotes": [ + { + "version": "1.0.0", + "title": "SpyCloud Enterprise Protection - Automation Rules", + "notes": [ + "Initial version" + ] + } + ] + } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_playbookContentId3')]", + "contentKind": "Playbook", + "displayName": "SpyCloud_AutomationRules", + "contentProductId": "[variables('_playbookcontentProductId3')]", + "id": "[variables('_playbookcontentProductId3')]", + "version": "[variables('playbookVersion3')]" + } + }, + { + "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": "SpyCloud Enterprise Protection CCF", + "publisherDisplayName": "SpyCloud", + "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 SpyCloud Enterprise Protection solution for Microsoft Sentinel ingests SpyCloud breach watchlist and catalog data via the Codeless Connector Framework (CCF), including an optional Compass daily feed. The solution includes two built-in analytic rules, two KQL parsers, and two automation playbooks for Microsoft Defender for Endpoint and Azure AD / Entra ID Conditional Access response.

\n

Underlying Microsoft Technologies used:

\n

This solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:

\n
    \n
  1. Codeless Connector Framework (CCF)

    \n
  2. \n
  3. Azure Logic Apps

    \n
  4. \n
  5. Microsoft Defender for Endpoint

    \n
  6. \n
\n

Data Connectors: 1, Parsers: 2, Analytic Rules: 2, Playbooks: 3

\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": "SpyCloud Enterprise Protection CCF", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "SpyCloud", + "email": "[variables('_email')]" + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRuleObject1')._analyticRulecontentId1]", + "version": "[variables('analyticRuleObject1').analyticRuleVersion1]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRuleObject2')._analyticRulecontentId2]", + "version": "[variables('analyticRuleObject2').analyticRuleVersion2]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentIdConnections1')]", + "version": "[variables('dataConnectorCCPVersion')]" + }, + { + "kind": "Parser", + "contentId": "[variables('parserObject1').parserContentId1]", + "version": "[variables('parserObject1').parserVersion1]" + }, + { + "kind": "Parser", + "contentId": "[variables('parserObject2').parserContentId2]", + "version": "[variables('parserObject2').parserVersion2]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_SpyCloud_MDE_Automation')]", + "version": "[variables('playbookVersion1')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_SpyCloud_Conditional_Access_Playbook')]", + "version": "[variables('playbookVersion2')]" + }, + { + "kind": "Playbook", + "contentId": "[variables('_SpyCloud_AutomationRules')]", + "version": "[variables('playbookVersion3')]" + } + ] + }, + "firstPublishDate": "2026-06-09", + "lastPublishDate": "2026-06-09", + "providers": [ + "SpyCloud" + ], + "categories": { + "domains": [ + "Security - Threat Intelligence", + "Identity" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Package/testParameters.json b/Solutions/SpyCloud Enterprise Protection CCF/Package/testParameters.json new file mode 100644 index 00000000000..554801e41b7 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Package/testParameters.json @@ -0,0 +1,38 @@ +{ + "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" + } + }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "resource group name where Microsoft Sentinel is setup" + } + }, + "subscription": { + "type": "string", + "defaultValue": "[last(split(subscription().id, '/'))]", + "metadata": { + "description": "subscription id where Microsoft Sentinel is setup" + } + } +} diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_Spycloud_enriched_data.yaml b/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_Spycloud_enriched_data.yaml new file mode 100644 index 00000000000..af2da1a3167 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_Spycloud_enriched_data.yaml @@ -0,0 +1,102 @@ +id: ea883c92-ce82-4079-9e1d-5743349c3962 +Function: + Title: SpyCloud Enriched Data Parser + Version: '1.0.0' + LastUpdated: '2026-06-09' +Category: Microsoft Sentinel Parser +FunctionName: get_Spycloud_enriched_data +FunctionAlias: get_Spycloud_enriched_data +FunctionParams: + - Name: lookback + Type: timespan + Default: 1d +FunctionQuery: | + let _lookback = coalesce(lookback, 1d); + let LatestBreachCatalog = + SpyCloudBreachCatalogV2_CL + | summarize arg_max(TimeGenerated, BreachTitle, Description, Status) by SourceId + | project + SourceId, + BreachTitle, + CatalogDescription = Description, + CatalogStatus = Status; + SpyCloudBreachWatchlistV2_CL + | where TimeGenerated >= ago(_lookback) + | join kind=leftouter LatestBreachCatalog on SourceId + | project + TimeGenerated, + SourceId, + InfectedPath, + UserHostName, + IPAddresses, + TimeZone, + TargetUrl, + DocumentId, + TargetDomain, + UserSysRegisteredOwner, + DisplayResolution, + Password, + Email, + Severity, + AVSoftwares, + LogId, + UserOS, + EmailUsername, + SpyCloudPublishDate, + InfectedMachineId, + PasswordPlaintext, + InfectedTime, + CountryCode, + KeyboardLanguages, + PasswordType, + Domain, + EmailDomain, + TargetSubdomain, + Sighting, + AccountLastActivityTime, + AccountNotes, + AccountSignupTime, + Username, + Homepage, + Salt, + AccountLoginTime, + SocialOther, + LastName, + FullName, + Phone, + FirstName, + Address1, + AccountModificationTime, + Gender, + City, + BirthYear, + DOB, + CompanyWebsite, + Industry, + AccountStatus, + SocialCrunchbase, + CompanyName, + SocialLinkedIn, + SocialTwitter, + AccountCaption, + Address2, + SSNLastFour, + SocialSecurityNumber, + HealthInsuranceId, + PostalCode, + Age, + TaxId, + State, + AccountType, + DeviceName, + BankNumber, + MobileEquipmentId, + Country, + EducationalInstitution, + JobTitle, + AccountImageUrl, + StudentId, + AccountId, + BreachTitle, + CatalogDescription, + CatalogStatus diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_spycloud_compass_data.yaml b/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_spycloud_compass_data.yaml new file mode 100644 index 00000000000..b7261ef5126 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Parsers/get_spycloud_compass_data.yaml @@ -0,0 +1,20 @@ +id: 60e2f847-1c83-4099-9d2e-1401e3590798 +Function: + Title: SpyCloud Compass Data Parser + Version: '1.0.0' + LastUpdated: '2026-06-09' +Category: Microsoft Sentinel Parser +FunctionName: get_spycloud_compass_data +FunctionAlias: get_spycloud_compass_data +FunctionParams: + - Name: startTime + Type: timespan + Default: 1d +FunctionQuery: | + let _startTime = coalesce(startTime, 1d); + spycloud_compassV2_CL + | where TimeGenerated > ago(_startTime) + | project + TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, Email, Domain, + Password, PasswordPlaintext, Severity, IPAddresses, InfectedMachineId, + InfectedTime, BreachTitle, BreachCategory diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/azuredeploy.json b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/azuredeploy.json new file mode 100644 index 00000000000..c0cc5791ed1 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/azuredeploy.json @@ -0,0 +1,179 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "SpyCloud Enterprise Protection - Automation Rules", + "description": "Deploys automation rules that trigger the SpyCloud MDE Automation and SpyCloud Conditional Access playbooks when a matching SpyCloud analytic rule creates an incident.", + "prerequisites": [ + "1. The SpyCloud_MDE_Automation and SpyCloud_Conditional_Access_Playbook playbooks must be deployed in the same resource group.", + "2. The SpyCloud analytic rules (AR_malware_25, AR_Breached_Users_20) must be deployed to the same Microsoft Sentinel workspace.", + "3. Microsoft Sentinel must be enabled on the target Log Analytics workspace." + ], + "postDeployment": [ + "1. Verify the automation rules are visible in Microsoft Sentinel > Automation.", + "2. Grant each playbook's Managed Identity the Microsoft Sentinel Responder role if not already done." + ], + "lastUpdateTime": "2026-07-15T00:00:00.000Z", + "entities": [], + "tags": [ "Automation" ], + "support": { + "tier": "Partner", + "name": "SpyCloud", + "link": "https://support.spycloud.com" + }, + "source": { + "type": "solution", + "name": "SpyCloud Enterprise Protection" + }, + "author": { + "name": "SpyCloud" + }, + "releaseNotes": [ + { + "version": "1.0.0", + "title": "SpyCloud Enterprise Protection - Automation Rules", + "notes": [ "Initial version" ] + } + ] + }, + "parameters": { + "Sentinel_Workspace_Resource_Id": { + "type": "string", + "metadata": { + "description": "Full resource ID of the Log Analytics workspace with Microsoft Sentinel enabled (e.g., /subscriptions/.../resourceGroups/.../providers/Microsoft.OperationalInsights/workspaces/...)" + } + }, + "MDE_PlaybookName": { + "type": "string", + "defaultValue": "SpyCloud_MDE_Automation", + "metadata": { + "description": "Name of the SpyCloud_MDE_Automation Logic App" + } + }, + "ConditionalAccess_PlaybookName": { + "type": "string", + "defaultValue": "SpyCloud_Conditional_Access_Playbook", + "metadata": { + "description": "Name of the SpyCloud_Conditional_Access_Playbook Logic App" + } + }, + "MalwareAnalyticRuleId": { + "type": "string", + "defaultValue": "ead4deed-9d48-4646-aee0-6b46c2dd1ae6", + "metadata": { + "description": "GUID of the SpyCloud infostealer malware credential exposure analytic rule (AR_malware_25) that triggers the MDE automation rule" + } + }, + "BreachedUsersAnalyticRuleId": { + "type": "string", + "defaultValue": "a25eba0e-ff42-4c97-a379-d76bdb2aa1e3", + "metadata": { + "description": "GUID of the SpyCloud plaintext credential exposure analytic rule (AR_Breached_Users_20) that triggers the Conditional Access automation rule" + } + }, + "MDE_Automation_Rule_Order": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Execution order of the MDE automation rule (lower = higher priority)" + } + }, + "ConditionalAccess_Automation_Rule_Order": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Execution order of the Conditional Access automation rule (lower = higher priority)" + } + } + }, + "variables": { + "mdeAutomationRuleName": "[guid('SpyCloud-MDE-Rule', parameters('Sentinel_Workspace_Resource_Id'))]", + "conditionalAccessAutomationRuleName": "[guid('SpyCloud-ConditionalAccess-Rule', parameters('Sentinel_Workspace_Resource_Id'))]" + }, + "resources": [ + { + "type": "Microsoft.SecurityInsights/automationRules", + "name": "[variables('mdeAutomationRuleName')]", + "scope": "[parameters('Sentinel_Workspace_Resource_Id')]", + "apiVersion": "2023-02-01-preview", + "properties": { + "displayName": "SpyCloud - Isolate compromised device on malware exposure", + "order": "[parameters('MDE_Automation_Rule_Order')]", + "triggeringLogic": { + "isEnabled": true, + "triggersOn": "Incidents", + "triggersWhen": "Created", + "conditions": [ + { + "conditionType": "Property", + "conditionProperties": { + "propertyName": "IncidentRelatedAnalyticRuleIds", + "operator": "Contains", + "propertyValues": [ + "[extensionResourceId(parameters('Sentinel_Workspace_Resource_Id'), 'Microsoft.SecurityInsights/alertRules', parameters('MalwareAnalyticRuleId'))]" + ] + } + } + ] + }, + "actions": [ + { + "order": 1, + "actionType": "RunPlaybook", + "actionConfiguration": { + "logicAppResourceId": "[resourceId('Microsoft.Logic/workflows', parameters('MDE_PlaybookName'))]", + "tenantId": "[subscription().tenantId]" + } + } + ] + } + }, + { + "type": "Microsoft.SecurityInsights/automationRules", + "name": "[variables('conditionalAccessAutomationRuleName')]", + "scope": "[parameters('Sentinel_Workspace_Resource_Id')]", + "apiVersion": "2023-02-01-preview", + "properties": { + "displayName": "SpyCloud - Enforce Conditional Access on credential exposure", + "order": "[parameters('ConditionalAccess_Automation_Rule_Order')]", + "triggeringLogic": { + "isEnabled": true, + "triggersOn": "Incidents", + "triggersWhen": "Created", + "conditions": [ + { + "conditionType": "Property", + "conditionProperties": { + "propertyName": "IncidentRelatedAnalyticRuleIds", + "operator": "Contains", + "propertyValues": [ + "[extensionResourceId(parameters('Sentinel_Workspace_Resource_Id'), 'Microsoft.SecurityInsights/alertRules', parameters('BreachedUsersAnalyticRuleId'))]" + ] + } + } + ] + }, + "actions": [ + { + "order": 1, + "actionType": "RunPlaybook", + "actionConfiguration": { + "logicAppResourceId": "[resourceId('Microsoft.Logic/workflows', parameters('ConditionalAccess_PlaybookName'))]", + "tenantId": "[subscription().tenantId]" + } + } + ] + } + } + ], + "outputs": { + "mdeAutomationRuleId": { + "type": "string", + "value": "[variables('mdeAutomationRuleName')]" + }, + "conditionalAccessAutomationRuleId": { + "type": "string", + "value": "[variables('conditionalAccessAutomationRuleName')]" + } + } +} diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/readme.md b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/readme.md new file mode 100644 index 00000000000..bdd58a50c18 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_AutomationRules/readme.md @@ -0,0 +1,37 @@ +# SpyCloud Automation Rules + +This template deploys two Microsoft Sentinel automation rules that connect the SpyCloud analytic rules to the SpyCloud response playbooks, so incidents are automatically routed to the right automation without manual configuration. + +| Automation Rule | Triggers On | Runs Playbook | +|---|---|---| +| SpyCloud - Isolate compromised device on malware exposure | Incident created from **AR_malware_25** (SpyCloud infostealer malware credential exposure) | `SpyCloud_MDE_Automation` | +| SpyCloud - Enforce Conditional Access on credential exposure | Incident created from **AR_Breached_Users_20** (SpyCloud plaintext credential exposure detected) | `SpyCloud_Conditional_Access_Playbook` | + +## Prerequisites + +- The `SpyCloud_MDE_Automation` and `SpyCloud_Conditional_Access_Playbook` playbooks must already be deployed in the same resource group +- The `AR_malware_25` and `AR_Breached_Users_20` analytic rules must already be deployed to the target Microsoft Sentinel workspace +- Each playbook's Managed Identity must have the **Microsoft Sentinel Responder** role on the workspace (grant this after deployment if not already assigned) + +## Deployment + +1. In the Azure Portal, navigate to **Deploy a custom template** +2. Select this template (`azuredeploy.json`) +3. Confirm Subscription and Resource Group +4. Enter the full resource ID of your Sentinel-enabled Log Analytics workspace for **Sentinel_Workspace_Resource_Id** +5. Leave the playbook name and analytic rule ID parameters at their defaults unless you renamed those resources during deployment +6. Click **Review + Create**, then **Create** + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| Sentinel_Workspace_Resource_Id | String | — | Full resource ID of the Sentinel-enabled Log Analytics workspace | +| MDE_PlaybookName | String | SpyCloud_MDE_Automation | Name of the MDE automation playbook Logic App | +| ConditionalAccess_PlaybookName | String | SpyCloud_Conditional_Access_Playbook | Name of the Conditional Access playbook Logic App | +| MalwareAnalyticRuleId | String | ead4deed-9d48-4646-aee0-6b46c2dd1ae6 | GUID of AR_malware_25 | +| BreachedUsersAnalyticRuleId | String | a25eba0e-ff42-4c97-a379-d76bdb2aa1e3 | GUID of AR_Breached_Users_20 | +| MDE_Automation_Rule_Order | Int | 1 | Execution order of the MDE automation rule | +| ConditionalAccess_Automation_Rule_Order | Int | 2 | Execution order of the Conditional Access automation rule | + +After deployment, confirm both rules appear under **Microsoft Sentinel → Automation** and are enabled. diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/azuredeploy.json b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/azuredeploy.json new file mode 100644 index 00000000000..60985056acb --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/azuredeploy.json @@ -0,0 +1,864 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "title": "SpyCloud Conditional Access Playbook", + "description": "Spycloud Conditional access playbook", + "prerequisites": "Create an App in App registration and provide permissions and create a client secret", + "lastUpdateTime": "2026-03-11T00:00:00.000Z", + "entities": [ + "account" + ], + "tags": [], + "support": { + "tier": "community", + "armtemplate": "Generated from https://github.com/Azure/Azure-Sentinel/tree/master/Tools/Playbook-ARM-Template-Generator" + }, + "author": { + "name": "SpyCloud" + } + }, + "parameters": { + "PlaybookName": { + "defaultValue": "SpyCloud_Conditional_Access_Playbook", + "type": "string" + } + }, + "variables": { + "loginUrl": "[environment().authentication.loginEndpoint]", + "AzureSentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]", + "Office365V1": "[concat('office365-', parameters('PlaybookName'))]", + "subscription": "[last(split(subscription().id, '/'))]", + "resourceGroupName": "[resourceGroup().name]" + }, + "resources": [ + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('Office365V1')]", + "location": "[resourceGroup().location]", + "properties": { + "displayName": "[variables('Office365V1')]", + "customParameterValues": {}, + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('AzureSentinelConnectionName')]", + "location": "[resourceGroup().location]", + "kind": "V1", + "properties": { + "displayName": "[variables('AzureSentinelConnectionName')]", + "customParameterValues": {}, + "parameterValueType": "Alternative", + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2017-07-01", + "name": "[parameters('PlaybookName')]", + "location": "[resourceGroup().location]", + "identity": { + "type": "SystemAssigned" + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]" + ], + "properties": { + "state": "Disabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "defaultValue": {}, + "type": "Object" + }, + "PlaybookName": { + "defaultValue": "[parameters('PlaybookName')]", + "type": "String" + }, + "Notify_Users_Emails": { + "type": "String" + }, + "Force_Password_Reset_On_Next_SignIn": { + "type": "Bool", + "defaultValue": false + }, + "Disable_User": { + "type": "Bool", + "defaultValue": false + }, + "Add_User_To_Azure_CA_Group": { + "type": "Bool", + "defaultValue": false + }, + "Azure_CA_Group_Object_ID": { + "type": "String" + }, + "Revoke_User_Sessions": { + "type": "Bool", + "defaultValue": false + }, + "ClientID": { + "type": "String" + }, + "TenantID": { + "type": "String" + }, + "ClientSecret": { + "type": "String" + }, + "DCE_Endpoint": { + "type": "String" + }, + "DCE_Immutable_ID": { + "type": "String" + }, + "Custom_Table_Name": { + "type": "String", + "defaultValue": "SpyCloud_ConditionalAccessLogsV2_CL" + } + }, + "triggers": { + "Microsoft_Sentinel_incident": { + "type": "ApiConnectionWebhook", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "body": { + "callback_url": "@{listCallbackUrl()}" + }, + "path": "/incident-creation" + } + } + }, + "actions": { + "Entities_-_Get_Accounts": { + "runAfter": { + "For_each_incident_alert": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/account" + } + }, + "For_each": { + "foreach": "@body('Entities_-_Get_Accounts')?['Accounts']", + "actions": { + "Get_User_Details": { + "runAfter": { + "Set_user": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}?$select=id,displayName,accountEnabled,lastPasswordChangeDateTime,userPrincipalName", + "method": "GET", + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_user": { + "type": "SetVariable", + "inputs": { + "name": "user_email", + "value": "@{concat(items('For_each')?['Name'],'@',items('for_each')?['UPNSuffix'])}" + } + }, + "Condition_-_Check_if_user_is_enabled": { + "actions": { + "Condition_Check_if_password_has_not_been_reset_since_7_days": { + "actions": { + "Condition_-_Check_if_user_needs_to_be_added_to_CA_group_": { + "actions": { + "Add_user_to_Conditional_Access_Group": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/groups/@{parameters('Azure_CA_Group_Object_ID')}/members/$ref", + "method": "POST", + "body": { + "@@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/@{body('Get_User_Details')?['id']}" + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_Added_To_CA_Group_Enforced": { + "runAfter": { + "Add_user_to_Conditional_Access_Group": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AddedToCAGroupEnforced", + "value": true + } + }, + "Set_Added_To_CA_Group_Enforced_Text": { + "runAfter": { + "Set_Added_To_CA_Group_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AddedToCAGroupText", + "value": "Successfully added the user to Conditional Access Group." + } + } + }, + "runAfter": { + "Condition_-_Check_Revoke_User_Sessions": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Add_User_To_Azure_CA_Group')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_If_User_needs_to_be_disabled": { + "actions": { + "HTTP_-_Disable_User": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}", + "method": "PATCH", + "body": { + "accountEnabled": false + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + } + }, + "Set_Account_Disabled_": { + "runAfter": { + "HTTP_-_Disable_User": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountDisabledEnforced", + "value": true + } + }, + "Set_Account_Disabled_Text": { + "runAfter": { + "Set_Account_Disabled_": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "AccountDisabledText", + "value": "The User has been successfully Disabled." + } + } + }, + "runAfter": { + "Condition_-_Check_if_user_needs_to_be_added_to_CA_group_": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Disable_User')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Check_Revoke_User_Sessions": { + "actions": { + "HTTP_-_Revoke_User_Sessions": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}/revokeSignInSessions", + "method": "POST", + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_User_Session_Enforced": { + "runAfter": { + "HTTP_-_Revoke_User_Sessions": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "UserSessionsRevokeEnforced", + "value": true + } + }, + "Set_User_Session_Revoke_Text": { + "runAfter": { + "Set_User_Session_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "UserSessionRevokeText", + "value": "User sessions has been successfully revoked." + } + } + }, + "runAfter": { + "Condition-Check_for_Password_Reset": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Revoke_User_Sessions')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition-Check_for_Password_Reset": { + "actions": { + "Force_Password_Reset": { + "type": "Http", + "inputs": { + "uri": "https://graph.microsoft.com/v1.0/users/@{variables('user_email')}", + "method": "PATCH", + "body": { + "passwordProfile": { + "forceChangePasswordNextSignIn": true + } + }, + "authentication": { + "type": "ActiveDirectoryOAuth", + "authority": "@{variables('Authority')}", + "tenant": "@{parameters('TenantID')}", + "audience": "@{variables('Audience')}", + "clientId": "@{parameters('ClientID')}", + "secret": "@{parameters('ClientSecret')}" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_Passwod_Reset_Enforced": { + "runAfter": { + "Force_Password_Reset": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PasswordResetEnforced", + "value": true + } + }, + "Set_Password_Reset_Text": { + "runAfter": { + "Set_Passwod_Reset_Enforced": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "PasswordResetText", + "value": "Password has been successfully reset" + } + } + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Force_Password_Reset_On_Next_SignIn')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Add_comment_to_incident": { + "runAfter": { + "Condition_-_If_User_needs_to_be_disabled": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) the following actions were done from the Spycloud playbook. Manager () is notified.

@{variables('PasswordResetText')}

@{variables('AddedToCAGroupText')}

@{variables('UserSessionRevokeText')}

@{variables('AccountDisabledText')}


" + }, + "path": "/Incidents/Comment" + } + }, + "Send_an_email_-_to_manager_": { + "runAfter": { + "Add_comment_to_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['office365']['connectionId']" + } + }, + "method": "post", + "body": { + "To": "@parameters('Notify_Users_Emails')", + "Subject": "@{items('For_each')?['Name']} - security risk!", + "Body": "

Security notification! This is automated email sent by Microsoft Sentinel SpyCloud Automation!

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) the following actions were done from the Spycloud playbook.
@{variables('PasswordResetText')}
@{variables('AddedToCAGroupText')}
@{variables('UserSessionRevokeText')}
@{variables('AccountDisabledText')}




Can you please notify the user and work with him to reach our support.


", + "Importance": "High" + }, + "path": "/v2/Mail" + } + } + }, + "else": { + "actions": { + "Add_comment_to_incident_-_Password_Latest": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) no actions were done from the Spycloud playbook.


Reason: Password has been reset after the breached date by the user.





" + }, + "path": "/Incidents/Comment" + } + } + } + }, + "expression": { + "and": [ + { + "less": [ + "@addToDateTime(parseDateTime(body('Get_User_Details')?['lastPasswordChangeDateTime']), 7, 'Day')", + "@parseDateTime(variables('SpyCloudPublishDate'))" + ] + } + ] + }, + "type": "If" + }, + "GetAccessToken": { + "runAfter": { + "Condition_Check_if_password_has_not_been_reset_since_7_days": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('ClientSecret')}&scope=https://monitor.azure.com/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Log_ingestion": { + "runAfter": { + "GetAccessToken": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@variables('log_ingestion_api')", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('GetAccessToken')?['access_token']}", + "Content-Type": "application/json" + }, + "body": [ + { + "TimeGenerated": "@{utcNow()}", + "IncidentId": "@{triggerBody()?['object']?['properties']?['providerIncidentId']}", + "DocumentId": "@{variables('DocumentID')}", + "SpyCloudPublishDate": "@{variables('SpyCloudPublishDate')}", + "InfectedTime": "@{variables('InfectedTime')}", + "BreachTitle": "@{variables('BreachTitle')}", + "InfectedMachineId": "@{variables('InfectedMachineId')}", + "Username": "@{variables('user_email')}", + "UserEmail": "@{variables('user_email')}", + "ForcedPasswordResetOnNextSignIn": "@variables('PasswordResetEnforced')", + "UserSessionsRevoked": "@variables('UserSessionsRevokeEnforced')", + "CAgroup": "@variables('AddedToCAGroupEnforced')", + "UserDisabled": "@variables('AccountDisabledEnforced')", + "PlaybookName": "SpyCloud_Conditonal_Access_Automation" + } + ] + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + } + }, + "runAfter": { + "Get_User_Details": [ + "Succeeded" + ] + }, + "else": { + "actions": { + "Add_comment_to_incident_-_user_disable": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": { + "incidentArmId": "@triggerBody()?['object']?['id']", + "message": "

For User @{items('For_each')?['Name']} (UPN -@{variables('user_email')} ) no actions were done from the Spycloud playbook.


Reason: The user is currently disabled..



" + }, + "path": "/Incidents/Comment" + } + } + } + }, + "expression": { + "and": [ + { + "equals": [ + "@body('Get_User_Details')?['accountEnabled']", + "@true" + ] + } + ] + }, + "type": "If" + } + }, + "runAfter": { + "Entities_-_Get_Accounts": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_incident_alert": { + "foreach": "@triggerBody()?['object']?['properties']?['Alerts']", + "actions": { + "Set_custom_details_object": { + "type": "SetVariable", + "inputs": { + "name": "incident_custom_details_object", + "value": "@json(items('For_each_incident_alert')?['properties']?['additionalData']?['Custom Details'])" + } + }, + "Set_Spycloud_publish_date": { + "runAfter": { + "Set_custom_details_object": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SpyCloudPublishDate", + "value": "@first(coalesce(variables('incident_custom_details_object')?['SpyCloudPublishDate'], createArray('')))" + } + }, + "Set_Infected_Time": { + "runAfter": { + "Set_Spycloud_publish_date": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedTime", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedTime'], createArray('')))" + } + }, + "Set_Breach_Title": { + "runAfter": { + "Set_Infected_Time": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "BreachTitle", + "value": "@first(coalesce(variables('incident_custom_details_object')?['BreachTitle'], createArray('')))\n" + } + }, + "Set_Infected_Machine_ID": { + "runAfter": { + "Set_Breach_Title": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedMachineId", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedMachineId'], createArray('')))" + } + }, + "Set_Document_ID": { + "runAfter": { + "Set_Infected_Machine_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "DocumentID", + "value": "@first(coalesce(variables('incident_custom_details_object')?['DocumentID'], createArray('')))" + } + }, + "Set_log_ingestion_api_url": { + "runAfter": { + "Set_Document_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "log_ingestion_api", + "value": "@concat(concat(concat(parameters('DCE_Endpoint'),'/dataCollectionRules/'),parameters('DCE_Immutable_ID') ),concat('/streams/Custom-',concat(parameters('Custom_Table_Name'), '?api-version=2023-01-01') ))" + } + } + }, + "runAfter": { + "variables_Section": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "variables_Section": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "incident_custom_details_object", + "type": "object" + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "DocumentID", + "type": "string" + }, + { + "name": "last_password_reset_date", + "type": "string" + }, + { + "name": "Authority", + "type": "string", + "value": "[variables('loginUrl')]" + }, + { + "name": "Audience", + "type": "string", + "value": "https://graph.microsoft.com" + }, + { + "name": "user_email", + "type": "string" + }, + { + "name": "log_ingestion_api", + "type": "string" + }, + { + "name": "PasswordResetEnforced", + "type": "boolean", + "value": false + }, + { + "name": "AccountDisabledEnforced", + "type": "boolean", + "value": false + }, + { + "name": "AddedToCAGroupEnforced", + "type": "boolean", + "value": false + }, + { + "name": "PasswordResetText", + "type": "string" + }, + { + "name": "AccountDisabledText", + "type": "string" + }, + { + "name": "AddedToCAGroupText", + "type": "string" + }, + { + "name": "UserSessionsRevokeEnforced", + "type": "boolean", + "value": false + }, + { + "name": "UserSessionRevokeText", + "type": "string" + } + ] + } + } + }, + "outputs": {} + }, + "parameters": { + "$connections": { + "value": { + "azuresentinel": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]", + "connectionName": "[variables('AzureSentinelConnectionName')]", + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + } + }, + "office365": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "connectionName": "[variables('Office365V1')]", + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]" + } + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/readme.md b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/readme.md new file mode 100644 index 00000000000..ed19c7d84f2 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_Conditional_Access_Playbook/readme.md @@ -0,0 +1,54 @@ +# SpyCloud Conditional Access Playbook + +This playbook automates Azure AD / Entra ID identity response actions when SpyCloud breach data identifies compromised user credentials. + +**Capabilities** +- Account disablement +- Session revocation across all applications +- Forced password reset at next sign-in +- Conditional Access group membership enforcement +- Email notifications +- Execution log ingestion to `SpyCloud_ConditionalAccessLogsV2_CL` + +## Prerequisites + +- App Registration with the Microsoft Graph permissions listed in the [Integration Guide](../../SpyCloud_Sentinel_Integration_Guide.md), Section 2.1 +- DCR Immutable ID and DCE Logs Ingestion Endpoint URL for `SpyCloud_ConditionalAccessLogsV2_CL` (Section 2.2) +- Monitoring Metrics Publisher role assigned to the App Registration on that DCR +- Object ID of the Azure AD Conditional Access enforcement group (if using group membership actions) + +## Deployment + +1. In the Azure Portal, navigate to **Deploy a custom template** +2. Select this template (`azuredeploy.json`) +3. Confirm Subscription, Resource Group, and Region +4. Enter a value for **PlaybookName** (this is the only ARM deployment-time parameter) +5. Click **Review + Create**, then **Create** +6. Authorize the `office365` and `azuresentinel` API connections created by the deployment + +## Post-deployment configuration + +All other settings are **workflow parameters**, baked into the Logic App with default values. After the playbook is deployed, update them with your own values: + +1. Navigate to the Microsoft Sentinel workspace, open **Automation**, and select the `SpyCloud_Conditional_Access_Playbook` playbook — or go directly to the Logic App resource in the Azure Portal +2. Open the Logic App and click **Edit** to open the workflow designer +3. Open the **Parameters** section (in the designer toolbar, or under **Development Tools → Workflow parameters**) +4. For each parameter listed below, enter the appropriate value for your environment +5. Click **Save** to apply the changes to the playbook + +| Parameter | Type | Default | Description | +|---|---|---|---| +| Notify_Users_Emails | String | (empty) | Email address(es) for notifications, semicolon-separated | +| Force_Password_Reset_On_Next_SignIn | Bool | false | Forces password reset at next sign-in for affected users | +| Disable_User | Bool | false | Disables affected Azure AD user accounts | +| Add_User_To_Azure_CA_Group | Bool | false | Adds affected users to the Conditional Access enforcement group | +| Azure_CA_Group_Object_ID | String | (empty) | Object ID of the Azure AD Conditional Access group | +| Revoke_User_Sessions | Bool | false | Revokes all active sign-in sessions for affected users | +| ClientID | String | (empty) | App Registration Client ID | +| TenantID | String | (empty) | Azure Tenant ID | +| ClientSecret | String | (empty) | App Registration Client Secret | +| DCE_Endpoint | String | (empty) | DCE Logs Ingestion Endpoint URL for CA logs | +| DCE_Immutable_ID | String | (empty) | DCR Immutable ID for `SpyCloud_ConditionalAccessLogsV2_CL` | +| Custom_Table_Name | String | SpyCloud_ConditionalAccessLogsV2_CL | Custom Log Analytics table for playbook logs | + +After saving workflow parameters, confirm `SpyCloud_Conditional_Access_Playbook` shows status **Enabled** and check Run History for immediate failures. diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/azuredeploy.json b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/azuredeploy.json new file mode 100644 index 00000000000..95096ca2cbb --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/azuredeploy.json @@ -0,0 +1,965 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "PlaybookName": { + "defaultValue": "SpyCloud_MDE_Automation", + "type": "string" + } + }, + "variables": { + "loginUrl": "[environment().authentication.loginEndpoint]", + "AzureSentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]", + "Office365V1": "[concat('office365-', parameters('PlaybookName'))]", + "WDATPConnection": "[concat('wdatp-', parameters('PlaybookName'))]" + }, + "resources": [ + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('Office365V1')]", + "location": "[resourceGroup().location]", + "properties": { + "displayName": "[variables('Office365V1')]", + "customParameterValues": {}, + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('WDATPConnection')]", + "location": "[resourceGroup().location]", + "properties": { + "displayName": "WDATP Connection", + "customParameterValues": {}, + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/wdatp')]" + } + } + }, + { + "type": "Microsoft.Web/connections", + "apiVersion": "2016-06-01", + "name": "[variables('AzureSentinelConnectionName')]", + "location": "[resourceGroup().location]", + "kind": "V1", + "properties": { + "displayName": "[variables('AzureSentinelConnectionName')]", + "customParameterValues": {}, + "parameterValueType": "Alternative", + "api": { + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]" + } + } + }, + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2017-07-01", + "name": "[parameters('PlaybookName')]", + "location": "[resourceGroup().location]", + "identity": { + "type": "SystemAssigned" + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "[resourceId('Microsoft.Web/connections', variables('WDATPConnection'))]", + "[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]" + ], + "properties": { + "state": "Disabled", + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "$connections": { + "defaultValue": {}, + "type": "Object" + }, + "PlaybookName": { + "defaultValue": "[parameters('PlaybookName')]", + "type": "String" + }, + "Isolate_Machine": { + "type": "Bool", + "defaultValue": false + }, + "Machine_Tag_Value": { + "type": "String" + }, + "Save_IOCs_Defender": { + "type": "Bool", + "defaultValue": false + }, + "IOC_Expiration_Days": { + "type": "Int", + "defaultValue": 30 + }, + "Spycloud_Defender_DCE_Endpoint": { + "type": "String" + }, + "Spycloud_Defender_DCE_Immutable_ID": { + "type": "String" + }, + "TenantID": { + "type": "String" + }, + "ClientID": { + "type": "String" + }, + "Client_Secret": { + "type": "String" + }, + "Ingestion_Table_Name": { + "type": "String", + "defaultValue": "Spycloud_MDE_LogsV2_CL" + }, + "create_incident_in_sentinel": { + "type": "Bool", + "defaultValue": false + }, + "Workspace_Name": { + "type": "String", + "defaultValue": "Your workspace name" + }, + "Defender_IOC_Action_Type": { + "type": "String", + "defaultValue": "Alert" + }, + "notification_email": { + "type": "String" + } + }, + "triggers": { + "Microsoft_Sentinel_incident": { + "type": "ApiConnectionWebhook", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "body": { + "callback_url": "@listCallbackUrl()" + }, + "path": "/incident-creation" + } + } + }, + "actions": { + "Entities_-_Get_Hosts": { + "runAfter": { + "For_each_incident_alert": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/host" + } + }, + "For_each": { + "foreach": "@body('Entities_-_Get_Hosts')?['Hosts']", + "actions": { + "Machines_-_Get_single_machine": { + "runAfter": { + "Set_host_name": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "get", + "path": "/api/machines/@variables('host_name')" + } + }, + "GetAccessToken": { + "runAfter": { + "Send_an_email_(V2)": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('Client_Secret')}&scope=https://monitor.azure.com/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Log_ingestion": { + "runAfter": { + "GetAccessToken": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@variables('log_ingestion_api')", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('GetAccessToken')?['access_token']}", + "Content-Type": "application/json" + }, + "body": [ + { + "TimeGenerated": "@{utcNow()}", + "IncidentId": "@{body('Create_incident')?['properties']?['providerIncidentId']}", + "DocumentId": "@{variables('DocumentID')}", + "SpyCloudPublishDate": "@{variables('SpyCloudPublishDate')}", + "InfectedTime": "@{variables('InfectedTime')}", + "BreachTitle": "@{variables('BreachTitle')}", + "InfectedMachineId": "@{variables('InfectedMachineId')}", + "HostName": "@{coalesce(body('Machines_-_Get_single_machine')?['computerDnsName'], '')}", + "NormalizedHostName": "@{toLower(coalesce(body('Machines_-_Get_single_machine')?['computerDnsName'], ''))}", + "DeviceId": "@{coalesce(body('Machines_-_Get_single_machine')?['id'], '')}", + "OSPlatform": "@{coalesce(body('Machines_-_Get_single_machine')?['osPlatform'], '')}", + "RiskScore": "@{coalesce(body('Machines_-_Get_single_machine')?['riskScore'], '')}", + "ExposureLevel": "@{coalesce(body('Machines_-_Get_single_machine')?['exposureLevel'], '')}", + "IsolationRequested": "@variables('machine_isolated')", + "IsolationStatus": "@variables('machine_isolated')", + "MachineTagAdded": "@variables('machine_tag_added')", + "MachineTagName": "@{parameters('Machine_Tag_Value')}", + "AddedIOCsToDefender": "@variables('defender_iocs_added')", + "PlaybookName": "[parameters('PlaybookName')]" + } + ] + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_host_name": { + "type": "SetVariable", + "inputs": { + "name": "host_name", + "value": "@item()?['HostName']" + } + }, + "Check_Create_Sentinel_Incident": { + "actions": { + "Create_incident": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "put", + "body": { + "title": "Spycloud MDE Alert - Machine Comprised @{variables('host_name')}", + "severity": "High", + "status": "Active", + "description": "The Incident is created from Spycloud MDE Automation Playbook" + }, + "path": "[concat('/Incidents/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/workspaces/', parameters('Workspace_Name'))]" + } + } + }, + "runAfter": { + "Machines_-_Get_single_machine": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('create_incident_in_sentinel')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_Isolate_Machine": { + "actions": { + "Condition_-_Check_Machine_is_Active": { + "actions": { + "Set_-_machine_active_to_true": { + "type": "SetVariable", + "inputs": { + "name": "is_machine_active", + "value": true + } + } + }, + "else": { + "actions": { + "Set_machine_active_to_false": { + "type": "SetVariable", + "inputs": { + "name": "is_machine_active", + "value": false + } + } + } + }, + "expression": { + "and": [ + { + "equals": [ + "@body('Machines_-_Get_single_machine')?['healthStatus']", + "Active" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Check_if_the_machine_is_lastseen_in_the_last_6_hours": { + "actions": { + "Set_last_active": { + "type": "SetVariable", + "inputs": { + "name": "is_last_sees_satisfied", + "value": true + } + } + }, + "runAfter": { + "Condition_-_Check_Machine_is_Active": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "greater": [ + "@ticks(body('Machines_-_Get_single_machine')?['lastSeen'])", + "@ticks(addHours(utcNow(), -6))" + ] + } + ] + }, + "type": "If" + }, + "Condition_If_we_can_Isolate_the_machine": { + "actions": { + "Actions_-_Isolate_machine": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "post", + "body": { + "Comment": "This machine has found comprised - SpyCloud", + "IsolationType": "Selective" + }, + "path": "/api/machines/@{encodeURIComponent(body('Machines_-_Get_single_machine')?['id'])}/isolate" + } + }, + "set_machine_isolatyed": { + "runAfter": { + "Actions_-_Isolate_machine": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "machine_isolated", + "value": true + } + } + }, + "runAfter": { + "Condition_-_Check_if_the_machine_is_lastseen_in_the_last_6_hours": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@variables('is_machine_active')", + "@true" + ] + }, + { + "equals": [ + "@variables('is_last_sees_satisfied')", + "@true" + ] + } + ] + }, + "type": "If" + } + }, + "runAfter": { + "Check_Create_Sentinel_Incident": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Isolate_Machine')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "Condition_-_Add_Machine_Tag": { + "actions": { + "Machines_-_Tag_machine": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['wdatp']['connectionId']" + } + }, + "method": "post", + "body": { + "Value": "@parameters('Machine_Tag_Value')", + "Action": "Add" + }, + "path": "/api/machines/@{encodeURIComponent(body('Machines_-_Get_single_machine')?['id'])}/tags" + } + }, + "Set_machine_tag_added": { + "runAfter": { + "Machines_-_Tag_machine": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "machine_tag_added", + "value": true + } + } + }, + "runAfter": { + "Condition_Isolate_Machine": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "greater": [ + "@length(parameters('Machine_Tag_Value'))", + 0 + ] + } + ] + }, + "type": "If" + }, + "Send_an_email_(V2)": { + "runAfter": { + "Condition_-_Add_Machine_Tag": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['office365']['connectionId']" + } + }, + "method": "post", + "body": { + "To": "@parameters('notification_email')", + "Subject": "@{variables('host_name')} - Security Risk", + "Body": "

Security notification! This is automated email sent by Microsoft Sentinel SpyCloud Automation!


For Host @{variables('host_name')} the following actions were taken


Machine Tag Added : @{variables('machine_tag_added')},

Machine Tag Value : @{parameters('Machine_Tag_Value')},

Machine Isolated: @{variables('machine_isolated')}

", + "Importance": "Normal" + }, + "path": "/v2/Mail" + } + } + }, + "runAfter": { + "Condition_Save_IOCS_in_Defender": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "Variables_Section": { + "runAfter": {}, + "type": "InitializeVariable", + "inputs": { + "variables": [ + { + "name": "log_ingestion_api", + "type": "string", + "value": "@{concat(concat(concat(parameters('Spycloud_Defender_DCE_Endpoint'),'/dataCollectionRules/'),parameters('Spycloud_Defender_DCE_Immutable_ID') ),concat('/streams/Custom-',concat(parameters('Ingestion_Table_Name'), '?api-version=2023-01-01') ))}" + }, + { + "name": "access_token_url", + "type": "string", + "value": "test" + }, + { + "name": "log_ingestion_url", + "type": "string", + "value": "test" + }, + { + "name": "host_name", + "type": "string", + "value": " " + }, + { + "name": "defender_iocs_object", + "type": "array", + "value": [] + }, + { + "name": "machine_isolated", + "type": "boolean", + "value": false + }, + { + "name": "machine_tag_added", + "type": "boolean", + "value": false + }, + { + "name": "defender_iocs_added", + "type": "boolean", + "value": false + }, + { + "name": "SpyCloudPublishDate", + "type": "string" + }, + { + "name": "InfectedTime", + "type": "string" + }, + { + "name": "BreachTitle", + "type": "string" + }, + { + "name": "InfectedMachineId", + "type": "string" + }, + { + "name": "DocumentID", + "type": "string" + }, + { + "name": "incident_custom_details_object", + "type": "object" + }, + { + "name": "is_machine_onboarded", + "type": "boolean" + }, + { + "name": "is_machine_active", + "type": "boolean", + "value": false + }, + { + "name": "is_machine_excluded", + "type": "boolean", + "value": false + }, + { + "name": "is_last_sees_satisfied", + "type": "boolean", + "value": false + } + ] + } + }, + "Condition_Save_IOCS_in_Defender": { + "actions": { + "Entities_-_Get_DNS": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/dnsresolution" + } + }, + "Entities_-_Get_IPs": { + "runAfter": { + "For_each_Domains_in_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/ip" + } + }, + "Entities_-_Get_URLs": { + "runAfter": { + "For_each_IPs_in_incident": [ + "Succeeded" + ] + }, + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "name": "@parameters('$connections')['azuresentinel']['connectionId']" + } + }, + "method": "post", + "body": "@triggerBody()?['object']?['properties']?['relatedEntities']", + "path": "/entities/url" + } + }, + "For_each_Domains_in_incident": { + "foreach": "@body('Entities_-_Get_DNS')?['Dnsresolutions']", + "actions": { + "Domain_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "@parameters('Defender_IOC_Action_Type')", + "description": "SpyCloud MDE Playbook", + "indicatorType": "DomainName", + "indicatorValue": "@item()?['DomainName']", + "title": "SpyCloud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object": { + "runAfter": { + "Domain_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('Domain_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_DNS": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_IPs_in_incident": { + "foreach": "@body('Entities_-_Get_IPs')?['IPs']", + "actions": { + "IP_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "Block", + "description": "SpyCloiud MDE Playbook", + "indicatorType": "IpAddress", + "indicatorValue": "@item()?['Address']", + "title": "SpyCloiud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object_1": { + "runAfter": { + "IP_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('IP_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_IPs": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "For_each_Url_in_incident": { + "foreach": "@body('Entities_-_Get_URLs')?['URLs']", + "actions": { + "Url_IOC_Obejct": { + "type": "Compose", + "inputs": { + "action": "Block", + "description": "SpyCloiud MDE Playbook", + "indicatorType": "Url", + "indicatorValue": "@item()?['Url']", + "title": "SpyCloiud MDE Playbook", + "application": "SpyCloud", + "expirationTime": "@addDays(utcNow(),parameters('IOC_Expiration_Days'),'yyyy-MM-ddTHH:mm:ssZ')" + }, + "description": "SpyCloud MDE Playbook" + }, + "Build_IOC_Object_2": { + "runAfter": { + "Url_IOC_Obejct": [ + "Succeeded" + ] + }, + "type": "AppendToArrayVariable", + "inputs": { + "name": "defender_iocs_object", + "value": "@outputs('Url_IOC_Obejct')" + } + } + }, + "runAfter": { + "Entities_-_Get_URLs": [ + "Succeeded" + ] + }, + "type": "Foreach" + }, + "Auth_MDE": { + "runAfter": { + "For_each_Url_in_incident": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "@concat(variables('loginUrl'), parameters('TenantID'), '/oauth2/v2.0/token')", + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + }, + "body": "grant_type=client_credentials&client_id=@{parameters('ClientID')}&client_secret=@{parameters('Client_Secret')}&scope=https://securitycenter.onmicrosoft.com/windowsatpservice/.default" + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "HTTP_-_Create_Indicator": { + "runAfter": { + "Auth_MDE": [ + "Succeeded" + ] + }, + "type": "Http", + "inputs": { + "uri": "https://api.security.microsoft.com/api/indicators/import", + "method": "POST", + "headers": { + "Authorization": "Bearer @{body('Auth_MDE')?['access_token']}" + }, + "body": { + "Indicators": "@variables('defender_iocs_object')" + } + }, + "runtimeConfiguration": { + "contentTransfer": { + "transferMode": "Chunked" + } + } + }, + "Set_defender_iocs_variable": { + "runAfter": { + "HTTP_-_Create_Indicator": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "defender_iocs_added", + "value": true + } + } + }, + "runAfter": { + "Entities_-_Get_Hosts": [ + "Succeeded" + ] + }, + "else": { + "actions": {} + }, + "expression": { + "and": [ + { + "equals": [ + "@parameters('Save_IOCs_Defender')", + "@true" + ] + } + ] + }, + "type": "If" + }, + "For_each_incident_alert": { + "foreach": "@triggerBody()?['object']?['properties']?['Alerts']", + "actions": { + "Set_custom_details_object": { + "type": "SetVariable", + "inputs": { + "name": "incident_custom_details_object", + "value": "@json(items('For_each_incident_alert')?['properties']?['additionalData']?['Custom Details'])" + } + }, + "Set_Spycloud_publish_date": { + "runAfter": { + "Set_custom_details_object": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "SpyCloudPublishDate", + "value": "@first(coalesce(variables('incident_custom_details_object')?['SpyCloudPublishDate'], createArray('')))" + } + }, + "Set_Infected_Time": { + "runAfter": { + "Set_Spycloud_publish_date": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedTime", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedTime'], createArray('')))" + } + }, + "Set_Breach_Title": { + "runAfter": { + "Set_Infected_Time": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "BreachTitle", + "value": "@first(coalesce(variables('incident_custom_details_object')?['BreachTitle'], createArray('')))\r\n" + } + }, + "Set_Infected_Machine_ID": { + "runAfter": { + "Set_Breach_Title": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "InfectedMachineId", + "value": "@first(coalesce(variables('incident_custom_details_object')?['InfectedMachineId'], createArray('')))" + } + }, + "Set_Document_ID": { + "runAfter": { + "Set_Infected_Machine_ID": [ + "Succeeded" + ] + }, + "type": "SetVariable", + "inputs": { + "name": "DocumentID", + "value": "@first(coalesce(variables('incident_custom_details_object')?['DocumentID'], createArray('')))" + } + } + }, + "runAfter": { + "Variables_Section": [ + "Succeeded" + ] + }, + "type": "Foreach" + } + }, + "outputs": {} + }, + "parameters": { + "$connections": { + "value": { + "wdatp": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('WDATPConnection'))]", + "connectionName": "[variables('WDATPConnection')]", + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/wdatp')]" + }, + "azuresentinel": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureSentinelConnectionName'))]", + "connectionName": "[variables('AzureSentinelConnectionName')]", + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]", + "connectionProperties": { + "authentication": { + "type": "ManagedServiceIdentity" + } + } + }, + "office365": { + "connectionId": "[resourceId('Microsoft.Web/connections', variables('Office365V1'))]", + "connectionName": "[variables('Office365V1')]", + "id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/office365')]" + } + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/readme.md b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/readme.md new file mode 100644 index 00000000000..4616555a568 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/Playbooks/SpyCloud_MDE_Automation/readme.md @@ -0,0 +1,55 @@ +# SpyCloud MDE Automation Playbook + +This playbook automates endpoint response actions in Microsoft Defender for Endpoint (MDE) when SpyCloud breach data identifies compromised machines. + +**Capabilities** +- Machine isolation in Defender for Endpoint +- Machine tagging for tracking, grouping, and policy targeting +- IOC submission to Defender Threat Intelligence +- Microsoft Sentinel incident creation +- Email notifications +- Execution log ingestion to `Spycloud_MDE_LogsV2_CL` + +## Prerequisites + +- App Registration with the Microsoft Graph and WindowsDefenderATP permissions listed in the [Integration Guide](../../SpyCloud_Sentinel_Integration_Guide.md), Section 2.1 +- DCR Immutable ID and DCE Logs Ingestion Endpoint URL for `Spycloud_MDE_LogsV2_CL` (Section 2.2) +- Monitoring Metrics Publisher role assigned to the App Registration on that DCR + +## Deployment + +1. In the Azure Portal, navigate to **Deploy a custom template** +2. Select this template (`azuredeploy.json`) +3. Confirm Subscription, Resource Group, and Region +4. Enter a value for **PlaybookName** (this is the only ARM deployment-time parameter) +5. Click **Review + Create**, then **Create** +6. Authorize the `office365`, `WindowsDefenderATP`, and `azuresentinel` API connections created by the deployment + +## Post-deployment configuration + +All other settings are **workflow parameters**, baked into the Logic App with default values. After the playbook is deployed, update them with your own values: + +1. Navigate to the Microsoft Sentinel workspace, open **Automation**, and select the `SpyCloud_MDE_Automation` playbook — or go directly to the Logic App resource in the Azure Portal +2. Open the Logic App and click **Edit** to open the workflow designer +3. Open the **Parameters** section (in the designer toolbar, or under **Development Tools → Workflow parameters**) +4. For each parameter listed below, enter the appropriate value for your environment +5. Click **Save** to apply the changes to the playbook + +| Parameter | Type | Default | Description | +|---|---|---|---| +| Isolate_Machine | Bool | false | Enables automatic machine isolation in Defender for Endpoint | +| Machine_Tag_Value | String | (empty) | Tag value applied to affected machines | +| Save_IOCs_Defender | Bool | false | Enables submitting IOCs to Defender Threat Intelligence | +| IOC_Expiration_Days | Int | 30 | Days before a submitted IOC expires in Defender | +| Spycloud_Defender_DCE_Endpoint | String | (empty) | DCE Logs Ingestion Endpoint URL | +| Spycloud_Defender_DCE_Immutable_ID | String | (empty) | DCR Immutable ID for `Spycloud_MDE_LogsV2_CL` | +| TenantID | String | (empty) | Azure Tenant ID | +| ClientID | String | (empty) | App Registration Client ID | +| Client_Secret | String | (empty) | App Registration Client Secret | +| Ingestion_Table_Name | String | Spycloud_MDE_LogsV2_CL | Custom Log Analytics table for playbook logs | +| create_incident_in_sentinel | Bool | false | Enables automatic Sentinel incident creation | +| Workspace_Name | String | Your workspace name | Log Analytics Workspace name | +| Defender_IOC_Action_Type | String | Alert | IOC action in Defender, e.g. Alert, Warn, Block, Audit, or AlertAndBlock | +| notification_email | String | (empty) | Notification email address(es), semicolon-separated | + +After saving workflow parameters, confirm `SpyCloud_MDE_Automation` shows status **Enabled** and check Run History for immediate failures. diff --git a/Solutions/SpyCloud Enterprise Protection CCF/ReleaseNotes.md b/Solutions/SpyCloud Enterprise Protection CCF/ReleaseNotes.md new file mode 100644 index 00000000000..9a0f0d65fe6 --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/ReleaseNotes.md @@ -0,0 +1,3 @@ +| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | +|-------------|----------------------------------|--------------------------------------------------------| +| 3.0.0 | 09-06-2026 | Initial CCF-based release. SpyCloud Watchlist and Breach Catalog CCF data connector (Compass daily feed included), two built-in analytic rules (**AR_Breached_Users_20**, **AR_malware_25**), two KQL parsers (**get_Spycloud_enriched_data**, **get_spycloud_compass_data**), MDE Automation playbook, and Conditional Access playbook. | diff --git a/Solutions/SpyCloud Enterprise Protection CCF/SolutionMetadata.json b/Solutions/SpyCloud Enterprise Protection CCF/SolutionMetadata.json new file mode 100644 index 00000000000..aa56fc8ea5a --- /dev/null +++ b/Solutions/SpyCloud Enterprise Protection CCF/SolutionMetadata.json @@ -0,0 +1,20 @@ +{ + "publisherId": "spycloud", + "offerId": "azure-sentinel-solution-spycloud-enterprise-protection", + "firstPublishDate": "2026-06-09", + "lastPublishDate": "2026-06-09", + "providers": [ + "SpyCloud" + ], + "categories": { + "domains": [ + "Security - Threat Intelligence", + "Identity" + ] + }, + "support": { + "name": "SpyCloud", + "tier": "Partner", + "link": "https://support.spycloud.com" + } +}