From 6663563c26fcbe35ba9db09fcc1d08172e0dd1a5 Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Mon, 30 Oct 2023 16:37:12 +0530 Subject: [PATCH 01/11] Updating the Analytic rules --- .../Creation_of_Expensive_Computes_in_Azure.yaml | 10 +++++++--- .../NRT_Creation_of_Expensive_Computes_in_Azure.yaml | 10 +++++++--- .../Azure Activity/Data/Solution_AzureActivity.json | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Solutions/Azure Activity/Analytic Rules/Creation_of_Expensive_Computes_in_Azure.yaml b/Solutions/Azure Activity/Analytic Rules/Creation_of_Expensive_Computes_in_Azure.yaml index 2e369f4deca..fa031d01688 100644 --- a/Solutions/Azure Activity/Analytic Rules/Creation_of_Expensive_Computes_in_Azure.yaml +++ b/Solutions/Azure Activity/Analytic Rules/Creation_of_Expensive_Computes_in_Azure.yaml @@ -20,7 +20,7 @@ tactics: relevantTechniques: - T1578 query: | - let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","g5","gs5","g4","gs4","nc12","nc24","nv24"]); + let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","nc12","nc24","nv24"]); let operationList = dynamic(["microsoft.compute/virtualmachines/write", "microsoft.resources/deployments/write"]); AzureActivity | where OperationNameValue in~ (operationList) @@ -28,7 +28,7 @@ query: | | where Properties has 'vmSize' | extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties | extend vmSize = tostring((parsed_property.hardwareProfile).vmSize) - | where vmSize has_any (tokens) + | mv-apply token=tokens to typeof(string) on (where vmSize contains token) | extend ComputerName = tostring((parsed_property.osProfile).computerName) | project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize | extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0]) @@ -39,9 +39,13 @@ entityMappings: columnName: Name - identifier: UPNSuffix columnName: UPNSuffix + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: ComputerName - entityType: IP fieldMappings: - identifier: Address columnName: CallerIpAddress -version: 2.0.1 +version: 2.0.2 kind: Scheduled \ No newline at end of file diff --git a/Solutions/Azure Activity/Analytic Rules/NRT_Creation_of_Expensive_Computes_in_Azure.yaml b/Solutions/Azure Activity/Analytic Rules/NRT_Creation_of_Expensive_Computes_in_Azure.yaml index 1d01c9e6a12..1305177c0e5 100644 --- a/Solutions/Azure Activity/Analytic Rules/NRT_Creation_of_Expensive_Computes_in_Azure.yaml +++ b/Solutions/Azure Activity/Analytic Rules/NRT_Creation_of_Expensive_Computes_in_Azure.yaml @@ -16,7 +16,7 @@ tactics: relevantTechniques: - T1578 query: | - let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","g5","gs5","g4","gs4","nc12","nc24","nv24"]); + let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","nc12","nc24","nv24"]); let operationList = dynamic(["microsoft.compute/virtualmachines/write", "microsoft.resources/deployments/write"]); AzureActivity | where OperationNameValue in~ (operationList) @@ -24,7 +24,7 @@ query: | | where Properties has 'vmSize' | extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties | extend vmSize = tostring((parsed_property.hardwareProfile).vmSize) - | where vmSize has_any (tokens) + | mv-apply token=tokens to typeof(string) on (where vmSize contains token) | extend ComputerName = tostring((parsed_property.osProfile).computerName) | project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize | extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0]) @@ -35,9 +35,13 @@ entityMappings: columnName: Name - identifier: UPNSuffix columnName: UPNSuffix + - entityType: Host + fieldMappings: + - identifier: HostName + columnName: ComputerName - entityType: IP fieldMappings: - identifier: Address columnName: CallerIpAddress -version: 2.0.1 +version: 2.0.2 kind: NRT diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json index 68d545bc035..82f2b2af2e9 100644 --- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json +++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json @@ -40,7 +40,7 @@ "Workbooks/AzureActivity.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", - "Version": "2.0.6", + "Version": "3.0.0", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1PConnector": true From 426d75c8abc6b522d8abd29f7bb5d1fc4d4f1303 Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Mon, 30 Oct 2023 17:05:59 +0530 Subject: [PATCH 02/11] Updated the Release Notes --- Solutions/Azure Activity/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Solutions/Azure Activity/ReleaseNotes.md diff --git a/Solutions/Azure Activity/ReleaseNotes.md b/Solutions/Azure Activity/ReleaseNotes.md new file mode 100644 index 00000000000..d906ae1c8bb --- /dev/null +++ b/Solutions/Azure Activity/ReleaseNotes.md @@ -0,0 +1,4 @@ +| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | +|-------------|--------------------------------|--------------------------------------------------------------------| +| 3.0.0 | 30-10-2023 | Optimized the **Analytic Rule** query logic to achieve expected results | + From 43f18644d539943fd0a10689a1cdd7211ffa0357 Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Tue, 31 Oct 2023 14:39:42 +0530 Subject: [PATCH 03/11] Updated data file --- Solutions/Azure Activity/Data/Solution_AzureActivity.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json index 82f2b2af2e9..68d545bc035 100644 --- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json +++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json @@ -40,7 +40,7 @@ "Workbooks/AzureActivity.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", - "Version": "3.0.0", + "Version": "2.0.6", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1PConnector": true From 7663a96613591d48ea14424ef842b517b0e554aa Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Tue, 31 Oct 2023 14:40:56 +0530 Subject: [PATCH 04/11] Updating the Data File --- Solutions/Azure Activity/Data/Solution_AzureActivity.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json index 68d545bc035..82f2b2af2e9 100644 --- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json +++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json @@ -40,7 +40,7 @@ "Workbooks/AzureActivity.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", - "Version": "2.0.6", + "Version": "3.0.0", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1PConnector": true From 0d3cdbe495a47537b016281ac67c254b04d9b274 Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Tue, 31 Oct 2023 17:50:23 +0530 Subject: [PATCH 05/11] Updated the Data file for auto package --- Solutions/Azure Activity/Data/Solution_AzureActivity.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json index 82f2b2af2e9..da8fec9a7e4 100644 --- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json +++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json @@ -37,7 +37,7 @@ "Analytic Rules/TimeSeriesAnomaly_Mass_Cloud_Resource_Deletions.yaml" ], "Workbooks": [ - "Workbooks/AzureActivity.json" + "Workbooks/AzureActivity.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", "Version": "3.0.0", From 1fd9db66d660df84b97cba9c0384d770c4717977 Mon Sep 17 00:00:00 2001 From: Github Bot Date: Tue, 31 Oct 2023 12:40:17 +0000 Subject: [PATCH 06/11] [skip ci] Github Bot Added package to Pull Request! --- .../Data/system_generated_metadata.json | 33 + Solutions/Azure Activity/Package/3.0.0.zip | Bin 0 -> 26376 bytes .../Package/createUiDefinition.json | 28 +- .../Azure Activity/Package/mainTemplate.json | 3679 ++++++++--------- 4 files changed, 1717 insertions(+), 2023 deletions(-) create mode 100644 Solutions/Azure Activity/Data/system_generated_metadata.json create mode 100644 Solutions/Azure Activity/Package/3.0.0.zip diff --git a/Solutions/Azure Activity/Data/system_generated_metadata.json b/Solutions/Azure Activity/Data/system_generated_metadata.json new file mode 100644 index 00000000000..1997cee0cd0 --- /dev/null +++ b/Solutions/Azure Activity/Data/system_generated_metadata.json @@ -0,0 +1,33 @@ +{ + "Name": "Azure Activity", + "Author": "Microsoft - support@microsoft.com", + "Logo": "", + "Description": "The [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.", + "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", + "Version": "3.0.0", + "Metadata": "SolutionMetadata.json", + "TemplateSpec": true, + "Is1PConnector": true, + "publisherId": "azuresentinel", + "offerId": "azure-sentinel-solution-azureactivity", + "providers": [ + "Microsoft" + ], + "categories": { + "domains": [ + "IT Operations" + ], + "verticals": [] + }, + "firstPublishDate": "2022-04-18", + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + }, + "Data Connectors": "[\n \"Data Connectors/AzureActivity.json\"\n]", + "Workbooks": "[\n \"Workbooks/AzureActivity.json\"\n]", + "Analytic Rules": "[\n \"AADHybridHealthADFSNewServer.yaml\",\n \"AADHybridHealthADFSServiceDelete.yaml\",\n \"AADHybridHealthADFSSuspApp.yaml\",\n \"Creating_Anomalous_Number_Of_Resources_detection.yaml\",\n \"Creation_of_Expensive_Computes_in_Azure.yaml\",\n \"Granting_Permissions_To_Account_detection.yaml\",\n \"NRT-AADHybridHealthADFSNewServer.yaml\",\n \"NRT_Creation_of_Expensive_Computes_in_Azure.yaml\",\n \"New-CloudShell-User.yaml\",\n \"NewResourceGroupsDeployedTo.yaml\",\n \"RareOperations.yaml\",\n \"TimeSeriesAnomaly_Mass_Cloud_Resource_Deletions.yaml\"\n]", + "Hunting Queries": "[\n \"AnalyticsRulesAdministrativeOperations.yaml\",\n \"AnomalousAzureOperationModel.yaml\",\n \"Anomalous_Listing_Of_Storage_Keys.yaml\",\n \"AzureAdministrationFromVPS.yaml\",\n \"AzureNSG_AdministrativeOperations.yaml\",\n \"AzureRunCommandFromAzureIP.yaml\",\n \"AzureSentinelConnectors_AdministrativeOperations.yaml\",\n \"AzureSentinelWorkbooks_AdministrativeOperation.yaml\",\n \"AzureVirtualNetworkSubnets_AdministrativeOperationset.yaml\",\n \"Common_Deployed_Resources.yaml\",\n \"Creating_Anomalous_Number_Of_Resources.yaml\",\n \"Granting_Permissions_to_Account.yaml\",\n \"PortOpenedForAzureResource.yaml\",\n \"Rare_Custom_Script_Extension.yaml\"\n]" +} diff --git a/Solutions/Azure Activity/Package/3.0.0.zip b/Solutions/Azure Activity/Package/3.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..bebe5452f1ac88b28e68acd7093f98ee993c24fb GIT binary patch literal 26376 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 z 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\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Data Connectors:** 1, **Workbooks:** 1, **Analytic Rules:** 12, **Hunting Queries:** 14\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Workbooks:** 1, **Analytic Rules:** 12, **Hunting Queries:** 14\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -51,30 +51,6 @@ } ], "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 Azure Activity. You can get Azure Activity custom log 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-link2", - "type": "Microsoft.Common.TextBlock", - "options": { - "link": { - "label": "Learn more about connecting data sources", - "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" - } - } - } - ] - }, { "name": "workbooks", "label": "Workbooks", @@ -88,7 +64,7 @@ "name": "workbooks-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "The workbooks installed with the Azure Activity solution provide insights into operations on different Azure resources. After installing the solution, start using the workbook in Manage solution view." + "text": "This solution installs workbook(s) to help you gain insights into the telemetry collected in Microsoft Sentinel. After installing the solution, start using the workbook in Manage solution view." } }, { diff --git a/Solutions/Azure Activity/Package/mainTemplate.json b/Solutions/Azure Activity/Package/mainTemplate.json index c84fb96717c..de9b2fdb89f 100644 --- a/Solutions/Azure Activity/Package/mainTemplate.json +++ b/Solutions/Azure Activity/Package/mainTemplate.json @@ -42,233 +42,217 @@ "_solutionId": "[variables('solutionId')]", "email": "support@microsoft.com", "_email": "[variables('email')]", + "_solutionName": "Azure Activity", + "_solutionVersion": "3.0.0", + "workbookVersion1": "2.0.0", + "workbookContentId1": "AzureActivityWorkbook", + "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", + "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", + "_workbookContentId1": "[variables('workbookContentId1')]", "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", - "uiConfigId1": "AzureActivity", - "_uiConfigId1": "[variables('uiConfigId1')]", - "dataConnectorContentId1": "AzureActivity", - "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", - "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "_dataConnectorId1": "[variables('dataConnectorId1')]", - "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1')))]", - "dataConnectorVersion1": "2.0.0", + "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", + "analyticRuleVersion1": "2.0.1", + "analyticRulecontentId1": "88f453ff-7b9e-45bb-8c12-4058ca5e44ee", + "_analyticRulecontentId1": "[variables('analyticRulecontentId1')]", + "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]", + "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1'))))]", + "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId1'),'-', variables('analyticRuleVersion1'))))]", + "analyticRuleVersion2": "2.0.1", + "analyticRulecontentId2": "86a036b2-3686-42eb-b417-909fc0867771", + "_analyticRulecontentId2": "[variables('analyticRulecontentId2')]", + "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]", + "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2'))))]", + "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId2'),'-', variables('analyticRuleVersion2'))))]", + "analyticRuleVersion3": "2.0.1", + "analyticRulecontentId3": "d9938c3b-16f9-444d-bc22-ea9a9110e0fd", + "_analyticRulecontentId3": "[variables('analyticRulecontentId3')]", + "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId3'))]", + "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId3'))))]", + "_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId3'),'-', variables('analyticRuleVersion3'))))]", + "analyticRuleVersion4": "2.0.3", + "analyticRulecontentId4": "361dd1e3-1c11-491e-82a3-bb2e44ac36ba", + "_analyticRulecontentId4": "[variables('analyticRulecontentId4')]", + "analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId4'))]", + "analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId4'))))]", + "_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId4'),'-', variables('analyticRuleVersion4'))))]", + "analyticRuleVersion5": "2.0.2", + "analyticRulecontentId5": "9736e5f1-7b6e-4bfb-a708-e53ff1d182c3", + "_analyticRulecontentId5": "[variables('analyticRulecontentId5')]", + "analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId5'))]", + "analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId5'))))]", + "_analyticRulecontentProductId5": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId5'),'-', variables('analyticRuleVersion5'))))]", + "analyticRuleVersion6": "2.0.1", + "analyticRulecontentId6": "b2c15736-b9eb-4dae-8b02-3016b6a45a32", + "_analyticRulecontentId6": "[variables('analyticRulecontentId6')]", + "analyticRuleId6": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId6'))]", + "analyticRuleTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId6'))))]", + "_analyticRulecontentProductId6": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId6'),'-', variables('analyticRuleVersion6'))))]", + "analyticRuleVersion7": "2.0.1", + "analyticRulecontentId7": "ec491363-5fe7-4eff-b68e-f42dcb76fcf6", + "_analyticRulecontentId7": "[variables('analyticRulecontentId7')]", + "analyticRuleId7": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId7'))]", + "analyticRuleTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId7'))))]", + "_analyticRulecontentProductId7": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId7'),'-', variables('analyticRuleVersion7'))))]", + "analyticRuleVersion8": "2.0.2", + "analyticRulecontentId8": "56fe0db0-6779-46fa-b3c5-006082a53064", + "_analyticRulecontentId8": "[variables('analyticRulecontentId8')]", + "analyticRuleId8": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId8'))]", + "analyticRuleTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId8'))))]", + "_analyticRulecontentProductId8": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId8'),'-', variables('analyticRuleVersion8'))))]", + "analyticRuleVersion9": "2.0.2", + "analyticRulecontentId9": "6d7214d9-4a28-44df-aafb-0910b9e6ae3e", + "_analyticRulecontentId9": "[variables('analyticRulecontentId9')]", + "analyticRuleId9": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId9'))]", + "analyticRuleTemplateSpecName9": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId9'))))]", + "_analyticRulecontentProductId9": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId9'),'-', variables('analyticRuleVersion9'))))]", + "analyticRuleVersion10": "2.0.2", + "analyticRulecontentId10": "9fb57e58-3ed8-4b89-afcf-c8e786508b1c", + "_analyticRulecontentId10": "[variables('analyticRulecontentId10')]", + "analyticRuleId10": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId10'))]", + "analyticRuleTemplateSpecName10": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId10'))))]", + "_analyticRulecontentProductId10": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId10'),'-', variables('analyticRuleVersion10'))))]", + "analyticRuleVersion11": "2.0.2", + "analyticRulecontentId11": "23de46ea-c425-4a77-b456-511ae4855d69", + "_analyticRulecontentId11": "[variables('analyticRulecontentId11')]", + "analyticRuleId11": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId11'))]", + "analyticRuleTemplateSpecName11": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId11'))))]", + "_analyticRulecontentProductId11": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId11'),'-', variables('analyticRuleVersion11'))))]", + "analyticRuleVersion12": "2.0.2", + "analyticRulecontentId12": "ed43bdb7-eaab-4ea4-be52-6951fcfa7e3b", + "_analyticRulecontentId12": "[variables('analyticRulecontentId12')]", + "analyticRuleId12": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId12'))]", + "analyticRuleTemplateSpecName12": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId12'))))]", + "_analyticRulecontentProductId12": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId12'),'-', variables('analyticRuleVersion12'))))]", "huntingQueryVersion1": "2.0.1", "huntingQuerycontentId1": "ef7ef44e-6129-4d8e-94fe-b5530415d8e5", "_huntingQuerycontentId1": "[variables('huntingQuerycontentId1')]", "huntingQueryId1": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId1'))]", - "huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId1')))]", + "huntingQueryTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId1'))))]", + "_huntingQuerycontentProductId1": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId1'),'-', variables('huntingQueryVersion1'))))]", "huntingQueryVersion2": "2.0.0", "huntingQuerycontentId2": "43cb0347-bdcc-4e83-af5a-cebbd03971d8", "_huntingQuerycontentId2": "[variables('huntingQuerycontentId2')]", "huntingQueryId2": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId2'))]", - "huntingQueryTemplateSpecName2": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId2')))]", + "huntingQueryTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId2'))))]", + "_huntingQuerycontentProductId2": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId2'),'-', variables('huntingQueryVersion2'))))]", "huntingQueryVersion3": "2.0.1", "huntingQuerycontentId3": "5d2399f9-ea5c-4e67-9435-1fba745f3a39", "_huntingQuerycontentId3": "[variables('huntingQuerycontentId3')]", "huntingQueryId3": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId3'))]", - "huntingQueryTemplateSpecName3": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId3')))]", + "huntingQueryTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId3'))))]", + "_huntingQuerycontentProductId3": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId3'),'-', variables('huntingQueryVersion3'))))]", "huntingQueryVersion4": "2.0.1", "huntingQuerycontentId4": "1b8779c9-abf2-444f-a21f-437b8f90ac4a", "_huntingQuerycontentId4": "[variables('huntingQuerycontentId4')]", "huntingQueryId4": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId4'))]", - "huntingQueryTemplateSpecName4": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId4')))]", + "huntingQueryTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId4'))))]", + "_huntingQuerycontentProductId4": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId4'),'-', variables('huntingQueryVersion4'))))]", "huntingQueryVersion5": "2.0.1", "huntingQuerycontentId5": "e94d6756-981c-4f02-9a81-d006d80c8b41", "_huntingQuerycontentId5": "[variables('huntingQuerycontentId5')]", "huntingQueryId5": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId5'))]", - "huntingQueryTemplateSpecName5": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId5')))]", + "huntingQueryTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId5'))))]", + "_huntingQuerycontentProductId5": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId5'),'-', variables('huntingQueryVersion5'))))]", "huntingQueryVersion6": "2.1.1", "huntingQuerycontentId6": "efe843ca-3ce7-4896-9f8b-f2c374ae6527", "_huntingQuerycontentId6": "[variables('huntingQuerycontentId6')]", "huntingQueryId6": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId6'))]", - "huntingQueryTemplateSpecName6": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId6')))]", + "huntingQueryTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId6'))))]", + "_huntingQuerycontentProductId6": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId6'),'-', variables('huntingQueryVersion6'))))]", "huntingQueryVersion7": "2.0.1", "huntingQuerycontentId7": "17201aa8-0916-4078-a020-7ea3a9262889", "_huntingQuerycontentId7": "[variables('huntingQuerycontentId7')]", "huntingQueryId7": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId7'))]", - "huntingQueryTemplateSpecName7": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId7')))]", + "huntingQueryTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId7'))))]", + "_huntingQuerycontentProductId7": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId7'),'-', variables('huntingQueryVersion7'))))]", "huntingQueryVersion8": "2.0.1", "huntingQuerycontentId8": "5a1f9655-c893-4091-8dc0-7f11d7676506", "_huntingQuerycontentId8": "[variables('huntingQuerycontentId8')]", "huntingQueryId8": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId8'))]", - "huntingQueryTemplateSpecName8": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId8')))]", + "huntingQueryTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId8'))))]", + "_huntingQuerycontentProductId8": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId8'),'-', variables('huntingQueryVersion8'))))]", "huntingQueryVersion9": "2.0.1", "huntingQuerycontentId9": "57784ba5-7791-422e-916f-65ef94fe1dbb", "_huntingQuerycontentId9": "[variables('huntingQuerycontentId9')]", "huntingQueryId9": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId9'))]", - "huntingQueryTemplateSpecName9": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId9')))]", + "huntingQueryTemplateSpecName9": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId9'))))]", + "_huntingQuerycontentProductId9": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId9'),'-', variables('huntingQueryVersion9'))))]", "huntingQueryVersion10": "2.0.1", "huntingQuerycontentId10": "0278e3b8-9899-45c5-8928-700cd80d2d80", "_huntingQuerycontentId10": "[variables('huntingQuerycontentId10')]", "huntingQueryId10": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId10'))]", - "huntingQueryTemplateSpecName10": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId10')))]", + "huntingQueryTemplateSpecName10": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId10'))))]", + "_huntingQuerycontentProductId10": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId10'),'-', variables('huntingQueryVersion10'))))]", "huntingQueryVersion11": "2.0.1", "huntingQuerycontentId11": "a09e6368-065b-4f1e-a4ce-b1b3a64b493b", "_huntingQuerycontentId11": "[variables('huntingQuerycontentId11')]", "huntingQueryId11": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId11'))]", - "huntingQueryTemplateSpecName11": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId11')))]", + "huntingQueryTemplateSpecName11": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId11'))))]", + "_huntingQuerycontentProductId11": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId11'),'-', variables('huntingQueryVersion11'))))]", "huntingQueryVersion12": "2.0.1", "huntingQuerycontentId12": "860cda84-765b-4273-af44-958b7cca85f7", "_huntingQuerycontentId12": "[variables('huntingQuerycontentId12')]", "huntingQueryId12": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId12'))]", - "huntingQueryTemplateSpecName12": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId12')))]", + "huntingQueryTemplateSpecName12": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId12'))))]", + "_huntingQuerycontentProductId12": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId12'),'-', variables('huntingQueryVersion12'))))]", "huntingQueryVersion13": "2.0.1", "huntingQuerycontentId13": "9e146876-e303-49af-b847-b029d1a66852", "_huntingQuerycontentId13": "[variables('huntingQuerycontentId13')]", "huntingQueryId13": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId13'))]", - "huntingQueryTemplateSpecName13": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId13')))]", + "huntingQueryTemplateSpecName13": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId13'))))]", + "_huntingQuerycontentProductId13": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId13'),'-', variables('huntingQueryVersion13'))))]", "huntingQueryVersion14": "2.0.1", "huntingQuerycontentId14": "81fd68a2-9ad6-4a1c-7bd7-18efe5c99081", "_huntingQuerycontentId14": "[variables('huntingQuerycontentId14')]", "huntingQueryId14": "[resourceId('Microsoft.OperationalInsights/savedSearches', variables('_huntingQuerycontentId14'))]", - "huntingQueryTemplateSpecName14": "[concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId14')))]", - "analyticRuleVersion1": "2.0.1", - "analyticRulecontentId1": "88f453ff-7b9e-45bb-8c12-4058ca5e44ee", - "_analyticRulecontentId1": "[variables('analyticRulecontentId1')]", - "analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]", - "analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1')))]", - "analyticRuleVersion2": "2.0.1", - "analyticRulecontentId2": "86a036b2-3686-42eb-b417-909fc0867771", - "_analyticRulecontentId2": "[variables('analyticRulecontentId2')]", - "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]", - "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2')))]", - "analyticRuleVersion3": "2.0.1", - "analyticRulecontentId3": "d9938c3b-16f9-444d-bc22-ea9a9110e0fd", - "_analyticRulecontentId3": "[variables('analyticRulecontentId3')]", - "analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId3'))]", - "analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId3')))]", - "analyticRuleVersion4": "2.0.3", - "analyticRulecontentId4": "361dd1e3-1c11-491e-82a3-bb2e44ac36ba", - "_analyticRulecontentId4": "[variables('analyticRulecontentId4')]", - "analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId4'))]", - "analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId4')))]", - "analyticRuleVersion5": "2.0.1", - "analyticRulecontentId5": "9736e5f1-7b6e-4bfb-a708-e53ff1d182c3", - "_analyticRulecontentId5": "[variables('analyticRulecontentId5')]", - "analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId5'))]", - "analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId5')))]", - "analyticRuleVersion6": "2.0.1", - "analyticRulecontentId6": "b2c15736-b9eb-4dae-8b02-3016b6a45a32", - "_analyticRulecontentId6": "[variables('analyticRulecontentId6')]", - "analyticRuleId6": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId6'))]", - "analyticRuleTemplateSpecName6": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId6')))]", - "analyticRuleVersion7": "2.0.1", - "analyticRulecontentId7": "ec491363-5fe7-4eff-b68e-f42dcb76fcf6", - "_analyticRulecontentId7": "[variables('analyticRulecontentId7')]", - "analyticRuleId7": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId7'))]", - "analyticRuleTemplateSpecName7": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId7')))]", - "analyticRuleVersion8": "2.0.1", - "analyticRulecontentId8": "56fe0db0-6779-46fa-b3c5-006082a53064", - "_analyticRulecontentId8": "[variables('analyticRulecontentId8')]", - "analyticRuleId8": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId8'))]", - "analyticRuleTemplateSpecName8": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId8')))]", - "analyticRuleVersion9": "2.0.2", - "analyticRulecontentId9": "6d7214d9-4a28-44df-aafb-0910b9e6ae3e", - "_analyticRulecontentId9": "[variables('analyticRulecontentId9')]", - "analyticRuleId9": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId9'))]", - "analyticRuleTemplateSpecName9": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId9')))]", - "analyticRuleVersion10": "2.0.2", - "analyticRulecontentId10": "9fb57e58-3ed8-4b89-afcf-c8e786508b1c", - "_analyticRulecontentId10": "[variables('analyticRulecontentId10')]", - "analyticRuleId10": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId10'))]", - "analyticRuleTemplateSpecName10": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId10')))]", - "analyticRuleVersion11": "2.0.2", - "analyticRulecontentId11": "23de46ea-c425-4a77-b456-511ae4855d69", - "_analyticRulecontentId11": "[variables('analyticRulecontentId11')]", - "analyticRuleId11": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId11'))]", - "analyticRuleTemplateSpecName11": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId11')))]", - "analyticRuleVersion12": "2.0.2", - "analyticRulecontentId12": "ed43bdb7-eaab-4ea4-be52-6951fcfa7e3b", - "_analyticRulecontentId12": "[variables('analyticRulecontentId12')]", - "analyticRuleId12": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId12'))]", - "analyticRuleTemplateSpecName12": "[concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId12')))]", - "TemplateEmptyArray": "[json('[]')]", - "blanks": "[replace('b', 'b', '')]", - "workbookVersion1": "2.0.0", - "workbookContentId1": "AzureActivityWorkbook", - "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", - "workbookTemplateSpecName1": "[concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1')))]", - "_workbookContentId1": "[variables('workbookContentId1')]" + "huntingQueryTemplateSpecName14": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-hq-',uniquestring(variables('_huntingQuerycontentId14'))))]", + "_huntingQuerycontentProductId14": "[concat(take(variables('_solutionId'),50),'-','hq','-', uniqueString(concat(variables('_solutionId'),'-','HuntingQuery','-',variables('_huntingQuerycontentId14'),'-', variables('huntingQueryVersion14'))))]", + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" }, "resources": [ { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('dataConnectorTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "DataConnector" - }, - "properties": { - "description": "Azure Activity data connector with template", - "displayName": "Azure Activity template" - } - }, - { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('dataConnectorTemplateSpecName1'),'/',variables('dataConnectorVersion1'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName1')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "DataConnector" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('dataConnectorTemplateSpecName1'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Azure Activity data connector with template version 2.0.6", + "description": "AzureActivityWorkbook Workbook with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('dataConnectorVersion1')]", + "contentVersion": "[variables('workbookVersion1')]", "parameters": {}, "variables": {}, "resources": [ { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", - "apiVersion": "2021-03-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId1')]", "location": "[parameters('workspace-location')]", - "kind": "StaticUI", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "Gain extensive insight into your organization's Azure Activity by analyzing, and correlating all user operations and events.\nYou can learn about all user operations, trends, and anomalous changes over time.\nThis workbook gives you the ability to drill down into caller activities and summarize detected failure and warning events." + }, "properties": { - "connectorUiConfig": { - "id": "[variables('_uiConfigId1')]", - "title": "Azure Activity", - "publisher": "Microsoft", - "descriptionMarkdown": "Azure Activity Log is a subscription log that provides insight into subscription-level events that occur in Azure, including events from Azure Resource Manager operational data, service health events, write operations taken on the resources in your subscription, and the status of activities performed in Azure. For more information, see the [Microsoft Sentinel documentation ](https://go.microsoft.com/fwlink/p/?linkid=2219695&wt.mc_id=sentinel_dataconnectordocs_content_cnl_csasci).", - "graphQueries": [ - { - "metricName": "Total data received", - "legend": "AzureActivity", - "baseQuery": "AzureActivity" - } - ], - "connectivityCriterias": [ - { - "type": "IsConnectedQuery", - "value": [ - "AzureActivity\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" - ] - } - ], - "dataTypes": [ - { - "name": "AzureActivity", - "lastDataReceivedQuery": "AzureActivity\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - } - ] - } + "displayName": "[parameters('workbook1-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"query\":\"\",\"parameters\":[{\"id\":\"52bfbd84-1639-480c-bda5-bfc87fd81832\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"value\":{\"durationMs\":604800000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}]}},{\"id\":\"eeb5dcf9-e898-46af-9c12-d91d97e13cd3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Caller\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"AzureActivity\\r\\n| summarize by Caller\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"All\"},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"46375a76-7ae1-4d7e-9082-4191531198a9\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ResourceGroup\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"AzureActivity\\r\\n| summarize by ResourceGroup\",\"value\":[\"value::all\"],\"typeSettings\":{\"resourceTypeFilter\":{\"microsoft.resources/resourcegroups\":true},\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"All\"},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let data = AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup});\\r\\ndata\\r\\n| summarize Count = count() by ResourceGroup\\r\\n| join kind = fullouter (datatable(ResourceGroup:string)['Medium', 'high', 'low']) on ResourceGroup\\r\\n| project ResourceGroup = iff(ResourceGroup == '', ResourceGroup1, ResourceGroup), Count = iff(ResourceGroup == '', 0, Count)\\r\\n| join kind = inner (data\\r\\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain} by ResourceGroup)\\r\\n on ResourceGroup\\r\\n| project-away ResourceGroup1, TimeGenerated\\r\\n| extend ResourceGroups = ResourceGroup\\r\\n| union (\\r\\n data \\r\\n | summarize Count = count() \\r\\n | extend jkey = 1\\r\\n | join kind=inner (data\\r\\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain}\\r\\n | extend jkey = 1) on jkey\\r\\n | extend ResourceGroup = 'All', ResourceGroups = '*' \\r\\n)\\r\\n| order by Count desc\\r\\n| take 10\",\"size\":4,\"exportToExcelOptions\":\"visible\",\"title\":\"Top 10 active resource groups\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"ResourceGroup\",\"formatter\":1,\"formatOptions\":{\"showIcon\":true}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\",\"showIcon\":true},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"secondaryContent\":{\"columnMatch\":\"Trend\",\"formatter\":9,\"formatOptions\":{\"palette\":\"blueOrange\",\"showIcon\":true}},\"showBorder\":false}},\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize deletions = countif(OperationNameValue hassuffix \\\"delete\\\"), creations = countif(OperationNameValue hassuffix \\\"write\\\"), updates = countif(OperationNameValue hassuffix \\\"write\\\"), Activities = count(OperationNameValue) by bin_at(TimeGenerated, 1h, now())\\r\\n\",\"size\":0,\"exportToExcelOptions\":\"visible\",\"title\":\"Activities over time\",\"color\":\"gray\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"graphSettings\":{\"type\":0}},\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize deletions = countif(OperationNameValue hassuffix \\\"Delete\\\"), creations = countif(OperationNameValue hassuffix \\\"write\\\"), updates = countif(OperationNameValue hassuffix \\\"write\\\"), Activities = count() by Caller\\r\\n\",\"size\":1,\"exportToExcelOptions\":\"visible\",\"title\":\"Caller activities\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Caller\",\"formatter\":0,\"formatOptions\":{\"showIcon\":true}},{\"columnMatch\":\"deletions\",\"formatter\":4,\"formatOptions\":{\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"creations\",\"formatter\":4,\"formatOptions\":{\"palette\":\"purple\",\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"updates\",\"formatter\":4,\"formatOptions\":{\"palette\":\"gray\",\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"Activities\",\"formatter\":4,\"formatOptions\":{\"palette\":\"greenDark\",\"linkTarget\":\"GenericDetails\",\"linkIsContextBlade\":true,\"showIcon\":true,\"aggregation\":\"Count\",\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"templateIdSource\":\"static\",\"templateId\":\"https://go.microsoft.com/fwlink/?linkid=874159&resourceId=%2Fsubscriptions%2F44e4eff8-1fcb-4a22-a7d6-992ac7286382%2FresourceGroups%2FSOC&featureName=Workbooks&itemId=%2Fsubscriptions%2F44e4eff8-1fcb-4a22-a7d6-992ac7286382%2Fresourcegroups%2Fsoc%2Fproviders%2Fmicrosoft.insights%2Fworkbooks%2F4c195aec-747f-40bb-addb-934acb3ec646&name=CiscoASA&func=NavigateToPortalFeature&type=workbook\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\"}}}],\"sortBy\":[{\"itemKey\":\"$gen_bar_updates_3\",\"sortOrder\":2}]}},\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity \\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize Informational = countif(Level == \\\"Informational\\\"), Warning = countif(Level == \\\"Warning\\\"), Error = countif(Level == \\\"Error\\\") by bin_at(TimeGenerated, 1h, now())\\r\\n\",\"size\":0,\"exportToExcelOptions\":\"visible\",\"title\":\"Activities by log level over time\",\"color\":\"redBright\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"scatterchart\",\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":2,\"topContent\":{\"columnMatch\":\"Error\",\"formatter\":12,\"formatOptions\":{\"showIcon\":true}},\"hivesContent\":{\"columnMatch\":\"TimeGenerated\",\"formatter\":1,\"formatOptions\":{\"showIcon\":true}},\"nodeIdField\":\"Error\",\"sourceIdField\":\"Error\",\"targetIdField\":\"Error\",\"staticNodeSize\":100,\"groupByField\":\"TimeGenerated\",\"hivesMargin\":5}},\"name\":\"query - 4\"}],\"fromTemplateId\":\"sentinel-AzureActivity\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", "properties": { - "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "contentId": "[variables('_dataConnectorContentId1')]", - "kind": "DataConnector", - "version": "[variables('dataConnectorVersion1')]", + "description": "@{workbookKey=AzureActivityWorkbook; logoFileName=azureactivity_logo.svg; description=Gain extensive insight into your organization's Azure Activity by analyzing, and correlating all user operations and events.\nYou can learn about all user operations, trends, and anomalous changes over time.\nThis workbook gives you the ability to drill down into caller activities and summarize detected failure and warning events.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0.0; title=Azure Activity; templateRelativePath=AzureActivity.json; subtitle=; provider=Microsoft}.description", + "parentId": "[variables('workbookId1')]", + "contentId": "[variables('_workbookContentId1')]", + "kind": "Workbook", + "version": "[variables('workbookVersion1')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -283,228 +267,108 @@ "name": "Microsoft Corporation", "email": "support@microsoft.com", "link": "https://support.microsoft.com/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "contentId": "AzureActivity", + "kind": "DataType" + }, + { + "contentId": "AzureActivity", + "kind": "DataConnector" + } + ] } } } ] - } - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", - "dependsOn": [ - "[variables('_dataConnectorId1')]" - ], - "location": "[parameters('workspace-location')]", - "properties": { - "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "contentId": "[variables('_dataConnectorContentId1')]", - "kind": "DataConnector", - "version": "[variables('dataConnectorVersion1')]", - "source": { - "kind": "Solution", - "name": "Azure Activity", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "Microsoft", - "email": "[variables('_email')]" }, - "support": { - "tier": "Microsoft", - "name": "Microsoft Corporation", - "email": "support@microsoft.com", - "link": "https://support.microsoft.com/" - } - } - }, - { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", - "apiVersion": "2021-03-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", - "location": "[parameters('workspace-location')]", - "kind": "StaticUI", - "properties": { - "connectorUiConfig": { - "title": "Azure Activity", - "publisher": "Microsoft", - "descriptionMarkdown": "Azure Activity Log is a subscription log that provides insight into subscription-level events that occur in Azure, including events from Azure Resource Manager operational data, service health events, write operations taken on the resources in your subscription, and the status of activities performed in Azure. For more information, see the [Microsoft Sentinel documentation ](https://go.microsoft.com/fwlink/p/?linkid=2219695&wt.mc_id=sentinel_dataconnectordocs_content_cnl_csasci).", - "graphQueries": [ - { - "metricName": "Total data received", - "legend": "AzureActivity", - "baseQuery": "AzureActivity" - } - ], - "dataTypes": [ - { - "name": "AzureActivity", - "lastDataReceivedQuery": "AzureActivity\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" - } - ], - "connectivityCriterias": [ - { - "type": "IsConnectedQuery", - "value": [ - "AzureActivity\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" - ] - } - ], - "id": "[variables('_uiConfigId1')]" - } + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId1')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook1-name')]", + "contentProductId": "[variables('_workbookcontentProductId1')]", + "id": "[variables('_workbookcontentProductId1')]", + "version": "[variables('workbookVersion1')]" } }, { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 1 with template", - "displayName": "Azure Activity Hunting Query template" - } - }, - { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName1'),'/',variables('huntingQueryVersion1'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName1')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName1'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AnalyticsRulesAdministrativeOperations_HuntingQueries Hunting Query with template version 2.0.6", + "description": "AADHybridHealthADFSNewServer_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion1')]", + "contentVersion": "[variables('analyticRuleVersion1')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_1", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId1')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Microsoft Sentinel Analytics Rules Administrative Operations", - "category": "Hunting Queries", - "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/alertRules/write\", \"Microsoft.SecurityInsights/alertRules/delete\"]);\n// Microsoft Sentinel Analytics - Rule Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ - { - "name": "description", - "value": "Identifies Microsoft Sentinel Analytics Rules administrative operations" - }, - { - "name": "tactics", - "value": "Impact" - }, + "description": "This detection uses AzureActivity logs (Administrative category) to identify the creation or update of a server instance in an Azure AD Hybrid Health AD FS service.\nA threat actor can create a new AD Health ADFS service and create a fake server instance to spoof AD FS signing logs. There is no need to compromise an on-premises AD FS server.\nThis can be done programmatically via HTTP requests to Azure. More information in this blog: https://o365blog.com/post/hybridhealthagent/", + "displayName": "Azure Active Directory Hybrid Health AD FS New Server", + "enabled": false, + "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/servicemembers/action'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", + "queryFrequency": "P1D", + "queryPeriod": "P1D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "techniques", - "value": "T1496" + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" } - ] - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId1'),'/'))))]", - "properties": { - "description": "Azure Activity Hunting Query 1", - "parentId": "[variables('huntingQueryId1')]", - "contentId": "[variables('_huntingQuerycontentId1')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion1')]", - "source": { - "kind": "Solution", - "name": "Azure Activity", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "Microsoft", - "email": "[variables('_email')]" - }, - "support": { - "tier": "Microsoft", - "name": "Microsoft Corporation", - "email": "support@microsoft.com", - "link": "https://support.microsoft.com/" - } - } - } - ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName2')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 2 with template", - "displayName": "Azure Activity Hunting Query template" - } - }, - { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName2'),'/',variables('huntingQueryVersion2'))]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName2'))]" - ], - "properties": { - "description": "AnomalousAzureOperationModel_HuntingQueries Hunting Query with template version 2.0.6", - "mainTemplate": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion2')]", - "parameters": {}, - "variables": {}, - "resources": [ - { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_2", - "location": "[parameters('workspace-location')]", - "properties": { - "eTag": "*", - "displayName": "Anomalous Azure Operation Hunting Model", - "category": "Hunting Queries", - "query": "// When the detection window will end (3 days prior to now)\nlet startDetectDate = 3d;\n// When the detection window will start (now)\nlet endDetectDate = 0d;\n// When to start collecting data for detection\nlet startDate = startDetectDate + 30d;\n// Operation to monitor, in this case Run Command\nlet monitoredOps = dynamic(['microsoft.compute/virtualmachines/runcommand/action']);\n// The resource type to monitor, in this case virtual machines\nlet monitoredResource = pack_array('microsoft.compute/virtualmachines');\nlet pair_probabilities_fl = (tbl:(*), A_col:string, B_col:string, scope_col:string)\n{\nlet T = (tbl | extend _A = column_ifexists(A_col, ''), _B = column_ifexists(B_col, ''), _scope = column_ifexists(scope_col, ''));\nlet countOnScope = T | summarize countAllOnScope = count() by _scope;\nlet probAB = T | summarize countAB = count() by _A, _B, _scope | join kind = leftouter (countOnScope) on _scope | extend P_AB = todouble(countAB)/countAllOnScope;\nlet probA = probAB | summarize countA = sum(countAB), countAllOnScope = max(countAllOnScope) by _A, _scope | extend P_A = todouble(countA)/countAllOnScope;\nlet probB = probAB | summarize countB = sum(countAB), countAllOnScope = max(countAllOnScope) by _B, _scope | extend P_B = todouble(countB)/countAllOnScope;\n probAB\n | join kind = leftouter (probA) on _A, _scope\n | join kind = leftouter (probB) on _B, _scope\n | extend P_AUB = P_A + P_B - P_AB\n , P_AIB = P_AB/P_B\n , P_BIA = P_AB/P_A\n | extend Lift_AB = P_AB/(P_A * P_B)\n , Jaccard_AB = P_AB/P_AUB\n | project _A, _B, _scope, floor(P_A, 0.00001), floor(P_B, 0.00001), floor(P_AB, 0.00001), floor(P_AUB, 0.00001), floor(P_AIB, 0.00001)\n , floor(P_BIA, 0.00001), floor(Lift_AB, 0.00001), floor(Jaccard_AB, 0.00001)\n | sort by _scope, _A, _B\n};\nlet eventsTable = materialize (\nAzureActivity\n| where TimeGenerated between (ago(startDate) .. ago(endDetectDate))\n| where isnotempty(CallerIpAddress)\n| where ActivityStatusValue has_any ('Success', 'Succeeded')\n| extend ResourceId = iff(isempty(_ResourceId), ResourceId, _ResourceId)\n| extend splitOp = split(OperationNameValue, '/')\n| extend splitRes = split(ResourceId, '/')\n| project TimeGenerated , subscriptionId=SubscriptionId\n , ResourceProvider\n , ResourceName = tolower(tostring(splitRes[-1]))\n , OperationNameValue = tolower(OperationNameValue)\n , timeSlice = floor(TimeGenerated, 1d)\n , clientIp = tostring(CallerIpAddress)\n , Caller\n , isMonitoredOp = iff(OperationNameValue has_any (monitoredOps), 1, 0)\n , isMonitoredResource = iff(OperationNameValue has_any (monitoredResource), 1, 0)\n , CorrelationId\n| extend clientIpMask = format_ipv4_mask(clientIp, 16)\n);\nlet modelData = (\neventsTable\n| where TimeGenerated < ago(startDetectDate) and isnotempty(Caller) and isnotempty(subscriptionId)\n| summarize countEvents = count(), countMonRes = countif(isMonitoredResource == 1), counMonOp = countif(isMonitoredOp == 1)\n , firstSeen = min(timeSlice), firstSeenOnMonRes = minif(timeSlice, isMonitoredResource == 1), firstSeenOnMonOp = minif(timeSlice, isMonitoredOp == 1)\n by subscriptionId, Caller, clientIpMask\n);\nlet monOpProbs = materialize (\neventsTable\n| where TimeGenerated < ago(startDetectDate) and isnotempty(Caller) and isnotempty(subscriptionId)\n| invoke pair_probabilities_fl('Caller', 'isMonitoredResource','subscriptionId')\n| where _B == 1\n| sort by P_AIB desc\n| extend rankOnMonRes = row_rank(P_AIB), sumBiggerCondProbs = row_cumsum(P_AIB) - P_AIB\n| extend avgBiggerCondProbs = floor(iff(rankOnMonRes > 1, sumBiggerCondProbs/(rankOnMonRes-1), max_of(0.0, prev(sumBiggerCondProbs))), 0.00001)\n| project-away sumBiggerCondProbs\n);\neventsTable\n| where TimeGenerated between (ago(startDetectDate) .. ago(endDetectDate))\n| join kind = leftouter (modelData | summarize countEventsPrincOnSub = sum(countEvents), countEventsMonResPrincOnSub = sum(countMonRes), countEventsMonOpPrincOnSub = sum(counMonOp)\n , firstSeenPrincOnSubs = min(firstSeen), firstSeenMonResPrincOnSubs = min(firstSeenOnMonRes), firstSeenMonOpPrincOnSubs = min(firstSeenOnMonOp) by subscriptionId, Caller) \n on subscriptionId, Caller\n| join kind = leftouter (modelData | summarize countEventsIpMaskOnSub = sum(countEvents), countEventsMonResIpMaskOnSub = sum(countMonRes), countEventsMonOpIpMaskOnSub = sum(counMonOp)\n , firstSeenIpMaskOnSubs = min(firstSeen), firstSeenMonResIpMaskOnSubs = min(firstSeenOnMonRes), firstSeenMonOpIpMaskOnSubs = min(firstSeenOnMonOp) by subscriptionId, clientIpMask) \n on subscriptionId, clientIpMask\n| join kind = leftouter (modelData | summarize countEventsOnSub = sum(countEvents), countEventsMonResOnSub = sum(countMonRes), countEventsMonOpOnSub = sum(counMonOp)\n , firstSeenOnSubs = min(firstSeen), firstSeenMonResOnSubs = min(firstSeenOnMonRes), firstSeenMonOpOnSubs = min(firstSeenOnMonOp)\n , countCallersOnSubs = dcount(Caller), countIpMasksOnSubs = dcount(clientIpMask) by subscriptionId)\n on subscriptionId \n| project-away subscriptionId1, Caller1, subscriptionId2\n| extend daysOnSubs = datetime_diff('day', timeSlice, firstSeenOnSubs)\n| extend avgMonOpOnSubs = floor(1.0*countEventsMonOpOnSub/daysOnSubs, 0.01), avgMonResOnSubs = floor(1.0*countEventsMonResOnSub/daysOnSubs, 0.01)\n| join kind = leftouter(monOpProbs) on $left.subscriptionId == $right._scope, $left.Caller == $right._A\n| project-away _A, _B, _scope\n| sort by subscriptionId asc, TimeGenerated asc\n| extend rnOnSubs = row_number(1, subscriptionId != prev(subscriptionId))\n| sort by subscriptionId asc, Caller asc, TimeGenerated asc\n| extend rnOnCallerSubs = row_number(1, (subscriptionId != prev(subscriptionId) and (Caller != prev(Caller))))\n| extend newCaller = iff(isempty(firstSeenPrincOnSubs), 1, 0)\n , newCallerOnMonRes = iff(isempty(firstSeenMonResPrincOnSubs), 1, 0)\n , newIpMask = iff(isempty(firstSeenIpMaskOnSubs), 1, 0)\n , newIpMaskOnMonRes = iff(isempty(firstSeenMonResIpMaskOnSubs), 1, 0)\n , newMonOpOnSubs = iff(isempty(firstSeenMonResOnSubs), 1, 0)\n , anomCallerMonRes = iff(((Jaccard_AB <= 0.1) or (P_AIB <= 0.1)), 1, 0)\n| project TimeGenerated, subscriptionId, ResourceProvider, ResourceName, OperationNameValue, Caller, CorrelationId, ClientIP=clientIp, ActiveDaysOnSub=daysOnSubs, avgMonOpOnSubs, newCaller, newCallerOnMonRes, newIpMask, newIpMaskOnMonRes, newMonOpOnSubs, anomCallerMonRes, isMonitoredOp, isMonitoredResource\n| order by TimeGenerated\n| where isMonitoredOp == 1\n// Optional - focus only on monitored operations or monitored resource in detection window\n| where isMonitoredOp == 1\n//| where isMonitoredResource == 1\n", - "version": 2, - "tags": [ - { - "name": "description", - "value": "This query can be used during threat hunts to identify a range of different Azure Operation anomalies.\nThe query is heavily commented inline to explain operation. Anomalies covered are: New Caller, New Caller IP,\nNew Caller IP Range, Anomalous operation based on Jaccard index. By default this query is configured to detect\nanomalous Run Command operations. The operation and resource type to perform anomaly detection can be configured \nat the top of the query along with the detection window parameters" - }, + ], + "tactics": [ + "DefenseEvasion" + ], + "techniques": [ + "T1578" + ], + "entityMappings": [ { - "name": "tactics", - "value": "LateralMovement,CredentialAccess" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1570,T1078.004" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -512,13 +376,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId2'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId1'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 2", - "parentId": "[variables('huntingQueryId2')]", - "contentId": "[variables('_huntingQuerycontentId2')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion2')]", + "description": "Azure Activity Analytics Rule 1", + "parentId": "[variables('analyticRuleId1')]", + "contentId": "[variables('_analyticRulecontentId1')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion1')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -537,66 +401,91 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName3')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 3 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId1')]", + "contentKind": "AnalyticsRule", + "displayName": "Azure Active Directory Hybrid Health AD FS New Server", + "contentProductId": "[variables('_analyticRulecontentProductId1')]", + "id": "[variables('_analyticRulecontentProductId1')]", + "version": "[variables('analyticRuleVersion1')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName3'),'/',variables('huntingQueryVersion3'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName2')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName3'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Anomalous_Listing_Of_Storage_Keys_HuntingQueries Hunting Query with template version 2.0.6", + "description": "AADHybridHealthADFSServiceDelete_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion3')]", + "contentVersion": "[variables('analyticRuleVersion2')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_3", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId2')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Azure storage key enumeration", - "category": "Hunting Queries", - "query": "AzureActivity\n| where OperationNameValue =~ \"microsoft.storage/storageaccounts/listkeys/action\"\n| where ActivityStatusValue =~ \"Succeeded\" \n| join kind= inner (\n AzureActivity\n | where OperationNameValue =~ \"microsoft.storage/storageaccounts/listkeys/action\"\n | where ActivityStatusValue =~ \"Succeeded\" \n | project ExpectedIpAddress=CallerIpAddress, Caller \n | evaluate autocluster()\n) on Caller\n| where CallerIpAddress != ExpectedIpAddress\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResourceIds = make_set(ResourceId,100), ResourceIdCount = dcount(ResourceId) by OperationNameValue, Caller, CallerIpAddress\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "This detection uses AzureActivity logs (Administrative category) to identify the deletion of an Azure AD Hybrid Health AD FS service instance in a tenant.\nA threat actor can create a new AD Health ADFS service and create a fake server to spoof AD FS signing logs.\nThe health AD FS service can then be deleted after it is no longer needed via HTTP requests to Azure.\nMore information is available in this blog https://o365blog.com/post/hybridhealthagent/", + "displayName": "Azure Active Directory Hybrid Health AD FS Service Delete", + "enabled": false, + "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/delete'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", + "queryFrequency": "P1D", + "queryPeriod": "P1D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Listing of storage keys is an interesting operation in Azure which might expose additional \nsecrets and PII to callers as well as granting access to VMs. While there are many benign operations of this\ntype, it would be interesting to see if the account performing this activity or the source IP address from \nwhich it is being done is anomalous. \nThe query below generates known clusters of ip address per caller, notice that users which only had single\noperations do not appear in this list as we cannot learn from it their normal activity (only based on a single\nevent). The activities for listing storage account keys is correlated with this learned \nclusters of expected activities and activity which is not expected is returned." - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "DefenseEvasion" + ], + "techniques": [ + "T1578" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Discovery" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1087" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -604,13 +493,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId3'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId2'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 3", - "parentId": "[variables('huntingQueryId3')]", - "contentId": "[variables('_huntingQuerycontentId3')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion3')]", + "description": "Azure Activity Analytics Rule 2", + "parentId": "[variables('analyticRuleId2')]", + "contentId": "[variables('_analyticRulecontentId2')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion2')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -629,66 +518,93 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName4')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 4 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId2')]", + "contentKind": "AnalyticsRule", + "displayName": "Azure Active Directory Hybrid Health AD FS Service Delete", + "contentProductId": "[variables('_analyticRulecontentProductId2')]", + "id": "[variables('_analyticRulecontentProductId2')]", + "version": "[variables('analyticRuleVersion2')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName4'),'/',variables('huntingQueryVersion4'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName3')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName4'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureAdministrationFromVPS_HuntingQueries Hunting Query with template version 2.0.6", + "description": "AADHybridHealthADFSSuspApp_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion4')]", + "contentVersion": "[variables('analyticRuleVersion3')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_4", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId3')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "AzureActivity Administration From VPS Providers", - "category": "Hunting Queries", - "query": "let IP_Data = (externaldata(network:string)\n[@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/VPS_Networks.csv\"] with (format=\"csv\"));\nAzureActivity\n| where CategoryValue =~ \"Administrative\"\n| evaluate ipv4_lookup(IP_Data, CallerIpAddress, network, return_unmatched = false)\n| summarize Operations = make_set(OperationNameValue), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by CallerIpAddress, Caller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "This detection uses AzureActivity logs (Administrative category) to identify a suspicious application adding a server instance to an Azure AD Hybrid Health AD FS service or deleting the AD FS service instance.\nUsually the Azure AD Connect Health Agent application with ID cf6d7e68-f018-4e0a-a7b3-126e053fb88d and ID cb1056e2-e479-49de-ae31-7812af012ed8 is used to perform those operations.", + "displayName": "Azure Active Directory Hybrid Health AD FS Suspicious Application", + "enabled": false, + "query": "// Azure AD Connect Health Agent - cf6d7e68-f018-4e0a-a7b3-126e053fb88d\n// Azure Active Directory Connect - cb1056e2-e479-49de-ae31-7812af012ed8\nlet appList = dynamic(['cf6d7e68-f018-4e0a-a7b3-126e053fb88d','cb1056e2-e479-49de-ae31-7812af012ed8']);\nlet operationNamesList = dynamic(['Microsoft.ADHybridHealthService/services/servicemembers/action','Microsoft.ADHybridHealthService/services/delete']);\nAzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue in~ (operationNamesList)\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| where AppId !in (appList)\n| project-away claimsJson\n", + "queryFrequency": "P1D", + "queryPeriod": "P1D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Looks for administrative actions in AzureActivity from known VPS provider network ranges.\nThis is not an exhaustive list of VPS provider ranges but covers some of the most prevalent providers observed." - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "CredentialAccess", + "DefenseEvasion" + ], + "techniques": [ + "T1528", + "T1550" + ], + "entityMappings": [ { - "name": "tactics", - "value": "InitialAccess" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1078" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -696,13 +612,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId4'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId3'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 4", - "parentId": "[variables('huntingQueryId4')]", - "contentId": "[variables('_huntingQuerycontentId4')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion4')]", + "description": "Azure Activity Analytics Rule 3", + "parentId": "[variables('analyticRuleId3')]", + "contentId": "[variables('_analyticRulecontentId3')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion3')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -721,66 +637,95 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName5')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 5 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId3')]", + "contentKind": "AnalyticsRule", + "displayName": "Azure Active Directory Hybrid Health AD FS Suspicious Application", + "contentProductId": "[variables('_analyticRulecontentProductId3')]", + "id": "[variables('_analyticRulecontentProductId3')]", + "version": "[variables('analyticRuleVersion3')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName5'),'/',variables('huntingQueryVersion5'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName4')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName5'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureNSG_AdministrativeOperations_HuntingQueries Hunting Query with template version 2.0.6", + "description": "Creating_Anomalous_Number_Of_Resources_detection_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion5')]", + "contentVersion": "[variables('analyticRuleVersion4')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_5", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId4')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Azure Network Security Group NSG Administrative Operations", - "category": "Hunting Queries", - "query": "let opValues = dynamic([\"Microsoft.Network/networkSecurityGroups/write\", \"Microsoft.Network/networkSecurityGroups/delete\"]);\n// Azure NSG Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\",\"Accepted\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "Indicates when an anomalous number of VM creations or deployment activities occur in Azure via the AzureActivity log. This query generates the baseline pattern of cloud resource creation by an individual and generates an anomaly when any unusual spike is detected. These anomalies from unusual or privileged users could be an indication of a cloud infrastructure takedown by an adversary.", + "displayName": "Suspicious number of resource creation or deployment activities", + "enabled": false, + "query": "let szOperationNames = dynamic([\"microsoft.compute/virtualMachines/write\", \"microsoft.resources/deployments/write\"]);\nlet starttime = 7d;\nlet endtime = 1d;\nlet timeframe = 1d;\nlet TimeSeriesData =\nAzureActivity\n| where TimeGenerated between (startofday(ago(starttime)) .. startofday(now()))\n| where OperationNameValue in~ (szOperationNames)\n| project TimeGenerated, Caller \n| make-series Total = count() on TimeGenerated from startofday(ago(starttime)) to startofday(now()) step timeframe by Caller; \nTimeSeriesData\n| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, 3, -1, 'linefit')\n| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long) \n| where TimeGenerated >= startofday(ago(endtime))\n| where anomalies > 0 and baseline > 0\n| project Caller, TimeGenerated, Total, baseline, anomalies, score\n| join (AzureActivity\n| where TimeGenerated > startofday(ago(endtime)) \n| where OperationNameValue in~ (szOperationNames)\n| summarize make_set(OperationNameValue,100), make_set(_ResourceId,100), make_set(CallerIpAddress,100) by bin(TimeGenerated, timeframe), Caller\n) on TimeGenerated, Caller\n| mv-expand CallerIpAddress=set_CallerIpAddress\n| project-away Caller1\n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", + "queryFrequency": "P1D", + "queryPeriod": "P7D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Identifies a set of Azure NSG administrative and operational detection queries for hunting activities." - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "Impact" + ], + "techniques": [ + "T1496" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Impact" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + }, + { + "columnName": "AadUserId", + "identifier": "AadUserId" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -788,13 +733,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId5'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId4'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 5", - "parentId": "[variables('huntingQueryId5')]", - "contentId": "[variables('_huntingQuerycontentId5')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion5')]", + "description": "Azure Activity Analytics Rule 4", + "parentId": "[variables('analyticRuleId4')]", + "contentId": "[variables('_analyticRulecontentId4')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion4')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -813,66 +758,100 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName6')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 6 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId4')]", + "contentKind": "AnalyticsRule", + "displayName": "Suspicious number of resource creation or deployment activities", + "contentProductId": "[variables('_analyticRulecontentProductId4')]", + "id": "[variables('_analyticRulecontentProductId4')]", + "version": "[variables('analyticRuleVersion4')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName6'),'/',variables('huntingQueryVersion6'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName5')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName6'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureRunCommandFromAzureIP_HuntingQueries Hunting Query with template version 2.0.6", + "description": "Creation_of_Expensive_Computes_in_Azure_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion6')]", + "contentVersion": "[variables('analyticRuleVersion5')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_6", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId5')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Azure VM Run Command executed from Azure IP address", - "category": "Hunting Queries", - "query": "let azure_ranges = externaldata(changeNumber: string, cloud: string, values: dynamic)\n[\"https://raw.githubusercontent.com/microsoft/mstic/master/PublicFeeds/MSFTIPRanges/ServiceTags_Public.json\"] with(format='multijson')\n| mv-expand values\n| extend Name = values.name, AddressPrefixes = values.properties.addressPrefixes\n| where Name startswith \"WindowsVirtualDesktop\"\n| mv-expand AddressPrefixes\n| summarize by tostring(AddressPrefixes);\nAzureActivity\n| where TimeGenerated > ago(30d)\n// Isolate run command actions\n| where OperationNameValue == \"Microsoft.Compute/virtualMachines/runCommand/action\"\n// Confirm that the operation impacted a virtual machine\n| where Authorization has \"virtualMachines\"\n// Each runcommand operation consists of three events when successful, Started, Accepted (or Rejected), Successful (or Failed).\n| summarize StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), max(CallerIpAddress), make_list(ActivityStatusValue) by CorrelationId, Authorization, Caller\n// Limit to Run Command executions that Succeeded\n| where list_ActivityStatusValue has \"Succeeded\"\n// Extract data from the Authorization field, allowing us to later extract the Caller (UPN) and CallerIpAddress\n| extend Authorization_d = parse_json(Authorization)\n| extend Scope = Authorization_d.scope\n| extend Scope_s = split(Scope, \"/\")\n| extend Subscription = tostring(Scope_s[2])\n| extend VirtualMachineName = tostring(Scope_s[-1])\n| project StartTime, EndTime, Subscription, VirtualMachineName, CorrelationId, Caller, CallerIpAddress=max_CallerIpAddress\n| evaluate ipv4_lookup(azure_ranges, CallerIpAddress, AddressPrefixes)\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure.\nAn adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes.\nFor Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes \nAzure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions", + "displayName": "Creation of expensive computes in Azure", + "enabled": false, + "query": "let tokens = dynamic([\"416\",\"208\",\"192\",\"128\",\"120\",\"96\",\"80\",\"72\",\"64\",\"48\",\"44\",\"40\",\"nc12\",\"nc24\",\"nv24\"]);\nlet operationList = dynamic([\"microsoft.compute/virtualmachines/write\", \"microsoft.resources/deployments/write\"]);\nAzureActivity\n| where OperationNameValue in~ (operationList)\n| where ActivityStatusValue startswith \"Accept\"\n| where Properties has 'vmSize'\n| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties\n| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)\n| mv-apply token=tokens to typeof(string) on (where vmSize contains token)\n| extend ComputerName = tostring((parsed_property.osProfile).computerName)\n| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", + "queryFrequency": "P1D", + "queryPeriod": "P1D", + "severity": "Low", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 1, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Identifies any Azure VM Run Command operation executed from an Azure IP address.\nRun Command allows an attacker or legitimate user to execute arbitrary PowerShell\non a target VM. This technique has been seen in use by NOBELIUM." + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "DefenseEvasion" + ], + "techniques": [ + "T1578" + ], + "entityMappings": [ + { + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "tactics", - "value": "LateralMovement,CredentialAccess" + "entityType": "Host", + "fieldMappings": [ + { + "columnName": "ComputerName", + "identifier": "HostName" + } + ] }, { - "name": "techniques", - "value": "T1570,T1078.004" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -880,13 +859,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId6'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId5'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 6", - "parentId": "[variables('huntingQueryId6')]", - "contentId": "[variables('_huntingQuerycontentId6')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion6')]", + "description": "Azure Activity Analytics Rule 5", + "parentId": "[variables('analyticRuleId5')]", + "contentId": "[variables('_analyticRulecontentId5')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion5')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -905,66 +884,99 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName7')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 7 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId5')]", + "contentKind": "AnalyticsRule", + "displayName": "Creation of expensive computes in Azure", + "contentProductId": "[variables('_analyticRulecontentProductId5')]", + "id": "[variables('_analyticRulecontentProductId5')]", + "version": "[variables('analyticRuleVersion5')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName7'),'/',variables('huntingQueryVersion7'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName6')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName7'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureSentinelConnectors_AdministrativeOperations_HuntingQueries Hunting Query with template version 2.0.6", + "description": "Granting_Permissions_To_Account_detection_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion7')]", + "contentVersion": "[variables('analyticRuleVersion6')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_7", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId6')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Microsoft Sentinel Connectors Administrative Operations", - "category": "Hunting Queries", - "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/dataConnectors/write\", \"Microsoft.SecurityInsights/dataConnectors/delete\"]);\n// Microsoft Sentinel Data Connectors Update / Delete\nAzureActivity\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "Identifies IPs from which users grant access to other users on Azure resources and alerts when a previously unseen source IP address is used.", + "displayName": "Suspicious granting of permissions to an account", + "enabled": false, + "query": "let starttime = 14d;\nlet endtime = 1d;\n// The number of operations above which an IP address is considered an unusual source of role assignment operations\nlet alertOperationThreshold = 5;\nlet AzureBuiltInRole = externaldata(Role:string,RoleDescription:string,ID:string) [@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/AzureBuiltInRole.csv\"] with (format=\"csv\", ignoreFirstRecord=True);\nlet createRoleAssignmentActivity = AzureActivity\n| where OperationNameValue =~ \"microsoft.authorization/roleassignments/write\";\nlet RoleAssignedActivity = createRoleAssignmentActivity \n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| summarize count() by CallerIpAddress, Caller, bin(TimeGenerated, 1d)\n| where count_ >= alertOperationThreshold\n// Returns all the records from the right side that don't have matches from the left.\n| join kind = rightanti ( \ncreateRoleAssignmentActivity\n| where TimeGenerated > ago(endtime)\n| extend parsed_property = tostring(parse_json(Properties).requestbody)\n| extend PrincipalId = case(parsed_property has_cs 'PrincipalId',parse_json(parsed_property).Properties.PrincipalId, parsed_property has_cs 'principalId',parse_json(parsed_property).properties.principalId,\"\")\n| extend PrincipalType = case(parsed_property has_cs 'PrincipalType',parse_json(parsed_property).Properties.PrincipalType, parsed_property has_cs 'principalType',parse_json(parsed_property).properties.principalType, \"\")\n| extend Scope = case(parsed_property has_cs 'Scope',parse_json(parsed_property).Properties.Scope, parsed_property has_cs 'scope',parse_json(parsed_property).properties.scope,\"\")\n| extend RoleAddedDetails = case(parsed_property has_cs 'RoleDefinitionId',parse_json(parsed_property).Properties.RoleDefinitionId,parsed_property has_cs 'roleDefinitionId',parse_json(parsed_property).properties.roleDefinitionId,\"\")\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated), ActivityStatusValue = make_set(ActivityStatusValue), CorrelationId = make_set(CorrelationId), ActivityCountByCallerIPAddress = count() \nby ResourceId, CallerIpAddress, Caller, OperationNameValue, Resource, ResourceGroup, PrincipalId, PrincipalType, Scope, RoleAddedDetails\n) on CallerIpAddress, Caller\n| extend timestamp = StartTimeUtc, AccountCustomEntity = Caller, IPCustomEntity = CallerIpAddress;\nlet RoleAssignedActivitywithRoleDetails = RoleAssignedActivity\n| extend RoleAssignedID = tostring(split(RoleAddedDetails, \"/\")[-1])\n// Returns all matching records from left and right sides.\n| join kind = inner (AzureBuiltInRole \n) on $left.RoleAssignedID == $right.ID;\nlet CallerIPCountSummary = RoleAssignedActivitywithRoleDetails | summarize AssignmentCountbyCaller = count() by Caller, CallerIpAddress;\nlet RoleAssignedActivityWithCount = RoleAssignedActivitywithRoleDetails | join kind = inner (CallerIPCountSummary | project Caller, AssignmentCountbyCaller, CallerIpAddress) on Caller, CallerIpAddress;\nRoleAssignedActivityWithCount\n| summarize arg_max(StartTimeUtc, *) by PrincipalId, RoleAssignedID\n// \tReturns all the records from the left side and only matching records from the right side.\n| join kind = leftouter( IdentityInfo\n| summarize arg_max(TimeGenerated, *) by AccountObjectId\n) on $left.PrincipalId == $right.AccountObjectId\n// Check if assignment count is greater than the threshold.\n| where AssignmentCountbyCaller >= alertOperationThreshold\n| project ActivityTimeStamp, OperationNameValue, Caller, CallerIpAddress, PrincipalId, RoleAssignedID, RoleAddedDetails, Role, RoleDescription, AccountUPN, AccountCreationTime, GroupMembership, UserType, ActivityStatusValue, ResourceGroup, PrincipalType, Scope, CorrelationId, timestamp, AccountCustomEntity, IPCustomEntity, AssignmentCountbyCaller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", + "queryFrequency": "P1D", + "queryPeriod": "P14D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Identifies a set of Microsoft Sentinel Data Connectors for administrative and operational detection queries for hunting activities." + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" }, { - "name": "tactics", - "value": "Impact" + "dataTypes": [ + "IdentityInfo" + ], + "connectorId": "BehaviorAnalytics" + } + ], + "tactics": [ + "Persistence", + "PrivilegeEscalation" + ], + "techniques": [ + "T1098", + "T1548" + ], + "entityMappings": [ + { + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -972,13 +984,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId7'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId6'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 7", - "parentId": "[variables('huntingQueryId7')]", - "contentId": "[variables('_huntingQuerycontentId7')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion7')]", + "description": "Azure Activity Analytics Rule 6", + "parentId": "[variables('analyticRuleId6')]", + "contentId": "[variables('_analyticRulecontentId6')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion6')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -997,66 +1009,87 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName8')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 8 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId6')]", + "contentKind": "AnalyticsRule", + "displayName": "Suspicious granting of permissions to an account", + "contentProductId": "[variables('_analyticRulecontentProductId6')]", + "id": "[variables('_analyticRulecontentProductId6')]", + "version": "[variables('analyticRuleVersion6')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName8'),'/',variables('huntingQueryVersion8'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName7')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName8'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureSentinelWorkbooks_AdministrativeOperation_HuntingQueries Hunting Query with template version 2.0.6", + "description": "NRT-AADHybridHealthADFSNewServer_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion8')]", + "contentVersion": "[variables('analyticRuleVersion7')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_8", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId7')]", + "apiVersion": "2022-04-01-preview", + "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Microsoft Sentinel Workbooks Administrative Operations", - "category": "Hunting Queries", - "query": "let opValues = dynamic([\"microsoft.insights/workbooks/write\", \"microsoft.insights/workbooks/delete\"]);\n// Microsoft Sentinel Workbook Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "This detection uses AzureActivity logs (Administrative category) to identify the creation or update of a server instance in an Azure AD Hybrid Health AD FS service.\nA threat actor can create a new AD Health ADFS service and create a fake server instance to spoof AD FS signing logs. There is no need to compromise an on-premises AD FS server.\nThis can be done programmatically via HTTP requests to Azure. More information in this blog: https://o365blog.com/post/hybridhealthagent/", + "displayName": "NRT Azure Active Directory Hybrid Health AD FS New Server", + "enabled": false, + "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/servicemembers/action'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Identifies set of Microsoft Sentinel Workbooks administrative operational detection queries for hunting activites" - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "DefenseEvasion" + ], + "techniques": [ + "T1578" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Impact" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -1064,13 +1097,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId8'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId7'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 8", - "parentId": "[variables('huntingQueryId8')]", - "contentId": "[variables('_huntingQuerycontentId8')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion8')]", + "description": "Azure Activity Analytics Rule 7", + "parentId": "[variables('analyticRuleId7')]", + "contentId": "[variables('_analyticRulecontentId7')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion7')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1089,66 +1122,96 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName9')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 9 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId7')]", + "contentKind": "AnalyticsRule", + "displayName": "NRT Azure Active Directory Hybrid Health AD FS New Server", + "contentProductId": "[variables('_analyticRulecontentProductId7')]", + "id": "[variables('_analyticRulecontentProductId7')]", + "version": "[variables('analyticRuleVersion7')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName9'),'/',variables('huntingQueryVersion9'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName8')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName9'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureVirtualNetworkSubnets_AdministrativeOperationset_HuntingQueries Hunting Query with template version 2.0.6", + "description": "NRT_Creation_of_Expensive_Computes_in_Azure_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion9')]", + "contentVersion": "[variables('analyticRuleVersion8')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_9", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId8')]", + "apiVersion": "2022-04-01-preview", + "kind": "NRT", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Azure Virtual Network Subnets Administrative Operations", - "category": "Hunting Queries", - "query": "let opValues = dynamic([\"Microsoft.Network/virtualNetworks/subnets/write\",\"Microsoft.Network/virtualNetworks/subnets/delete\"]);\n// Creating, Updating or Deleting Virtual Network Subnets\nAzureActivity\n| where CategoryValue =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\",\"Accepted\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure.\nAn adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes.\nFor Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes \nAzure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions", + "displayName": "NRT Creation of expensive computes in Azure", + "enabled": false, + "query": "let tokens = dynamic([\"416\",\"208\",\"192\",\"128\",\"120\",\"96\",\"80\",\"72\",\"64\",\"48\",\"44\",\"40\",\"nc12\",\"nc24\",\"nv24\"]);\nlet operationList = dynamic([\"microsoft.compute/virtualmachines/write\", \"microsoft.resources/deployments/write\"]);\nAzureActivity\n| where OperationNameValue in~ (operationList)\n| where ActivityStatusValue startswith \"Accept\"\n| where Properties has 'vmSize'\n| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties\n| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)\n| mv-apply token=tokens to typeof(string) on (where vmSize contains token)\n| extend ComputerName = tostring((parsed_property.osProfile).computerName)\n| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Identifies a set of Azure Virtual Network Subnets for administrative and operational detection queries for hunting activities." + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "DefenseEvasion" + ], + "techniques": [ + "T1578" + ], + "entityMappings": [ + { + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "tactics", - "value": "Impact" + "entityType": "Host", + "fieldMappings": [ + { + "columnName": "ComputerName", + "identifier": "HostName" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -1156,13 +1219,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId9'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId8'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 9", - "parentId": "[variables('huntingQueryId9')]", - "contentId": "[variables('_huntingQuerycontentId9')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion9')]", + "description": "Azure Activity Analytics Rule 8", + "parentId": "[variables('analyticRuleId8')]", + "contentId": "[variables('_analyticRulecontentId8')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion8')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1181,66 +1244,91 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName10')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 10 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId8')]", + "contentKind": "AnalyticsRule", + "displayName": "NRT Creation of expensive computes in Azure", + "contentProductId": "[variables('_analyticRulecontentProductId8')]", + "id": "[variables('_analyticRulecontentProductId8')]", + "version": "[variables('analyticRuleVersion8')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName10'),'/',variables('huntingQueryVersion10'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName9')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName10'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Common_Deployed_Resources_HuntingQueries Hunting Query with template version 2.0.6", + "description": "New-CloudShell-User_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion10')]", + "contentVersion": "[variables('analyticRuleVersion9')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_10", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId9')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Common deployed resources", - "category": "Hunting Queries", - "query": "AzureActivity\n| where OperationNameValue has_any (@\"deployments/write\", @\"virtualMachines/write\") \n| where ActivityStatusValue =~ \"Succeeded\"\n| summarize by bin(TimeGenerated,1d), Resource, ResourceGroup, ResourceId, OperationNameValue, Caller\n| evaluate basket()\n| where isnotempty(Caller) and isnotempty(Resource) and isnotempty(TimeGenerated)\n| order by Percent desc, TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend AzureResource_0_ResourceId = ResourceId\n// remove comments below on filters if the goal is to see more common or more rare Resource, Resource Group and Caller combinations\n//| where Percent <= 40 // <-- more rare\n//| where Percent >= 60 // <-- more common\n", - "version": 2, - "tags": [ + "description": "Identifies when a user creates an Azure CloudShell for the first time.\nMonitor this activity to ensure only the expected users are using CloudShell.", + "displayName": "New CloudShell User", + "enabled": false, + "query": "let match_window = 3m;\nAzureActivity\n| where ResourceGroup has \"cloud-shell\"\n| where (OperationNameValue =~ \"Microsoft.Storage/storageAccounts/listKeys/action\")\n| where ActivityStatusValue =~ \"Success\"\n| extend TimeKey = bin(TimeGenerated, match_window), AzureIP = CallerIpAddress\n| join kind = inner\n(AzureActivity\n| where ResourceGroup has \"cloud-shell\"\n| where (OperationNameValue =~ \"Microsoft.Storage/storageAccounts/write\")\n| extend TimeKey = bin(TimeGenerated, match_window), UserIP = CallerIpAddress\n) on Caller, TimeKey\n| summarize count() by TimeKey, Caller, ResourceGroup, SubscriptionId, TenantId, AzureIP, UserIP, HTTPRequest, Type, Properties, CategoryValue, OperationList = strcat(OperationNameValue, ' , ', OperationNameValue1)\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", + "queryFrequency": "P1D", + "queryPeriod": "P1D", + "severity": "Low", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "This query looks for common deployed resources (resource name and resource groups) and can be used\nin combination with other signals that show suspicious deployment to evaluate if the resource is one\nthat is commonly being deployed/created or unique.\nTo understand the basket() function better see - https://docs.microsoft.com/azure/data-explorer/kusto/query/basketplugin" - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "Execution" + ], + "techniques": [ + "T1059" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Impact" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "UserIP", + "identifier": "Address" + } + ] } ] } @@ -1248,13 +1336,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId10'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId9'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 10", - "parentId": "[variables('huntingQueryId10')]", - "contentId": "[variables('_huntingQuerycontentId10')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion10')]", + "description": "Azure Activity Analytics Rule 9", + "parentId": "[variables('analyticRuleId9')]", + "contentId": "[variables('_analyticRulecontentId9')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion9')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1273,66 +1361,95 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName11')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 11 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId9')]", + "contentKind": "AnalyticsRule", + "displayName": "New CloudShell User", + "contentProductId": "[variables('_analyticRulecontentProductId9')]", + "id": "[variables('_analyticRulecontentProductId9')]", + "version": "[variables('analyticRuleVersion9')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName11'),'/',variables('huntingQueryVersion11'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName10')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName11'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Creating_Anomalous_Number_Of_Resources_HuntingQueries Hunting Query with template version 2.0.6", + "description": "NewResourceGroupsDeployedTo_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion11')]", + "contentVersion": "[variables('analyticRuleVersion10')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_11", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId10')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Creation of an anomalous number of resources", - "category": "Hunting Queries", - "query": "AzureActivity\n| where OperationNameValue in~ (\"microsoft.compute/virtualMachines/write\", \"microsoft.resources/deployments/write\")\n| where ActivityStatusValue == \"Succeeded\" \n| make-series dcount(ResourceId) default=0 on EventSubmissionTimestamp in range(ago(7d), now(), 1d) by Caller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n", - "version": 2, - "tags": [ + "description": "Identifies when a rare Resource and ResourceGroup deployment occurs by a previously unseen caller.", + "displayName": "Suspicious Resource deployment", + "enabled": false, + "query": "// Add or remove operation names below as per your requirements. For operations lists, please refer to https://learn.microsoft.com/en-us/Azure/role-based-access-control/resource-provider-operations#all\nlet szOperationNames = dynamic([\"Microsoft.Compute/virtualMachines/write\", \"Microsoft.Resources/deployments/write\", \"Microsoft.Resources/subscriptions/resourceGroups/write\"]);\nlet starttime = 14d;\nlet endtime = 1d;\nlet RareCaller = AzureActivity\n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| where OperationNameValue in~ (szOperationNames)\n| summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d)\n// Returns all the records from the right side that don't have matches from the left.\n| join kind=rightantisemi (\nAzureActivity\n| where TimeGenerated > ago(endtime)\n| where OperationNameValue in~ (szOperationNames)\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated,100), ActivityStatusValue = make_set(ActivityStatusValue,100), CorrelationIds = make_set(CorrelationId,100), ResourceGroups = make_set(ResourceGroup,100), ResourceIds = make_set(_ResourceId,100), ActivityCountByCallerIPAddress = count()\nby CallerIpAddress, Caller, OperationNameValue) on CallerIpAddress, Caller, OperationNameValue;\nRareCaller\n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", + "queryFrequency": "P1D", + "queryPeriod": "P14D", + "severity": "Low", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Looks for anomalous number of resources creation or deployment activities in azure activity log.\nIt is best to run this query on a look back period which is at least 7 days." - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "Impact" + ], + "techniques": [ + "T1496" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Impact" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + }, + { + "columnName": "AadUserId", + "identifier": "AadUserId" + } + ] }, { - "name": "techniques", - "value": "T1496" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -1340,13 +1457,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId11'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId10'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 11", - "parentId": "[variables('huntingQueryId11')]", - "contentId": "[variables('_huntingQuerycontentId11')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion11')]", + "description": "Azure Activity Analytics Rule 10", + "parentId": "[variables('analyticRuleId10')]", + "contentId": "[variables('_analyticRulecontentId10')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion10')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1365,66 +1482,93 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName12')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 12 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId10')]", + "contentKind": "AnalyticsRule", + "displayName": "Suspicious Resource deployment", + "contentProductId": "[variables('_analyticRulecontentProductId10')]", + "id": "[variables('_analyticRulecontentProductId10')]", + "version": "[variables('analyticRuleVersion10')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName12'),'/',variables('huntingQueryVersion12'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName11')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName12'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Granting_Permissions_to_Account_HuntingQueries Hunting Query with template version 2.0.6", + "description": "RareOperations_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion12')]", + "contentVersion": "[variables('analyticRuleVersion11')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_12", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId11')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Granting permissions to account", - "category": "Hunting Queries", - "query": "AzureActivity\n| where OperationName =~ \"Create role assignment\"\n| where ActivityStatus =~ \"Succeeded\" \n| project Caller, CallerIpAddress\n| evaluate basket()\n// Returns all the records from the left side and only matching records from the right side.\n| join kind=leftouter (AzureActivity\n| where OperationName =~ \"Create role assignment\"\n| where ActivityStatus =~ \"Succeeded\"\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Caller, CallerIpAddress)\non Caller, CallerIpAddress\n| project-away Caller1, CallerIpAddress1\n| where isnotempty(StartTime)\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ + "description": "This query looks for a few sensitive subscription-level events based on Azure Activity Logs. For example, this monitors for the operation name 'Create or Update Snapshot', which is used for creating backups but could be misused by attackers to dump hashes or extract sensitive information from the disk.", + "displayName": "Rare subscription-level operations in Azure", + "enabled": false, + "query": "let starttime = 14d;\nlet endtime = 1d;\n// The number of operations above which an IP address is considered an unusual source of role assignment operations\nlet alertOperationThreshold = 5;\n// Add or remove operation names below as per your requirements. For operations lists, please refer to https://learn.microsoft.com/en-us/Azure/role-based-access-control/resource-provider-operations#all\nlet SensitiveOperationList = dynamic([\"microsoft.compute/snapshots/write\", \"microsoft.network/networksecuritygroups/write\", \"microsoft.storage/storageaccounts/listkeys/action\"]);\nlet SensitiveActivity = AzureActivity\n| where OperationNameValue in~ (SensitiveOperationList) or OperationNameValue hassuffix \"listkeys/action\"\n| where ActivityStatusValue =~ \"Success\";\nSensitiveActivity\n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d)\n| where count_ >= alertOperationThreshold\n// Returns all the records from the right side that don't have matches from the left\n| join kind = rightanti (\nSensitiveActivity\n| where TimeGenerated >= ago(endtime)\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_list(TimeGenerated), ActivityStatusValue = make_list(ActivityStatusValue), CorrelationIds = make_list(CorrelationId), ResourceGroups = make_list(ResourceGroup), ResourceIds = make_list(_ResourceId), ActivityCountByCallerIPAddress = count()\nby CallerIpAddress, Caller, OperationNameValue\n| where ActivityCountByCallerIPAddress >= alertOperationThreshold\n) on CallerIpAddress, Caller, OperationNameValue\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", + "queryFrequency": "P1D", + "queryPeriod": "P14D", + "severity": "Low", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "description", - "value": "Shows the most prevalent users who grant access to others on Azure resources. List the common source IP address for each of those accounts. If an operation is not from those IP addresses, it may be worthy of investigation." - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "CredentialAccess", + "Persistence" + ], + "techniques": [ + "T1003", + "T1098" + ], + "entityMappings": [ { - "name": "tactics", - "value": "Persistence,PrivilegeEscalation" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + } + ] }, { - "name": "techniques", - "value": "T1098" + "entityType": "IP", + "fieldMappings": [ + { + "columnName": "CallerIpAddress", + "identifier": "Address" + } + ] } ] } @@ -1432,13 +1576,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId12'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId11'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 12", - "parentId": "[variables('huntingQueryId12')]", - "contentId": "[variables('_huntingQuerycontentId12')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion12')]", + "description": "Azure Activity Analytics Rule 11", + "parentId": "[variables('analyticRuleId11')]", + "contentId": "[variables('_analyticRulecontentId11')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion11')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1457,66 +1601,86 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName13')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 13 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId11')]", + "contentKind": "AnalyticsRule", + "displayName": "Rare subscription-level operations in Azure", + "contentProductId": "[variables('_analyticRulecontentProductId11')]", + "id": "[variables('_analyticRulecontentProductId11')]", + "version": "[variables('analyticRuleVersion11')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName13'),'/',variables('huntingQueryVersion13'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('analyticRuleTemplateSpecName12')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName13'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "PortOpenedForAzureResource_HuntingQueries Hunting Query with template version 2.0.6", + "description": "TimeSeriesAnomaly_Mass_Cloud_Resource_Deletions_AnalyticalRules Analytics Rule with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion13')]", + "contentVersion": "[variables('analyticRuleVersion12')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_13", + "type": "Microsoft.SecurityInsights/AlertRuleTemplates", + "name": "[variables('analyticRulecontentId12')]", + "apiVersion": "2022-04-01-preview", + "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "eTag": "*", - "displayName": "Port opened for an Azure Resource", - "category": "Hunting Queries", - "query": "let lookback = 7d;\nAzureActivity\n| where TimeGenerated >= ago(lookback)\n| where OperationNameValue has_any (\"ipfilterrules\", \"securityRules\", \"publicIPAddresses\", \"firewallrules\") and OperationNameValue endswith \"write\"\n// Choosing Accepted here because it has the Rule Attributes included\n| where ActivityStatusValue == \"Accepted\" \n// If there is publicIP info, include it\n| extend parsed_properties = parse_json(tostring(parse_json(Properties).responseBody)).properties\n| extend publicIPAddressVersion = case(Properties has_cs 'publicIPAddressVersion',tostring(parsed_properties.publicIPAddressVersion),\"\")\n| extend publicIPAllocationMethod = case(Properties has_cs 'publicIPAllocationMethod',tostring(parsed_properties.publicIPAllocationMethod),\"\")\n// Include rule attributes for context\n| extend access = case(Properties has_cs 'access',tostring(parsed_properties.access),\"\")\n| extend description = case(Properties has_cs 'description',tostring(parsed_properties.description),\"\")\n| extend destinationPortRange = case(Properties has_cs 'destinationPortRange',tostring(parsed_properties.destinationPortRange),\"\")\n| extend direction = case(Properties has_cs 'direction',tostring(parsed_properties.direction),\"\")\n| extend protocol = case(Properties has_cs 'protocol',tostring(parsed_properties.protocol),\"\")\n| extend sourcePortRange = case(Properties has_cs 'sourcePortRange',tostring(parsed_properties.sourcePortRange),\"\")\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResourceIds = make_set(_ResourceId,100) by Caller, CallerIpAddress, Resource, ResourceGroup, \nActivityStatusValue, ActivitySubstatus, SubscriptionId, access, description, destinationPortRange, direction, protocol, sourcePortRange, publicIPAddressVersion, publicIPAllocationMethod\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", - "version": 2, - "tags": [ - { - "name": "description", - "value": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days" - }, + "description": "This query generates the baseline pattern of cloud resource deletions by an individual and generates an anomaly when any unusual spike is detected. These anomalies from unusual or privileged users could be an indication of a cloud infrastructure takedown by an adversary.", + "displayName": "Mass Cloud resource deletions Time Series Anomaly", + "enabled": false, + "query": "let starttime = 14d;\nlet endtime = 1d;\nlet timeframe = 1d;\nlet TotalEventsThreshold = 25;\nlet TimeSeriesData = AzureActivity \n| where TimeGenerated between (startofday(ago(starttime))..startofday(now())) \n| where OperationNameValue endswith \"delete\" \n| project TimeGenerated, Caller \n| make-series Total = count() on TimeGenerated from startofday(ago(starttime)) to startofday(now()) step timeframe by Caller;\nTimeSeriesData \n| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, 3, -1, 'linefit') \n| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long) \n| where TimeGenerated >= startofday(ago(endtime)) \n| where anomalies > 0 \n| project Caller, TimeGenerated, Total, baseline, anomalies, score \n| where Total > TotalEventsThreshold and baseline > 0 \n| join (AzureActivity \n| where TimeGenerated > startofday(ago(endtime)) \n| where OperationNameValue endswith \"delete\" \n| summarize count(), make_set(OperationNameValue,100), make_set(_ResourceId,100) by bin(TimeGenerated, timeframe), Caller ) on TimeGenerated, Caller \n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", + "queryFrequency": "P1D", + "queryPeriod": "P14D", + "severity": "Medium", + "suppressionDuration": "PT1H", + "suppressionEnabled": false, + "triggerOperator": "GreaterThan", + "triggerThreshold": 0, + "status": "Available", + "requiredDataConnectors": [ { - "name": "tactics", - "value": "CommandAndControl,Impact" - }, + "dataTypes": [ + "AzureActivity" + ], + "connectorId": "AzureActivity" + } + ], + "tactics": [ + "Impact" + ], + "techniques": [ + "T1485" + ], + "entityMappings": [ { - "name": "techniques", - "value": "T1071,T1571,T1496" + "entityType": "Account", + "fieldMappings": [ + { + "columnName": "Name", + "identifier": "Name" + }, + { + "columnName": "UPNSuffix", + "identifier": "UPNSuffix" + }, + { + "columnName": "AadUserId", + "identifier": "AadUserId" + } + ] } ] } @@ -1524,13 +1688,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId13'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId12'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 13", - "parentId": "[variables('huntingQueryId13')]", - "contentId": "[variables('_huntingQuerycontentId13')]", - "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion13')]", + "description": "Azure Activity Analytics Rule 12", + "parentId": "[variables('analyticRuleId12')]", + "contentId": "[variables('_analyticRulecontentId12')]", + "kind": "AnalyticsRule", + "version": "[variables('analyticRuleVersion12')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1549,66 +1713,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('huntingQueryTemplateSpecName14')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, - "properties": { - "description": "Azure Activity Hunting Query 14 with template", - "displayName": "Azure Activity Hunting Query template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_analyticRulecontentId12')]", + "contentKind": "AnalyticsRule", + "displayName": "Mass Cloud resource deletions Time Series Anomaly", + "contentProductId": "[variables('_analyticRulecontentProductId12')]", + "id": "[variables('_analyticRulecontentProductId12')]", + "version": "[variables('analyticRuleVersion12')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('huntingQueryTemplateSpecName14'),'/',variables('huntingQueryVersion14'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName1')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "HuntingQuery" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('huntingQueryTemplateSpecName14'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Rare_Custom_Script_Extension_HuntingQueries Hunting Query with template version 2.0.6", + "description": "AnalyticsRulesAdministrativeOperations_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('huntingQueryVersion14')]", + "contentVersion": "[variables('huntingQueryVersion1')]", "parameters": {}, "variables": {}, "resources": [ { "type": "Microsoft.OperationalInsights/savedSearches", - "apiVersion": "2020-08-01", - "name": "Azure_Activity_Hunting_Query_14", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_1", "location": "[parameters('workspace-location')]", "properties": { "eTag": "*", - "displayName": "Rare Custom Script Extension", + "displayName": "Microsoft Sentinel Analytics Rules Administrative Operations", "category": "Hunting Queries", - "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet Lookback = starttime - 14d;\nlet CustomScriptExecution = AzureActivity\n| where TimeGenerated >= Lookback\n| where OperationName =~ \"Create or Update Virtual Machine Extension\"\n| extend parsed_properties = parse_json(Properties)\n| extend Settings = tostring((parse_json(tostring(parsed_properties.responseBody)).properties).settings)\n| parse Settings with * 'fileUris\":[' FileURI \"]\" *\n| parse Settings with * 'commandToExecute\":' commandToExecute '}' *\n| extend message_ = tostring((parse_json(tostring(parsed_properties.statusMessage)).error).message);\nlet LookbackCustomScriptExecution = CustomScriptExecution\n| where TimeGenerated >= Lookback and TimeGenerated < starttime\n| where isnotempty(FileURI) and isnotempty(commandToExecute)\n| summarize max(TimeGenerated), OperationCount = count() by Caller, Resource, CallerIpAddress, FileURI, commandToExecute;\nlet CurrentCustomScriptExecution = CustomScriptExecution\n| where TimeGenerated between (starttime..endtime)\n| where isnotempty(FileURI) and isnotempty(commandToExecute)\n| project TimeGenerated, ActivityStatus, OperationId, CorrelationId, ResourceId, CallerIpAddress, Caller, OperationName, Resource, ResourceGroup, FileURI, commandToExecute, FailureMessage = message_, HTTPRequest, Settings;\nlet RareCustomScriptExecution = CurrentCustomScriptExecution\n| join kind= leftanti (LookbackCustomScriptExecution) on Caller, CallerIpAddress, FileURI, commandToExecute;\nlet IPCheck = RareCustomScriptExecution\n| summarize arg_max(TimeGenerated, OperationName), OperationIds = make_set(OperationId,100), CallerIpAddresses = make_set(CallerIpAddress,100) by ActivityStatus, CorrelationId, ResourceId, Caller, Resource, ResourceGroup, FileURI, commandToExecute, FailureMessage\n| extend IPArray = array_length(CallerIpAddresses);\n//Get IPs for later summarization so all associated CorrelationIds and Caller actions have an IP. Success and Fails do not always have IP\nlet multiIP = IPCheck | where IPArray > 1\n| mv-expand CallerIpAddresses | extend CallerIpAddress = tostring(CallerIpAddresses)\n| where isnotempty(CallerIpAddresses);\nlet singleIP = IPCheck | where IPArray <= 1\n| mv-expand CallerIpAddresses | extend CallerIpAddress = tostring(CallerIpAddresses);\nlet FullDetails = singleIP | union multiIP;\n//Get IP address associated with successes and fails with no IP listed\nlet IPList = FullDetails | where isnotempty(CallerIpAddress) | summarize by CorrelationId, Caller, CallerIpAddress;\nlet EmptyIP = FullDetails | where isempty(CallerIpAddress) | project-away CallerIpAddress;\nlet IpJoin = EmptyIP | join kind= leftouter (IPList) on CorrelationId, Caller | project-away CorrelationId1, Caller1;\nlet nonEmptyIP = FullDetails | where isnotempty(CallerIpAddress);\nnonEmptyIP | union IpJoin\n// summarize all activities with a given CorrelationId and Caller together so we can provide a singular result\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ActivityStatusSet = make_set(ActivityStatus,100), OperationIds = make_set(OperationIds,100), FailureMessages = make_set(FailureMessage,100) by CorrelationId, ResourceId, CallerIpAddress, Caller, Resource, ResourceGroup, FileURI, commandToExecute\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/alertRules/write\", \"Microsoft.SecurityInsights/alertRules/delete\"]);\n// Microsoft Sentinel Analytics - Rule Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", "version": 2, "tags": [ { "name": "description", - "value": "The Custom Script Extension downloads and executes scripts on Azure virtual machines. This extension is useful for post deployment configuration, software installation, or any other configuration or management tasks.\n Scripts could be downloaded from external links, Azure storage, GitHub, or provided to the Azure portal at extension run time. This could also be used maliciously by an attacker.\n The query tries to identify rare custom script extensions that have been executed in your environment" + "value": "Identifies Microsoft Sentinel Analytics Rules administrative operations" }, { "name": "tactics", - "value": "Execution" + "value": "Impact" }, { "name": "techniques", - "value": "T1059" + "value": "T1496" } ] } @@ -1616,13 +1773,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId14'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId1'),'/'))))]", "properties": { - "description": "Azure Activity Hunting Query 14", - "parentId": "[variables('huntingQueryId14')]", - "contentId": "[variables('_huntingQuerycontentId14')]", + "description": "Azure Activity Hunting Query 1", + "parentId": "[variables('huntingQueryId1')]", + "contentId": "[variables('_huntingQuerycontentId1')]", "kind": "HuntingQuery", - "version": "[variables('huntingQueryVersion14')]", + "version": "[variables('huntingQueryVersion1')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1641,98 +1798,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 1 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId1')]", + "contentKind": "HuntingQuery", + "displayName": "Microsoft Sentinel Analytics Rules Administrative Operations", + "contentProductId": "[variables('_huntingQuerycontentProductId1')]", + "id": "[variables('_huntingQuerycontentProductId1')]", + "version": "[variables('huntingQueryVersion1')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName1'),'/',variables('analyticRuleVersion1'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName2')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName1'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AADHybridHealthADFSNewServer_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AnomalousAzureOperationModel_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion1')]", + "contentVersion": "[variables('huntingQueryVersion2')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId1')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_2", "location": "[parameters('workspace-location')]", "properties": { - "description": "This detection uses AzureActivity logs (Administrative category) to identify the creation or update of a server instance in an Azure AD Hybrid Health AD FS service.\nA threat actor can create a new AD Health ADFS service and create a fake server instance to spoof AD FS signing logs. There is no need to compromise an on-premises AD FS server.\nThis can be done programmatically via HTTP requests to Azure. More information in this blog: https://o365blog.com/post/hybridhealthagent/", - "displayName": "Azure Active Directory Hybrid Health AD FS New Server", - "enabled": false, - "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/servicemembers/action'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", - "queryFrequency": "P1D", - "queryPeriod": "P1D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Anomalous Azure Operation Hunting Model", + "category": "Hunting Queries", + "query": "// When the detection window will end (3 days prior to now)\nlet startDetectDate = 3d;\n// When the detection window will start (now)\nlet endDetectDate = 0d;\n// When to start collecting data for detection\nlet startDate = startDetectDate + 30d;\n// Operation to monitor, in this case Run Command\nlet monitoredOps = dynamic(['microsoft.compute/virtualmachines/runcommand/action']);\n// The resource type to monitor, in this case virtual machines\nlet monitoredResource = pack_array('microsoft.compute/virtualmachines');\nlet pair_probabilities_fl = (tbl:(*), A_col:string, B_col:string, scope_col:string)\n{\nlet T = (tbl | extend _A = column_ifexists(A_col, ''), _B = column_ifexists(B_col, ''), _scope = column_ifexists(scope_col, ''));\nlet countOnScope = T | summarize countAllOnScope = count() by _scope;\nlet probAB = T | summarize countAB = count() by _A, _B, _scope | join kind = leftouter (countOnScope) on _scope | extend P_AB = todouble(countAB)/countAllOnScope;\nlet probA = probAB | summarize countA = sum(countAB), countAllOnScope = max(countAllOnScope) by _A, _scope | extend P_A = todouble(countA)/countAllOnScope;\nlet probB = probAB | summarize countB = sum(countAB), countAllOnScope = max(countAllOnScope) by _B, _scope | extend P_B = todouble(countB)/countAllOnScope;\n probAB\n | join kind = leftouter (probA) on _A, _scope\n | join kind = leftouter (probB) on _B, _scope\n | extend P_AUB = P_A + P_B - P_AB\n , P_AIB = P_AB/P_B\n , P_BIA = P_AB/P_A\n | extend Lift_AB = P_AB/(P_A * P_B)\n , Jaccard_AB = P_AB/P_AUB\n | project _A, _B, _scope, floor(P_A, 0.00001), floor(P_B, 0.00001), floor(P_AB, 0.00001), floor(P_AUB, 0.00001), floor(P_AIB, 0.00001)\n , floor(P_BIA, 0.00001), floor(Lift_AB, 0.00001), floor(Jaccard_AB, 0.00001)\n | sort by _scope, _A, _B\n};\nlet eventsTable = materialize (\nAzureActivity\n| where TimeGenerated between (ago(startDate) .. ago(endDetectDate))\n| where isnotempty(CallerIpAddress)\n| where ActivityStatusValue has_any ('Success', 'Succeeded')\n| extend ResourceId = iff(isempty(_ResourceId), ResourceId, _ResourceId)\n| extend splitOp = split(OperationNameValue, '/')\n| extend splitRes = split(ResourceId, '/')\n| project TimeGenerated , subscriptionId=SubscriptionId\n , ResourceProvider\n , ResourceName = tolower(tostring(splitRes[-1]))\n , OperationNameValue = tolower(OperationNameValue)\n , timeSlice = floor(TimeGenerated, 1d)\n , clientIp = tostring(CallerIpAddress)\n , Caller\n , isMonitoredOp = iff(OperationNameValue has_any (monitoredOps), 1, 0)\n , isMonitoredResource = iff(OperationNameValue has_any (monitoredResource), 1, 0)\n , CorrelationId\n| extend clientIpMask = format_ipv4_mask(clientIp, 16)\n);\nlet modelData = (\neventsTable\n| where TimeGenerated < ago(startDetectDate) and isnotempty(Caller) and isnotempty(subscriptionId)\n| summarize countEvents = count(), countMonRes = countif(isMonitoredResource == 1), counMonOp = countif(isMonitoredOp == 1)\n , firstSeen = min(timeSlice), firstSeenOnMonRes = minif(timeSlice, isMonitoredResource == 1), firstSeenOnMonOp = minif(timeSlice, isMonitoredOp == 1)\n by subscriptionId, Caller, clientIpMask\n);\nlet monOpProbs = materialize (\neventsTable\n| where TimeGenerated < ago(startDetectDate) and isnotempty(Caller) and isnotempty(subscriptionId)\n| invoke pair_probabilities_fl('Caller', 'isMonitoredResource','subscriptionId')\n| where _B == 1\n| sort by P_AIB desc\n| extend rankOnMonRes = row_rank(P_AIB), sumBiggerCondProbs = row_cumsum(P_AIB) - P_AIB\n| extend avgBiggerCondProbs = floor(iff(rankOnMonRes > 1, sumBiggerCondProbs/(rankOnMonRes-1), max_of(0.0, prev(sumBiggerCondProbs))), 0.00001)\n| project-away sumBiggerCondProbs\n);\neventsTable\n| where TimeGenerated between (ago(startDetectDate) .. ago(endDetectDate))\n| join kind = leftouter (modelData | summarize countEventsPrincOnSub = sum(countEvents), countEventsMonResPrincOnSub = sum(countMonRes), countEventsMonOpPrincOnSub = sum(counMonOp)\n , firstSeenPrincOnSubs = min(firstSeen), firstSeenMonResPrincOnSubs = min(firstSeenOnMonRes), firstSeenMonOpPrincOnSubs = min(firstSeenOnMonOp) by subscriptionId, Caller) \n on subscriptionId, Caller\n| join kind = leftouter (modelData | summarize countEventsIpMaskOnSub = sum(countEvents), countEventsMonResIpMaskOnSub = sum(countMonRes), countEventsMonOpIpMaskOnSub = sum(counMonOp)\n , firstSeenIpMaskOnSubs = min(firstSeen), firstSeenMonResIpMaskOnSubs = min(firstSeenOnMonRes), firstSeenMonOpIpMaskOnSubs = min(firstSeenOnMonOp) by subscriptionId, clientIpMask) \n on subscriptionId, clientIpMask\n| join kind = leftouter (modelData | summarize countEventsOnSub = sum(countEvents), countEventsMonResOnSub = sum(countMonRes), countEventsMonOpOnSub = sum(counMonOp)\n , firstSeenOnSubs = min(firstSeen), firstSeenMonResOnSubs = min(firstSeenOnMonRes), firstSeenMonOpOnSubs = min(firstSeenOnMonOp)\n , countCallersOnSubs = dcount(Caller), countIpMasksOnSubs = dcount(clientIpMask) by subscriptionId)\n on subscriptionId \n| project-away subscriptionId1, Caller1, subscriptionId2\n| extend daysOnSubs = datetime_diff('day', timeSlice, firstSeenOnSubs)\n| extend avgMonOpOnSubs = floor(1.0*countEventsMonOpOnSub/daysOnSubs, 0.01), avgMonResOnSubs = floor(1.0*countEventsMonResOnSub/daysOnSubs, 0.01)\n| join kind = leftouter(monOpProbs) on $left.subscriptionId == $right._scope, $left.Caller == $right._A\n| project-away _A, _B, _scope\n| sort by subscriptionId asc, TimeGenerated asc\n| extend rnOnSubs = row_number(1, subscriptionId != prev(subscriptionId))\n| sort by subscriptionId asc, Caller asc, TimeGenerated asc\n| extend rnOnCallerSubs = row_number(1, (subscriptionId != prev(subscriptionId) and (Caller != prev(Caller))))\n| extend newCaller = iff(isempty(firstSeenPrincOnSubs), 1, 0)\n , newCallerOnMonRes = iff(isempty(firstSeenMonResPrincOnSubs), 1, 0)\n , newIpMask = iff(isempty(firstSeenIpMaskOnSubs), 1, 0)\n , newIpMaskOnMonRes = iff(isempty(firstSeenMonResIpMaskOnSubs), 1, 0)\n , newMonOpOnSubs = iff(isempty(firstSeenMonResOnSubs), 1, 0)\n , anomCallerMonRes = iff(((Jaccard_AB <= 0.1) or (P_AIB <= 0.1)), 1, 0)\n| project TimeGenerated, subscriptionId, ResourceProvider, ResourceName, OperationNameValue, Caller, CorrelationId, ClientIP=clientIp, ActiveDaysOnSub=daysOnSubs, avgMonOpOnSubs, newCaller, newCallerOnMonRes, newIpMask, newIpMaskOnMonRes, newMonOpOnSubs, anomCallerMonRes, isMonitoredOp, isMonitoredResource\n| order by TimeGenerated\n| where isMonitoredOp == 1\n// Optional - focus only on monitored operations or monitored resource in detection window\n| where isMonitoredOp == 1\n//| where isMonitoredResource == 1\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "DefenseEvasion" - ], - "techniques": [ - "T1578" - ], - "entityMappings": [ + "name": "description", + "value": "This query can be used during threat hunts to identify a range of different Azure Operation anomalies.\nThe query is heavily commented inline to explain operation. Anomalies covered are: New Caller, New Caller IP,\nNew Caller IP Range, Anomalous operation based on Jaccard index. By default this query is configured to detect\nanomalous Run Command operations. The operation and resource type to perform anomaly detection can be configured \nat the top of the query along with the detection window parameters" + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "LateralMovement,CredentialAccess" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1570,T1078.004" } ] } @@ -1740,13 +1858,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId1'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId2'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 1", - "parentId": "[variables('analyticRuleId1')]", - "contentId": "[variables('_analyticRulecontentId1')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion1')]", + "description": "Azure Activity Hunting Query 2", + "parentId": "[variables('huntingQueryId2')]", + "contentId": "[variables('_huntingQuerycontentId2')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion2')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1765,98 +1883,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName2')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 2 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId2')]", + "contentKind": "HuntingQuery", + "displayName": "Anomalous Azure Operation Hunting Model", + "contentProductId": "[variables('_huntingQuerycontentProductId2')]", + "id": "[variables('_huntingQuerycontentProductId2')]", + "version": "[variables('huntingQueryVersion2')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName2'),'/',variables('analyticRuleVersion2'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName3')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName2'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AADHybridHealthADFSServiceDelete_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "Anomalous_Listing_Of_Storage_Keys_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion2')]", + "contentVersion": "[variables('huntingQueryVersion3')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId2')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_3", "location": "[parameters('workspace-location')]", "properties": { - "description": "This detection uses AzureActivity logs (Administrative category) to identify the deletion of an Azure AD Hybrid Health AD FS service instance in a tenant.\nA threat actor can create a new AD Health ADFS service and create a fake server to spoof AD FS signing logs.\nThe health AD FS service can then be deleted after it is no longer needed via HTTP requests to Azure.\nMore information is available in this blog https://o365blog.com/post/hybridhealthagent/", - "displayName": "Azure Active Directory Hybrid Health AD FS Service Delete", - "enabled": false, - "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/delete'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", - "queryFrequency": "P1D", - "queryPeriod": "P1D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Azure storage key enumeration", + "category": "Hunting Queries", + "query": "AzureActivity\n| where OperationNameValue =~ \"microsoft.storage/storageaccounts/listkeys/action\"\n| where ActivityStatusValue =~ \"Succeeded\" \n| join kind= inner (\n AzureActivity\n | where OperationNameValue =~ \"microsoft.storage/storageaccounts/listkeys/action\"\n | where ActivityStatusValue =~ \"Succeeded\" \n | project ExpectedIpAddress=CallerIpAddress, Caller \n | evaluate autocluster()\n) on Caller\n| where CallerIpAddress != ExpectedIpAddress\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResourceIds = make_set(ResourceId,100), ResourceIdCount = dcount(ResourceId) by OperationNameValue, Caller, CallerIpAddress\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "DefenseEvasion" - ], - "techniques": [ - "T1578" - ], - "entityMappings": [ + "name": "description", + "value": "Listing of storage keys is an interesting operation in Azure which might expose additional \nsecrets and PII to callers as well as granting access to VMs. While there are many benign operations of this\ntype, it would be interesting to see if the account performing this activity or the source IP address from \nwhich it is being done is anomalous. \nThe query below generates known clusters of ip address per caller, notice that users which only had single\noperations do not appear in this list as we cannot learn from it their normal activity (only based on a single\nevent). The activities for listing storage account keys is correlated with this learned \nclusters of expected activities and activity which is not expected is returned." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "Discovery" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1087" } ] } @@ -1864,13 +1943,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId2'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId3'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 2", - "parentId": "[variables('analyticRuleId2')]", - "contentId": "[variables('_analyticRulecontentId2')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion2')]", + "description": "Azure Activity Hunting Query 3", + "parentId": "[variables('huntingQueryId3')]", + "contentId": "[variables('_huntingQuerycontentId3')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion3')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -1889,100 +1968,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName3')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 3 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId3')]", + "contentKind": "HuntingQuery", + "displayName": "Azure storage key enumeration", + "contentProductId": "[variables('_huntingQuerycontentProductId3')]", + "id": "[variables('_huntingQuerycontentProductId3')]", + "version": "[variables('huntingQueryVersion3')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName3'),'/',variables('analyticRuleVersion3'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName4')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName3'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AADHybridHealthADFSSuspApp_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureAdministrationFromVPS_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion3')]", + "contentVersion": "[variables('huntingQueryVersion4')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId3')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_4", "location": "[parameters('workspace-location')]", "properties": { - "description": "This detection uses AzureActivity logs (Administrative category) to identify a suspicious application adding a server instance to an Azure AD Hybrid Health AD FS service or deleting the AD FS service instance.\nUsually the Azure AD Connect Health Agent application with ID cf6d7e68-f018-4e0a-a7b3-126e053fb88d and ID cb1056e2-e479-49de-ae31-7812af012ed8 is used to perform those operations.", - "displayName": "Azure Active Directory Hybrid Health AD FS Suspicious Application", - "enabled": false, - "query": "// Azure AD Connect Health Agent - cf6d7e68-f018-4e0a-a7b3-126e053fb88d\n// Azure Active Directory Connect - cb1056e2-e479-49de-ae31-7812af012ed8\nlet appList = dynamic(['cf6d7e68-f018-4e0a-a7b3-126e053fb88d','cb1056e2-e479-49de-ae31-7812af012ed8']);\nlet operationNamesList = dynamic(['Microsoft.ADHybridHealthService/services/servicemembers/action','Microsoft.ADHybridHealthService/services/delete']);\nAzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue in~ (operationNamesList)\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| where AppId !in (appList)\n| project-away claimsJson\n", - "queryFrequency": "P1D", - "queryPeriod": "P1D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ - { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "CredentialAccess", - "DefenseEvasion" - ], - "techniques": [ - "T1528", - "T1550" - ], - "entityMappings": [ + "eTag": "*", + "displayName": "AzureActivity Administration From VPS Providers", + "category": "Hunting Queries", + "query": "let IP_Data = (externaldata(network:string)\n[@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/VPS_Networks.csv\"] with (format=\"csv\"));\nAzureActivity\n| where CategoryValue =~ \"Administrative\"\n| evaluate ipv4_lookup(IP_Data, CallerIpAddress, network, return_unmatched = false)\n| summarize Operations = make_set(OperationNameValue), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by CallerIpAddress, Caller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "description", + "value": "Looks for administrative actions in AzureActivity from known VPS provider network ranges.\nThis is not an exhaustive list of VPS provider ranges but covers some of the most prevalent providers observed." + }, + { + "name": "tactics", + "value": "InitialAccess" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1078" } ] } @@ -1990,13 +2028,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId3'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId4'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 3", - "parentId": "[variables('analyticRuleId3')]", - "contentId": "[variables('_analyticRulecontentId3')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion3')]", + "description": "Azure Activity Hunting Query 4", + "parentId": "[variables('huntingQueryId4')]", + "contentId": "[variables('_huntingQuerycontentId4')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion4')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2015,102 +2053,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName4')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 4 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId4')]", + "contentKind": "HuntingQuery", + "displayName": "AzureActivity Administration From VPS Providers", + "contentProductId": "[variables('_huntingQuerycontentProductId4')]", + "id": "[variables('_huntingQuerycontentProductId4')]", + "version": "[variables('huntingQueryVersion4')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName4'),'/',variables('analyticRuleVersion4'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName5')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName4'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Creating_Anomalous_Number_Of_Resources_detection_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureNSG_AdministrativeOperations_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion4')]", + "contentVersion": "[variables('huntingQueryVersion5')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId4')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_5", "location": "[parameters('workspace-location')]", "properties": { - "description": "Indicates when an anomalous number of VM creations or deployment activities occur in Azure via the AzureActivity log. This query generates the baseline pattern of cloud resource creation by an individual and generates an anomaly when any unusual spike is detected. These anomalies from unusual or privileged users could be an indication of a cloud infrastructure takedown by an adversary.", - "displayName": "Suspicious number of resource creation or deployment activities", - "enabled": false, - "query": "let szOperationNames = dynamic([\"microsoft.compute/virtualMachines/write\", \"microsoft.resources/deployments/write\"]);\nlet starttime = 7d;\nlet endtime = 1d;\nlet timeframe = 1d;\nlet TimeSeriesData =\nAzureActivity\n| where TimeGenerated between (startofday(ago(starttime)) .. startofday(now()))\n| where OperationNameValue in~ (szOperationNames)\n| project TimeGenerated, Caller \n| make-series Total = count() on TimeGenerated from startofday(ago(starttime)) to startofday(now()) step timeframe by Caller; \nTimeSeriesData\n| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, 3, -1, 'linefit')\n| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long) \n| where TimeGenerated >= startofday(ago(endtime))\n| where anomalies > 0 and baseline > 0\n| project Caller, TimeGenerated, Total, baseline, anomalies, score\n| join (AzureActivity\n| where TimeGenerated > startofday(ago(endtime)) \n| where OperationNameValue in~ (szOperationNames)\n| summarize make_set(OperationNameValue,100), make_set(_ResourceId,100), make_set(CallerIpAddress,100) by bin(TimeGenerated, timeframe), Caller\n) on TimeGenerated, Caller\n| mv-expand CallerIpAddress=set_CallerIpAddress\n| project-away Caller1\n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", - "queryFrequency": "P1D", - "queryPeriod": "P7D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Azure Network Security Group NSG Administrative Operations", + "category": "Hunting Queries", + "query": "let opValues = dynamic([\"Microsoft.Network/networkSecurityGroups/write\", \"Microsoft.Network/networkSecurityGroups/delete\"]);\n// Azure NSG Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\",\"Accepted\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "Impact" - ], - "techniques": [ - "T1496" - ], - "entityMappings": [ + "name": "description", + "value": "Identifies a set of Azure NSG administrative and operational detection queries for hunting activities." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - }, - { - "columnName": "AadUserId", - "identifier": "AadUserId" - } - ] + "name": "tactics", + "value": "Impact" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1496" } ] } @@ -2118,13 +2113,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId4'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId5'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 4", - "parentId": "[variables('analyticRuleId4')]", - "contentId": "[variables('_analyticRulecontentId4')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion4')]", + "description": "Azure Activity Hunting Query 5", + "parentId": "[variables('huntingQueryId5')]", + "contentId": "[variables('_huntingQuerycontentId5')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion5')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2143,98 +2138,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName5')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 5 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId5')]", + "contentKind": "HuntingQuery", + "displayName": "Azure Network Security Group NSG Administrative Operations", + "contentProductId": "[variables('_huntingQuerycontentProductId5')]", + "id": "[variables('_huntingQuerycontentProductId5')]", + "version": "[variables('huntingQueryVersion5')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName5'),'/',variables('analyticRuleVersion5'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName6')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName5'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Creation_of_Expensive_Computes_in_Azure_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureRunCommandFromAzureIP_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion5')]", + "contentVersion": "[variables('huntingQueryVersion6')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId5')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_6", "location": "[parameters('workspace-location')]", "properties": { - "description": "Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure.\nAn adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes.\nFor Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes \nAzure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions", - "displayName": "Creation of expensive computes in Azure", - "enabled": false, - "query": "let tokens = dynamic([\"416\",\"208\",\"192\",\"128\",\"120\",\"96\",\"80\",\"72\",\"64\",\"48\",\"44\",\"40\",\"g5\",\"gs5\",\"g4\",\"gs4\",\"nc12\",\"nc24\",\"nv24\"]);\nlet operationList = dynamic([\"microsoft.compute/virtualmachines/write\", \"microsoft.resources/deployments/write\"]);\nAzureActivity\n| where OperationNameValue in~ (operationList)\n| where ActivityStatusValue startswith \"Accept\"\n| where Properties has 'vmSize'\n| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties\n| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)\n| where vmSize has_any (tokens)\n| extend ComputerName = tostring((parsed_property.osProfile).computerName)\n| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", - "queryFrequency": "P1D", - "queryPeriod": "P1D", - "severity": "Low", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 1, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Azure VM Run Command executed from Azure IP address", + "category": "Hunting Queries", + "query": "let azure_ranges = externaldata(changeNumber: string, cloud: string, values: dynamic)\n[\"https://raw.githubusercontent.com/microsoft/mstic/master/PublicFeeds/MSFTIPRanges/ServiceTags_Public.json\"] with(format='multijson')\n| mv-expand values\n| extend Name = values.name, AddressPrefixes = values.properties.addressPrefixes\n| where Name startswith \"WindowsVirtualDesktop\"\n| mv-expand AddressPrefixes\n| summarize by tostring(AddressPrefixes);\nAzureActivity\n| where TimeGenerated > ago(30d)\n// Isolate run command actions\n| where OperationNameValue == \"Microsoft.Compute/virtualMachines/runCommand/action\"\n// Confirm that the operation impacted a virtual machine\n| where Authorization has \"virtualMachines\"\n// Each runcommand operation consists of three events when successful, Started, Accepted (or Rejected), Successful (or Failed).\n| summarize StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), max(CallerIpAddress), make_list(ActivityStatusValue) by CorrelationId, Authorization, Caller\n// Limit to Run Command executions that Succeeded\n| where list_ActivityStatusValue has \"Succeeded\"\n// Extract data from the Authorization field, allowing us to later extract the Caller (UPN) and CallerIpAddress\n| extend Authorization_d = parse_json(Authorization)\n| extend Scope = Authorization_d.scope\n| extend Scope_s = split(Scope, \"/\")\n| extend Subscription = tostring(Scope_s[2])\n| extend VirtualMachineName = tostring(Scope_s[-1])\n| project StartTime, EndTime, Subscription, VirtualMachineName, CorrelationId, Caller, CallerIpAddress=max_CallerIpAddress\n| evaluate ipv4_lookup(azure_ranges, CallerIpAddress, AddressPrefixes)\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "DefenseEvasion" - ], - "techniques": [ - "T1578" - ], - "entityMappings": [ + "name": "description", + "value": "Identifies any Azure VM Run Command operation executed from an Azure IP address.\nRun Command allows an attacker or legitimate user to execute arbitrary PowerShell\non a target VM. This technique has been seen in use by NOBELIUM." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "LateralMovement,CredentialAccess" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1570,T1078.004" } ] } @@ -2242,13 +2198,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId5'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId6'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 5", - "parentId": "[variables('analyticRuleId5')]", - "contentId": "[variables('_analyticRulecontentId5')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion5')]", + "description": "Azure Activity Hunting Query 6", + "parentId": "[variables('huntingQueryId6')]", + "contentId": "[variables('_huntingQuerycontentId6')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion6')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2267,106 +2223,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName6')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 6 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId6')]", + "contentKind": "HuntingQuery", + "displayName": "Azure VM Run Command executed from Azure IP address", + "contentProductId": "[variables('_huntingQuerycontentProductId6')]", + "id": "[variables('_huntingQuerycontentProductId6')]", + "version": "[variables('huntingQueryVersion6')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName6'),'/',variables('analyticRuleVersion6'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName7')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName6'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Granting_Permissions_To_Account_detection_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureSentinelConnectors_AdministrativeOperations_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion6')]", + "contentVersion": "[variables('huntingQueryVersion7')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId6')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", - "location": "[parameters('workspace-location')]", - "properties": { - "description": "Identifies IPs from which users grant access to other users on Azure resources and alerts when a previously unseen source IP address is used.", - "displayName": "Suspicious granting of permissions to an account", - "enabled": false, - "query": "let starttime = 14d;\nlet endtime = 1d;\n// The number of operations above which an IP address is considered an unusual source of role assignment operations\nlet alertOperationThreshold = 5;\nlet AzureBuiltInRole = externaldata(Role:string,RoleDescription:string,ID:string) [@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/AzureBuiltInRole.csv\"] with (format=\"csv\", ignoreFirstRecord=True);\nlet createRoleAssignmentActivity = AzureActivity\n| where OperationNameValue =~ \"microsoft.authorization/roleassignments/write\";\nlet RoleAssignedActivity = createRoleAssignmentActivity \n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| summarize count() by CallerIpAddress, Caller, bin(TimeGenerated, 1d)\n| where count_ >= alertOperationThreshold\n// Returns all the records from the right side that don't have matches from the left.\n| join kind = rightanti ( \ncreateRoleAssignmentActivity\n| where TimeGenerated > ago(endtime)\n| extend parsed_property = tostring(parse_json(Properties).requestbody)\n| extend PrincipalId = case(parsed_property has_cs 'PrincipalId',parse_json(parsed_property).Properties.PrincipalId, parsed_property has_cs 'principalId',parse_json(parsed_property).properties.principalId,\"\")\n| extend PrincipalType = case(parsed_property has_cs 'PrincipalType',parse_json(parsed_property).Properties.PrincipalType, parsed_property has_cs 'principalType',parse_json(parsed_property).properties.principalType, \"\")\n| extend Scope = case(parsed_property has_cs 'Scope',parse_json(parsed_property).Properties.Scope, parsed_property has_cs 'scope',parse_json(parsed_property).properties.scope,\"\")\n| extend RoleAddedDetails = case(parsed_property has_cs 'RoleDefinitionId',parse_json(parsed_property).Properties.RoleDefinitionId,parsed_property has_cs 'roleDefinitionId',parse_json(parsed_property).properties.roleDefinitionId,\"\")\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated), ActivityStatusValue = make_set(ActivityStatusValue), CorrelationId = make_set(CorrelationId), ActivityCountByCallerIPAddress = count() \nby ResourceId, CallerIpAddress, Caller, OperationNameValue, Resource, ResourceGroup, PrincipalId, PrincipalType, Scope, RoleAddedDetails\n) on CallerIpAddress, Caller\n| extend timestamp = StartTimeUtc, AccountCustomEntity = Caller, IPCustomEntity = CallerIpAddress;\nlet RoleAssignedActivitywithRoleDetails = RoleAssignedActivity\n| extend RoleAssignedID = tostring(split(RoleAddedDetails, \"/\")[-1])\n// Returns all matching records from left and right sides.\n| join kind = inner (AzureBuiltInRole \n) on $left.RoleAssignedID == $right.ID;\nlet CallerIPCountSummary = RoleAssignedActivitywithRoleDetails | summarize AssignmentCountbyCaller = count() by Caller, CallerIpAddress;\nlet RoleAssignedActivityWithCount = RoleAssignedActivitywithRoleDetails | join kind = inner (CallerIPCountSummary | project Caller, AssignmentCountbyCaller, CallerIpAddress) on Caller, CallerIpAddress;\nRoleAssignedActivityWithCount\n| summarize arg_max(StartTimeUtc, *) by PrincipalId, RoleAssignedID\n// \tReturns all the records from the left side and only matching records from the right side.\n| join kind = leftouter( IdentityInfo\n| summarize arg_max(TimeGenerated, *) by AccountObjectId\n) on $left.PrincipalId == $right.AccountObjectId\n// Check if assignment count is greater than the threshold.\n| where AssignmentCountbyCaller >= alertOperationThreshold\n| project ActivityTimeStamp, OperationNameValue, Caller, CallerIpAddress, PrincipalId, RoleAssignedID, RoleAddedDetails, Role, RoleDescription, AccountUPN, AccountCreationTime, GroupMembership, UserType, ActivityStatusValue, ResourceGroup, PrincipalType, Scope, CorrelationId, timestamp, AccountCustomEntity, IPCustomEntity, AssignmentCountbyCaller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", - "queryFrequency": "P1D", - "queryPeriod": "P14D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ - { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - }, - { - "dataTypes": [ - "IdentityInfo" - ], - "connectorId": "BehaviorAnalytics" - } - ], - "tactics": [ - "Persistence", - "PrivilegeEscalation" - ], - "techniques": [ - "T1098", - "T1548" - ], - "entityMappings": [ + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_7", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Microsoft Sentinel Connectors Administrative Operations", + "category": "Hunting Queries", + "query": "let opValues = dynamic([\"Microsoft.SecurityInsights/dataConnectors/write\", \"Microsoft.SecurityInsights/dataConnectors/delete\"]);\n// Microsoft Sentinel Data Connectors Update / Delete\nAzureActivity\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "description", + "value": "Identifies a set of Microsoft Sentinel Data Connectors for administrative and operational detection queries for hunting activities." }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "tactics", + "value": "Impact" + }, + { + "name": "techniques", + "value": "T1496" } ] } @@ -2374,13 +2283,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId6'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId7'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 6", - "parentId": "[variables('analyticRuleId6')]", - "contentId": "[variables('_analyticRulecontentId6')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion6')]", + "description": "Azure Activity Hunting Query 7", + "parentId": "[variables('huntingQueryId7')]", + "contentId": "[variables('_huntingQuerycontentId7')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion7')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2399,94 +2308,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName7')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 7 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId7')]", + "contentKind": "HuntingQuery", + "displayName": "Microsoft Sentinel Connectors Administrative Operations", + "contentProductId": "[variables('_huntingQuerycontentProductId7')]", + "id": "[variables('_huntingQuerycontentProductId7')]", + "version": "[variables('huntingQueryVersion7')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName7'),'/',variables('analyticRuleVersion7'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName8')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName7'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NRT-AADHybridHealthADFSNewServer_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureSentinelWorkbooks_AdministrativeOperation_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion7')]", + "contentVersion": "[variables('huntingQueryVersion8')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId7')]", - "apiVersion": "2022-04-01-preview", - "kind": "NRT", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_8", "location": "[parameters('workspace-location')]", "properties": { - "description": "This detection uses AzureActivity logs (Administrative category) to identify the creation or update of a server instance in an Azure AD Hybrid Health AD FS service.\nA threat actor can create a new AD Health ADFS service and create a fake server instance to spoof AD FS signing logs. There is no need to compromise an on-premises AD FS server.\nThis can be done programmatically via HTTP requests to Azure. More information in this blog: https://o365blog.com/post/hybridhealthagent/", - "displayName": "NRT Azure Active Directory Hybrid Health AD FS New Server", - "enabled": false, - "query": "AzureActivity\n| where CategoryValue =~ 'Administrative'\n| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'\n| where _ResourceId has 'AdFederationService'\n| where OperationNameValue =~ 'Microsoft.ADHybridHealthService/services/servicemembers/action'\n| extend claimsJson = parse_json(Claims)\n| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| project-away claimsJson\n", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Microsoft Sentinel Workbooks Administrative Operations", + "category": "Hunting Queries", + "query": "let opValues = dynamic([\"microsoft.insights/workbooks/write\", \"microsoft.insights/workbooks/delete\"]);\n// Microsoft Sentinel Workbook Create / Update / Delete\nAzureActivity\n| where Category =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\", \"OK\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "DefenseEvasion" - ], - "techniques": [ - "T1578" - ], - "entityMappings": [ + "name": "description", + "value": "Identifies set of Microsoft Sentinel Workbooks administrative operational detection queries for hunting activites" + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "Impact" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1496" } ] } @@ -2494,13 +2368,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId7'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId8'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 7", - "parentId": "[variables('analyticRuleId7')]", - "contentId": "[variables('_analyticRulecontentId7')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion7')]", + "description": "Azure Activity Hunting Query 8", + "parentId": "[variables('huntingQueryId8')]", + "contentId": "[variables('_huntingQuerycontentId8')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion8')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2519,94 +2393,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName8')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 8 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId8')]", + "contentKind": "HuntingQuery", + "displayName": "Microsoft Sentinel Workbooks Administrative Operations", + "contentProductId": "[variables('_huntingQuerycontentProductId8')]", + "id": "[variables('_huntingQuerycontentProductId8')]", + "version": "[variables('huntingQueryVersion8')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName8'),'/',variables('analyticRuleVersion8'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName9')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName8'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NRT_Creation_of_Expensive_Computes_in_Azure_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "AzureVirtualNetworkSubnets_AdministrativeOperationset_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion8')]", + "contentVersion": "[variables('huntingQueryVersion9')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId8')]", - "apiVersion": "2022-04-01-preview", - "kind": "NRT", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_9", "location": "[parameters('workspace-location')]", "properties": { - "description": "Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure.\nAn adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes.\nFor Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes \nAzure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions", - "displayName": "NRT Creation of expensive computes in Azure", - "enabled": false, - "query": "let tokens = dynamic([\"416\",\"208\",\"192\",\"128\",\"120\",\"96\",\"80\",\"72\",\"64\",\"48\",\"44\",\"40\",\"g5\",\"gs5\",\"g4\",\"gs4\",\"nc12\",\"nc24\",\"nv24\"]);\nlet operationList = dynamic([\"microsoft.compute/virtualmachines/write\", \"microsoft.resources/deployments/write\"]);\nAzureActivity\n| where OperationNameValue in~ (operationList)\n| where ActivityStatusValue startswith \"Accept\"\n| where Properties has 'vmSize'\n| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties\n| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)\n| where vmSize has_any (tokens)\n| extend ComputerName = tostring((parsed_property.osProfile).computerName)\n| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Azure Virtual Network Subnets Administrative Operations", + "category": "Hunting Queries", + "query": "let opValues = dynamic([\"Microsoft.Network/virtualNetworks/subnets/write\",\"Microsoft.Network/virtualNetworks/subnets/delete\"]);\n// Creating, Updating or Deleting Virtual Network Subnets\nAzureActivity\n| where CategoryValue =~ \"Administrative\"\n| where OperationNameValue in~ (opValues)\n| where ActivitySubstatusValue in~ (\"Created\",\"Accepted\")\n| sort by TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "DefenseEvasion" - ], - "techniques": [ - "T1578" - ], - "entityMappings": [ + "name": "description", + "value": "Identifies a set of Azure Virtual Network Subnets for administrative and operational detection queries for hunting activities." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "Impact" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1496" } ] } @@ -2614,13 +2453,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId8'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId9'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 8", - "parentId": "[variables('analyticRuleId8')]", - "contentId": "[variables('_analyticRulecontentId8')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion8')]", + "description": "Azure Activity Hunting Query 9", + "parentId": "[variables('huntingQueryId9')]", + "contentId": "[variables('_huntingQuerycontentId9')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion9')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2639,98 +2478,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName9')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 9 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId9')]", + "contentKind": "HuntingQuery", + "displayName": "Azure Virtual Network Subnets Administrative Operations", + "contentProductId": "[variables('_huntingQuerycontentProductId9')]", + "id": "[variables('_huntingQuerycontentProductId9')]", + "version": "[variables('huntingQueryVersion9')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName9'),'/',variables('analyticRuleVersion9'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName10')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName9'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "New-CloudShell-User_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "Common_Deployed_Resources_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion9')]", + "contentVersion": "[variables('huntingQueryVersion10')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId9')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_10", "location": "[parameters('workspace-location')]", "properties": { - "description": "Identifies when a user creates an Azure CloudShell for the first time.\nMonitor this activity to ensure only the expected users are using CloudShell.", - "displayName": "New CloudShell User", - "enabled": false, - "query": "let match_window = 3m;\nAzureActivity\n| where ResourceGroup has \"cloud-shell\"\n| where (OperationNameValue =~ \"Microsoft.Storage/storageAccounts/listKeys/action\")\n| where ActivityStatusValue =~ \"Success\"\n| extend TimeKey = bin(TimeGenerated, match_window), AzureIP = CallerIpAddress\n| join kind = inner\n(AzureActivity\n| where ResourceGroup has \"cloud-shell\"\n| where (OperationNameValue =~ \"Microsoft.Storage/storageAccounts/write\")\n| extend TimeKey = bin(TimeGenerated, match_window), UserIP = CallerIpAddress\n) on Caller, TimeKey\n| summarize count() by TimeKey, Caller, ResourceGroup, SubscriptionId, TenantId, AzureIP, UserIP, HTTPRequest, Type, Properties, CategoryValue, OperationList = strcat(OperationNameValue, ' , ', OperationNameValue1)\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", - "queryFrequency": "P1D", - "queryPeriod": "P1D", - "severity": "Low", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ - { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "Execution" - ], - "techniques": [ - "T1059" - ], - "entityMappings": [ + "eTag": "*", + "displayName": "Common deployed resources", + "category": "Hunting Queries", + "query": "AzureActivity\n| where OperationNameValue has_any (@\"deployments/write\", @\"virtualMachines/write\") \n| where ActivityStatusValue =~ \"Succeeded\"\n| summarize by bin(TimeGenerated,1d), Resource, ResourceGroup, ResourceId, OperationNameValue, Caller\n| evaluate basket()\n| where isnotempty(Caller) and isnotempty(Resource) and isnotempty(TimeGenerated)\n| order by Percent desc, TimeGenerated desc\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend AzureResource_0_ResourceId = ResourceId\n// remove comments below on filters if the goal is to see more common or more rare Resource, Resource Group and Caller combinations\n//| where Percent <= 40 // <-- more rare\n//| where Percent >= 60 // <-- more common\n", + "version": 2, + "tags": [ { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "description", + "value": "This query looks for common deployed resources (resource name and resource groups) and can be used\nin combination with other signals that show suspicious deployment to evaluate if the resource is one\nthat is commonly being deployed/created or unique.\nTo understand the basket() function better see - https://docs.microsoft.com/azure/data-explorer/kusto/query/basketplugin" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "UserIP", - "identifier": "Address" - } - ] + "name": "tactics", + "value": "Impact" + }, + { + "name": "techniques", + "value": "T1496" } ] } @@ -2738,13 +2538,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId9'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId10'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 9", - "parentId": "[variables('analyticRuleId9')]", - "contentId": "[variables('_analyticRulecontentId9')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion9')]", + "description": "Azure Activity Hunting Query 10", + "parentId": "[variables('huntingQueryId10')]", + "contentId": "[variables('_huntingQuerycontentId10')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion10')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2763,102 +2563,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName10')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 10 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId10')]", + "contentKind": "HuntingQuery", + "displayName": "Common deployed resources", + "contentProductId": "[variables('_huntingQuerycontentProductId10')]", + "id": "[variables('_huntingQuerycontentProductId10')]", + "version": "[variables('huntingQueryVersion10')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName10'),'/',variables('analyticRuleVersion10'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName11')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName10'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "NewResourceGroupsDeployedTo_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "Creating_Anomalous_Number_Of_Resources_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion10')]", + "contentVersion": "[variables('huntingQueryVersion11')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId10')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_11", "location": "[parameters('workspace-location')]", "properties": { - "description": "Identifies when a rare Resource and ResourceGroup deployment occurs by a previously unseen caller.", - "displayName": "Suspicious Resource deployment", - "enabled": false, - "query": "// Add or remove operation names below as per your requirements. For operations lists, please refer to https://learn.microsoft.com/en-us/Azure/role-based-access-control/resource-provider-operations#all\nlet szOperationNames = dynamic([\"Microsoft.Compute/virtualMachines/write\", \"Microsoft.Resources/deployments/write\", \"Microsoft.Resources/subscriptions/resourceGroups/write\"]);\nlet starttime = 14d;\nlet endtime = 1d;\nlet RareCaller = AzureActivity\n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| where OperationNameValue in~ (szOperationNames)\n| summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d)\n// Returns all the records from the right side that don't have matches from the left.\n| join kind=rightantisemi (\nAzureActivity\n| where TimeGenerated > ago(endtime)\n| where OperationNameValue in~ (szOperationNames)\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated,100), ActivityStatusValue = make_set(ActivityStatusValue,100), CorrelationIds = make_set(CorrelationId,100), ResourceGroups = make_set(ResourceGroup,100), ResourceIds = make_set(_ResourceId,100), ActivityCountByCallerIPAddress = count()\nby CallerIpAddress, Caller, OperationNameValue) on CallerIpAddress, Caller, OperationNameValue;\nRareCaller\n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", - "queryFrequency": "P1D", - "queryPeriod": "P14D", - "severity": "Low", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Creation of an anomalous number of resources", + "category": "Hunting Queries", + "query": "AzureActivity\n| where OperationNameValue in~ (\"microsoft.compute/virtualMachines/write\", \"microsoft.resources/deployments/write\")\n| where ActivityStatusValue == \"Succeeded\" \n| make-series dcount(ResourceId) default=0 on EventSubmissionTimestamp in range(ago(7d), now(), 1d) by Caller\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "Impact" - ], - "techniques": [ - "T1496" - ], - "entityMappings": [ + "name": "description", + "value": "Looks for anomalous number of resources creation or deployment activities in azure activity log.\nIt is best to run this query on a look back period which is at least 7 days." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - }, - { - "columnName": "AadUserId", - "identifier": "AadUserId" - } - ] + "name": "tactics", + "value": "Impact" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1496" } ] } @@ -2866,13 +2623,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId10'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId11'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 10", - "parentId": "[variables('analyticRuleId10')]", - "contentId": "[variables('_analyticRulecontentId10')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion10')]", + "description": "Azure Activity Hunting Query 11", + "parentId": "[variables('huntingQueryId11')]", + "contentId": "[variables('_huntingQuerycontentId11')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion11')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -2891,100 +2648,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName11')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 11 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId11')]", + "contentKind": "HuntingQuery", + "displayName": "Creation of an anomalous number of resources", + "contentProductId": "[variables('_huntingQuerycontentProductId11')]", + "id": "[variables('_huntingQuerycontentProductId11')]", + "version": "[variables('huntingQueryVersion11')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName11'),'/',variables('analyticRuleVersion11'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName12')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName11'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "RareOperations_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "Granting_Permissions_to_Account_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion11')]", + "contentVersion": "[variables('huntingQueryVersion12')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId11')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_12", "location": "[parameters('workspace-location')]", "properties": { - "description": "This query looks for a few sensitive subscription-level events based on Azure Activity Logs. For example, this monitors for the operation name 'Create or Update Snapshot', which is used for creating backups but could be misused by attackers to dump hashes or extract sensitive information from the disk.", - "displayName": "Rare subscription-level operations in Azure", - "enabled": false, - "query": "let starttime = 14d;\nlet endtime = 1d;\n// The number of operations above which an IP address is considered an unusual source of role assignment operations\nlet alertOperationThreshold = 5;\n// Add or remove operation names below as per your requirements. For operations lists, please refer to https://learn.microsoft.com/en-us/Azure/role-based-access-control/resource-provider-operations#all\nlet SensitiveOperationList = dynamic([\"microsoft.compute/snapshots/write\", \"microsoft.network/networksecuritygroups/write\", \"microsoft.storage/storageaccounts/listkeys/action\"]);\nlet SensitiveActivity = AzureActivity\n| where OperationNameValue in~ (SensitiveOperationList) or OperationNameValue hassuffix \"listkeys/action\"\n| where ActivityStatusValue =~ \"Success\";\nSensitiveActivity\n| where TimeGenerated between (ago(starttime) .. ago(endtime))\n| summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d)\n| where count_ >= alertOperationThreshold\n// Returns all the records from the right side that don't have matches from the left\n| join kind = rightanti (\nSensitiveActivity\n| where TimeGenerated >= ago(endtime)\n| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_list(TimeGenerated), ActivityStatusValue = make_list(ActivityStatusValue), CorrelationIds = make_list(CorrelationId), ResourceGroups = make_list(ResourceGroup), ResourceIds = make_list(_ResourceId), ActivityCountByCallerIPAddress = count()\nby CallerIpAddress, Caller, OperationNameValue\n| where ActivityCountByCallerIPAddress >= alertOperationThreshold\n) on CallerIpAddress, Caller, OperationNameValue\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n", - "queryFrequency": "P1D", - "queryPeriod": "P14D", - "severity": "Low", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "eTag": "*", + "displayName": "Granting permissions to account", + "category": "Hunting Queries", + "query": "AzureActivity\n| where OperationName =~ \"Create role assignment\"\n| where ActivityStatus =~ \"Succeeded\" \n| project Caller, CallerIpAddress\n| evaluate basket()\n// Returns all the records from the left side and only matching records from the right side.\n| join kind=leftouter (AzureActivity\n| where OperationName =~ \"Create role assignment\"\n| where ActivityStatus =~ \"Succeeded\"\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Caller, CallerIpAddress)\non Caller, CallerIpAddress\n| project-away Caller1, CallerIpAddress1\n| where isnotempty(StartTime)\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "CredentialAccess", - "Persistence" - ], - "techniques": [ - "T1003", - "T1098" - ], - "entityMappings": [ + "name": "description", + "value": "Shows the most prevalent users who grant access to others on Azure resources. List the common source IP address for each of those accounts. If an operation is not from those IP addresses, it may be worthy of investigation." + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - } - ] + "name": "tactics", + "value": "Persistence,PrivilegeEscalation" }, { - "entityType": "IP", - "fieldMappings": [ - { - "columnName": "CallerIpAddress", - "identifier": "Address" - } - ] + "name": "techniques", + "value": "T1098" } ] } @@ -2992,13 +2708,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId11'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId12'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 11", - "parentId": "[variables('analyticRuleId11')]", - "contentId": "[variables('_analyticRulecontentId11')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion11')]", + "description": "Azure Activity Hunting Query 12", + "parentId": "[variables('huntingQueryId12')]", + "contentId": "[variables('_huntingQuerycontentId12')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion12')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -3017,93 +2733,59 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('analyticRuleTemplateSpecName12')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, - "properties": { - "description": "Azure Activity Analytics Rule 12 with template", - "displayName": "Azure Activity Analytics Rule template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId12')]", + "contentKind": "HuntingQuery", + "displayName": "Granting permissions to account", + "contentProductId": "[variables('_huntingQuerycontentProductId12')]", + "id": "[variables('_huntingQuerycontentProductId12')]", + "version": "[variables('huntingQueryVersion12')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('analyticRuleTemplateSpecName12'),'/',variables('analyticRuleVersion12'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName13')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "AnalyticsRule" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('analyticRuleTemplateSpecName12'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "TimeSeriesAnomaly_Mass_Cloud_Resource_Deletions_AnalyticalRules Analytics Rule with template version 2.0.6", + "description": "PortOpenedForAzureResource_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('analyticRuleVersion12')]", + "contentVersion": "[variables('huntingQueryVersion13')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.SecurityInsights/AlertRuleTemplates", - "name": "[variables('AnalyticRulecontentId12')]", - "apiVersion": "2022-04-01-preview", - "kind": "Scheduled", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_13", "location": "[parameters('workspace-location')]", - "properties": { - "description": "This query generates the baseline pattern of cloud resource deletions by an individual and generates an anomaly when any unusual spike is detected. These anomalies from unusual or privileged users could be an indication of a cloud infrastructure takedown by an adversary.", - "displayName": "Mass Cloud resource deletions Time Series Anomaly", - "enabled": false, - "query": "let starttime = 14d;\nlet endtime = 1d;\nlet timeframe = 1d;\nlet TotalEventsThreshold = 25;\nlet TimeSeriesData = AzureActivity \n| where TimeGenerated between (startofday(ago(starttime))..startofday(now())) \n| where OperationNameValue endswith \"delete\" \n| project TimeGenerated, Caller \n| make-series Total = count() on TimeGenerated from startofday(ago(starttime)) to startofday(now()) step timeframe by Caller;\nTimeSeriesData \n| extend (anomalies, score, baseline) = series_decompose_anomalies(Total, 3, -1, 'linefit') \n| mv-expand Total to typeof(double), TimeGenerated to typeof(datetime), anomalies to typeof(double), score to typeof(double), baseline to typeof(long) \n| where TimeGenerated >= startofday(ago(endtime)) \n| where anomalies > 0 \n| project Caller, TimeGenerated, Total, baseline, anomalies, score \n| where Total > TotalEventsThreshold and baseline > 0 \n| join (AzureActivity \n| where TimeGenerated > startofday(ago(endtime)) \n| where OperationNameValue endswith \"delete\" \n| summarize count(), make_set(OperationNameValue,100), make_set(_ResourceId,100) by bin(TimeGenerated, timeframe), Caller ) on TimeGenerated, Caller \n| extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),\"\")\n| extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),\"\")\n| extend AadUserId = iif(Caller !has '@',Caller,\"\")\n", - "queryFrequency": "P1D", - "queryPeriod": "P14D", - "severity": "Medium", - "suppressionDuration": "PT1H", - "suppressionEnabled": false, - "triggerOperator": "GreaterThan", - "triggerThreshold": 0, - "status": "Available", - "requiredDataConnectors": [ + "properties": { + "eTag": "*", + "displayName": "Port opened for an Azure Resource", + "category": "Hunting Queries", + "query": "let lookback = 7d;\nAzureActivity\n| where TimeGenerated >= ago(lookback)\n| where OperationNameValue has_any (\"ipfilterrules\", \"securityRules\", \"publicIPAddresses\", \"firewallrules\") and OperationNameValue endswith \"write\"\n// Choosing Accepted here because it has the Rule Attributes included\n| where ActivityStatusValue == \"Accepted\" \n// If there is publicIP info, include it\n| extend parsed_properties = parse_json(tostring(parse_json(Properties).responseBody)).properties\n| extend publicIPAddressVersion = case(Properties has_cs 'publicIPAddressVersion',tostring(parsed_properties.publicIPAddressVersion),\"\")\n| extend publicIPAllocationMethod = case(Properties has_cs 'publicIPAllocationMethod',tostring(parsed_properties.publicIPAllocationMethod),\"\")\n// Include rule attributes for context\n| extend access = case(Properties has_cs 'access',tostring(parsed_properties.access),\"\")\n| extend description = case(Properties has_cs 'description',tostring(parsed_properties.description),\"\")\n| extend destinationPortRange = case(Properties has_cs 'destinationPortRange',tostring(parsed_properties.destinationPortRange),\"\")\n| extend direction = case(Properties has_cs 'direction',tostring(parsed_properties.direction),\"\")\n| extend protocol = case(Properties has_cs 'protocol',tostring(parsed_properties.protocol),\"\")\n| extend sourcePortRange = case(Properties has_cs 'sourcePortRange',tostring(parsed_properties.sourcePortRange),\"\")\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ResourceIds = make_set(_ResourceId,100) by Caller, CallerIpAddress, Resource, ResourceGroup, \nActivityStatusValue, ActivitySubstatus, SubscriptionId, access, description, destinationPortRange, direction, protocol, sourcePortRange, publicIPAddressVersion, publicIPAllocationMethod\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ { - "dataTypes": [ - "AzureActivity" - ], - "connectorId": "AzureActivity" - } - ], - "tactics": [ - "Impact" - ], - "techniques": [ - "T1485" - ], - "entityMappings": [ + "name": "description", + "value": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days" + }, { - "entityType": "Account", - "fieldMappings": [ - { - "columnName": "Name", - "identifier": "Name" - }, - { - "columnName": "UPNSuffix", - "identifier": "UPNSuffix" - }, - { - "columnName": "AadUserId", - "identifier": "AadUserId" - } - ] + "name": "tactics", + "value": "CommandAndControl,Impact" + }, + { + "name": "techniques", + "value": "T1071,T1571,T1496" } ] } @@ -3111,13 +2793,13 @@ { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId12'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId13'),'/'))))]", "properties": { - "description": "Azure Activity Analytics Rule 12", - "parentId": "[variables('analyticRuleId12')]", - "contentId": "[variables('_analyticRulecontentId12')]", - "kind": "AnalyticsRule", - "version": "[variables('analyticRuleVersion12')]", + "description": "Azure Activity Hunting Query 13", + "parentId": "[variables('huntingQueryId13')]", + "contentId": "[variables('_huntingQuerycontentId13')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion13')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -3136,70 +2818,73 @@ } } ] - } - } - }, - { - "type": "Microsoft.Resources/templateSpecs", - "apiVersion": "2022-02-01", - "name": "[variables('workbookTemplateSpecName1')]", - "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "Workbook" - }, - "properties": { - "description": "Azure Activity Workbook with template", - "displayName": "Azure Activity workbook template" + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId13')]", + "contentKind": "HuntingQuery", + "displayName": "Port opened for an Azure Resource", + "contentProductId": "[variables('_huntingQuerycontentProductId13')]", + "id": "[variables('_huntingQuerycontentProductId13')]", + "version": "[variables('huntingQueryVersion13')]" } }, { - "type": "Microsoft.Resources/templateSpecs/versions", - "apiVersion": "2022-02-01", - "name": "[concat(variables('workbookTemplateSpecName1'),'/',variables('workbookVersion1'))]", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('huntingQueryTemplateSpecName14')]", "location": "[parameters('workspace-location')]", - "tags": { - "hidden-sentinelWorkspaceId": "[variables('workspaceResourceId')]", - "hidden-sentinelContentType": "Workbook" - }, "dependsOn": [ - "[resourceId('Microsoft.Resources/templateSpecs', variables('workbookTemplateSpecName1'))]" + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "AzureActivityWorkbook with template version 2.0.6", + "description": "Rare_Custom_Script_Extension_HuntingQueries Hunting Query with template version 3.0.0", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "[variables('workbookVersion1')]", + "contentVersion": "[variables('huntingQueryVersion14')]", "parameters": {}, "variables": {}, "resources": [ { - "type": "Microsoft.Insights/workbooks", - "name": "[variables('workbookContentId1')]", + "type": "Microsoft.OperationalInsights/savedSearches", + "apiVersion": "2022-10-01", + "name": "Azure_Activity_Hunting_Query_14", "location": "[parameters('workspace-location')]", - "kind": "shared", - "apiVersion": "2021-08-01", - "metadata": { - "description": "Gain extensive insight into your organization's Azure Activity by analyzing, and correlating all user operations and events.\nYou can learn about all user operations, trends, and anomalous changes over time.\nThis workbook gives you the ability to drill down into caller activities and summarize detected failure and warning events." - }, "properties": { - "displayName": "[parameters('workbook1-name')]", - "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"query\":\"\",\"crossComponentResources\":\"[variables('TemplateEmptyArray')]\",\"parameters\":[{\"id\":\"52bfbd84-1639-480c-bda5-bfc87fd81832\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"type\":4,\"isRequired\":true,\"value\":{\"durationMs\":604800000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}]}},{\"id\":\"eeb5dcf9-e898-46af-9c12-d91d97e13cd3\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Caller\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"AzureActivity\\r\\n| summarize by Caller\",\"value\":[\"value::all\"],\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"All\"},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"46375a76-7ae1-4d7e-9082-4191531198a9\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ResourceGroup\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"AzureActivity\\r\\n| summarize by ResourceGroup\",\"value\":[\"value::all\"],\"typeSettings\":{\"resourceTypeFilter\":{\"microsoft.resources/resourcegroups\":true},\"additionalResourceOptions\":[\"value::all\"],\"selectAllValue\":\"All\"},\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let data = AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup});\\r\\ndata\\r\\n| summarize Count = count() by ResourceGroup\\r\\n| join kind = fullouter (datatable(ResourceGroup:string)['Medium', 'high', 'low']) on ResourceGroup\\r\\n| project ResourceGroup = iff(ResourceGroup == '', ResourceGroup1, ResourceGroup), Count = iff(ResourceGroup == '', 0, Count)\\r\\n| join kind = inner (data\\r\\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain} by ResourceGroup)\\r\\n on ResourceGroup\\r\\n| project-away ResourceGroup1, TimeGenerated\\r\\n| extend ResourceGroups = ResourceGroup\\r\\n| union (\\r\\n data \\r\\n | summarize Count = count() \\r\\n | extend jkey = 1\\r\\n | join kind=inner (data\\r\\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain}\\r\\n | extend jkey = 1) on jkey\\r\\n | extend ResourceGroup = 'All', ResourceGroups = '*' \\r\\n)\\r\\n| order by Count desc\\r\\n| take 10\",\"size\":4,\"exportToExcelOptions\":\"visible\",\"title\":\"Top 10 active resource groups\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"ResourceGroup\",\"formatter\":1,\"formatOptions\":{\"showIcon\":true}},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\",\"showIcon\":true},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"secondaryContent\":{\"columnMatch\":\"Trend\",\"formatter\":9,\"formatOptions\":{\"palette\":\"blueOrange\",\"showIcon\":true}},\"showBorder\":false}},\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize deletions = countif(OperationNameValue hassuffix \\\"delete\\\"), creations = countif(OperationNameValue hassuffix \\\"write\\\"), updates = countif(OperationNameValue hassuffix \\\"write\\\"), Activities = count(OperationNameValue) by bin_at(TimeGenerated, 1h, now())\\r\\n\",\"size\":0,\"exportToExcelOptions\":\"visible\",\"title\":\"Activities over time\",\"color\":\"gray\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\",\"graphSettings\":{\"type\":0}},\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity\\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize deletions = countif(OperationNameValue hassuffix \\\"Delete\\\"), creations = countif(OperationNameValue hassuffix \\\"write\\\"), updates = countif(OperationNameValue hassuffix \\\"write\\\"), Activities = count() by Caller\\r\\n\",\"size\":1,\"exportToExcelOptions\":\"visible\",\"title\":\"Caller activities\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Caller\",\"formatter\":0,\"formatOptions\":{\"showIcon\":true}},{\"columnMatch\":\"deletions\",\"formatter\":4,\"formatOptions\":{\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"creations\",\"formatter\":4,\"formatOptions\":{\"palette\":\"purple\",\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"updates\",\"formatter\":4,\"formatOptions\":{\"palette\":\"gray\",\"showIcon\":true,\"aggregation\":\"Count\"}},{\"columnMatch\":\"Activities\",\"formatter\":4,\"formatOptions\":{\"palette\":\"greenDark\",\"linkTarget\":\"GenericDetails\",\"linkIsContextBlade\":true,\"showIcon\":true,\"aggregation\":\"Count\",\"workbookContext\":{\"componentIdSource\":\"workbook\",\"resourceIdsSource\":\"workbook\",\"templateIdSource\":\"static\",\"templateId\":\"https://go.microsoft.com/fwlink/?linkid=874159&resourceId=%2Fsubscriptions%2F44e4eff8-1fcb-4a22-a7d6-992ac7286382%2FresourceGroups%2FSOC&featureName=Workbooks&itemId=%2Fsubscriptions%2F44e4eff8-1fcb-4a22-a7d6-992ac7286382%2Fresourcegroups%2Fsoc%2Fproviders%2Fmicrosoft.insights%2Fworkbooks%2F4c195aec-747f-40bb-addb-934acb3ec646&name=CiscoASA&func=NavigateToPortalFeature&type=workbook\",\"typeSource\":\"workbook\",\"gallerySource\":\"workbook\"}}}],\"sortBy\":[{\"itemKey\":\"$gen_bar_updates_3\",\"sortOrder\":2}],\"labelSettings\":\"[variables('TemplateEmptyArray')]\"}},\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"AzureActivity \\r\\n| where \\\"{Caller:lable}\\\" == \\\"All\\\" or Caller in ({Caller})\\r\\n| where \\\"{ResourceGroup:lable}\\\" == \\\"All\\\" or ResourceGroup in ({ResourceGroup})\\r\\n| summarize Informational = countif(Level == \\\"Informational\\\"), Warning = countif(Level == \\\"Warning\\\"), Error = countif(Level == \\\"Error\\\") by bin_at(TimeGenerated, 1h, now())\\r\\n\",\"size\":0,\"exportToExcelOptions\":\"visible\",\"title\":\"Activities by log level over time\",\"color\":\"redBright\",\"timeContext\":{\"durationMs\":0},\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"scatterchart\",\"tileSettings\":{\"showBorder\":false},\"graphSettings\":{\"type\":2,\"topContent\":{\"columnMatch\":\"Error\",\"formatter\":12,\"formatOptions\":{\"showIcon\":true}},\"hivesContent\":{\"columnMatch\":\"TimeGenerated\",\"formatter\":1,\"formatOptions\":{\"showIcon\":true}},\"nodeIdField\":\"Error\",\"sourceIdField\":\"Error\",\"targetIdField\":\"Error\",\"nodeSize\":\"[variables('blanks')]\",\"staticNodeSize\":100,\"colorSettings\":\"[variables('blanks')]\",\"groupByField\":\"TimeGenerated\",\"hivesMargin\":5}},\"name\":\"query - 4\"}],\"fromTemplateId\":\"sentinel-AzureActivity\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", - "version": "1.0", - "sourceId": "[variables('workspaceResourceId')]", - "category": "sentinel" + "eTag": "*", + "displayName": "Rare Custom Script Extension", + "category": "Hunting Queries", + "query": "let starttime = todatetime('{{StartTimeISO}}');\nlet endtime = todatetime('{{EndTimeISO}}');\nlet Lookback = starttime - 14d;\nlet CustomScriptExecution = AzureActivity\n| where TimeGenerated >= Lookback\n| where OperationName =~ \"Create or Update Virtual Machine Extension\"\n| extend parsed_properties = parse_json(Properties)\n| extend Settings = tostring((parse_json(tostring(parsed_properties.responseBody)).properties).settings)\n| parse Settings with * 'fileUris\":[' FileURI \"]\" *\n| parse Settings with * 'commandToExecute\":' commandToExecute '}' *\n| extend message_ = tostring((parse_json(tostring(parsed_properties.statusMessage)).error).message);\nlet LookbackCustomScriptExecution = CustomScriptExecution\n| where TimeGenerated >= Lookback and TimeGenerated < starttime\n| where isnotempty(FileURI) and isnotempty(commandToExecute)\n| summarize max(TimeGenerated), OperationCount = count() by Caller, Resource, CallerIpAddress, FileURI, commandToExecute;\nlet CurrentCustomScriptExecution = CustomScriptExecution\n| where TimeGenerated between (starttime..endtime)\n| where isnotempty(FileURI) and isnotempty(commandToExecute)\n| project TimeGenerated, ActivityStatus, OperationId, CorrelationId, ResourceId, CallerIpAddress, Caller, OperationName, Resource, ResourceGroup, FileURI, commandToExecute, FailureMessage = message_, HTTPRequest, Settings;\nlet RareCustomScriptExecution = CurrentCustomScriptExecution\n| join kind= leftanti (LookbackCustomScriptExecution) on Caller, CallerIpAddress, FileURI, commandToExecute;\nlet IPCheck = RareCustomScriptExecution\n| summarize arg_max(TimeGenerated, OperationName), OperationIds = make_set(OperationId,100), CallerIpAddresses = make_set(CallerIpAddress,100) by ActivityStatus, CorrelationId, ResourceId, Caller, Resource, ResourceGroup, FileURI, commandToExecute, FailureMessage\n| extend IPArray = array_length(CallerIpAddresses);\n//Get IPs for later summarization so all associated CorrelationIds and Caller actions have an IP. Success and Fails do not always have IP\nlet multiIP = IPCheck | where IPArray > 1\n| mv-expand CallerIpAddresses | extend CallerIpAddress = tostring(CallerIpAddresses)\n| where isnotempty(CallerIpAddresses);\nlet singleIP = IPCheck | where IPArray <= 1\n| mv-expand CallerIpAddresses | extend CallerIpAddress = tostring(CallerIpAddresses);\nlet FullDetails = singleIP | union multiIP;\n//Get IP address associated with successes and fails with no IP listed\nlet IPList = FullDetails | where isnotempty(CallerIpAddress) | summarize by CorrelationId, Caller, CallerIpAddress;\nlet EmptyIP = FullDetails | where isempty(CallerIpAddress) | project-away CallerIpAddress;\nlet IpJoin = EmptyIP | join kind= leftouter (IPList) on CorrelationId, Caller | project-away CorrelationId1, Caller1;\nlet nonEmptyIP = FullDetails | where isnotempty(CallerIpAddress);\nnonEmptyIP | union IpJoin\n// summarize all activities with a given CorrelationId and Caller together so we can provide a singular result\n| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ActivityStatusSet = make_set(ActivityStatus,100), OperationIds = make_set(OperationIds,100), FailureMessages = make_set(FailureMessage,100) by CorrelationId, ResourceId, CallerIpAddress, Caller, Resource, ResourceGroup, FileURI, commandToExecute\n| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])\n| extend Account_0_Name = Name\n| extend Account_0_UPNSuffix = UPNSuffix\n| extend IP_0_Address = CallerIpAddress\n", + "version": 2, + "tags": [ + { + "name": "description", + "value": "The Custom Script Extension downloads and executes scripts on Azure virtual machines. This extension is useful for post deployment configuration, software installation, or any other configuration or management tasks.\n Scripts could be downloaded from external links, Azure storage, GitHub, or provided to the Azure portal at extension run time. This could also be used maliciously by an attacker.\n The query tries to identify rare custom script extensions that have been executed in your environment" + }, + { + "name": "tactics", + "value": "Execution" + }, + { + "name": "techniques", + "value": "T1059" + } + ] } }, { "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", "apiVersion": "2022-01-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('HuntingQuery-', last(split(variables('huntingQueryId14'),'/'))))]", "properties": { - "description": "@{workbookKey=AzureActivityWorkbook; logoFileName=azureactivity_logo.svg; description=Gain extensive insight into your organization's Azure Activity by analyzing, and correlating all user operations and events.\nYou can learn about all user operations, trends, and anomalous changes over time.\nThis workbook gives you the ability to drill down into caller activities and summarize detected failure and warning events.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0.0; title=Azure Activity; templateRelativePath=AzureActivity.json; subtitle=; provider=Microsoft}.description", - "parentId": "[variables('workbookId1')]", - "contentId": "[variables('_workbookContentId1')]", - "kind": "Workbook", - "version": "[variables('workbookVersion1')]", + "description": "Azure Activity Hunting Query 14", + "parentId": "[variables('huntingQueryId14')]", + "contentId": "[variables('_huntingQuerycontentId14')]", + "kind": "HuntingQuery", + "version": "[variables('huntingQueryVersion14')]", "source": { "kind": "Solution", "name": "Azure Activity", @@ -3214,34 +2899,39 @@ "name": "Microsoft Corporation", "email": "support@microsoft.com", "link": "https://support.microsoft.com/" - }, - "dependencies": { - "operator": "AND", - "criteria": [ - { - "contentId": "AzureActivity", - "kind": "DataType" - }, - { - "contentId": "AzureActivity", - "kind": "DataConnector" - } - ] } } } ] - } + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_huntingQuerycontentId14')]", + "contentKind": "HuntingQuery", + "displayName": "Rare Custom Script Extension", + "contentProductId": "[variables('_huntingQuerycontentProductId14')]", + "id": "[variables('_huntingQuerycontentProductId14')]", + "version": "[variables('huntingQueryVersion14')]" } }, { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "2.0.6", + "version": "3.0.0", "kind": "Solution", - "contentSchemaVersion": "2.0.0", + "contentSchemaVersion": "3.0.0", + "displayName": "Azure Activity", + "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", + "descriptionHtml": "

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

\n

The Azure Activity solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health logs using Diagnostic Settings into Microsoft Sentinel.

\n

Workbooks: 1, Analytic Rules: 12, Hunting Queries: 14

\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": { @@ -3263,9 +2953,69 @@ "operator": "AND", "criteria": [ { - "kind": "DataConnector", - "contentId": "[variables('_dataConnectorContentId1')]", - "version": "[variables('dataConnectorVersion1')]" + "kind": "Workbook", + "contentId": "[variables('_workbookContentId1')]", + "version": "[variables('workbookVersion1')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId1')]", + "version": "[variables('analyticRuleVersion1')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId2')]", + "version": "[variables('analyticRuleVersion2')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId3')]", + "version": "[variables('analyticRuleVersion3')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId4')]", + "version": "[variables('analyticRuleVersion4')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId5')]", + "version": "[variables('analyticRuleVersion5')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId6')]", + "version": "[variables('analyticRuleVersion6')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId7')]", + "version": "[variables('analyticRuleVersion7')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId8')]", + "version": "[variables('analyticRuleVersion8')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId9')]", + "version": "[variables('analyticRuleVersion9')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId10')]", + "version": "[variables('analyticRuleVersion10')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId11')]", + "version": "[variables('analyticRuleVersion11')]" + }, + { + "kind": "AnalyticsRule", + "contentId": "[variables('analyticRulecontentId12')]", + "version": "[variables('analyticRuleVersion12')]" }, { "kind": "HuntingQuery", @@ -3336,71 +3086,6 @@ "kind": "HuntingQuery", "contentId": "[variables('_huntingQuerycontentId14')]", "version": "[variables('huntingQueryVersion14')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId1')]", - "version": "[variables('analyticRuleVersion1')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId2')]", - "version": "[variables('analyticRuleVersion2')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId3')]", - "version": "[variables('analyticRuleVersion3')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId4')]", - "version": "[variables('analyticRuleVersion4')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId5')]", - "version": "[variables('analyticRuleVersion5')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId6')]", - "version": "[variables('analyticRuleVersion6')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId7')]", - "version": "[variables('analyticRuleVersion7')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId8')]", - "version": "[variables('analyticRuleVersion8')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId9')]", - "version": "[variables('analyticRuleVersion9')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId10')]", - "version": "[variables('analyticRuleVersion10')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId11')]", - "version": "[variables('analyticRuleVersion11')]" - }, - { - "kind": "AnalyticsRule", - "contentId": "[variables('analyticRulecontentId12')]", - "version": "[variables('analyticRuleVersion12')]" - }, - { - "kind": "Workbook", - "contentId": "[variables('_workbookContentId1')]", - "version": "[variables('workbookVersion1')]" } ] }, From 5dbdc75675e01f6c98c6dbb2b72e4cdf3c338945 Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Thu, 2 Nov 2023 17:12:29 +0530 Subject: [PATCH 07/11] Updated the Hunting query description --- Solutions/Azure Activity/Data/Solution_AzureActivity.json | 2 +- .../Hunting Queries/AnomalousAzureOperationModel.yaml | 2 ++ .../Hunting Queries/Anomalous_Listing_Of_Storage_Keys.yaml | 2 ++ .../Hunting Queries/Common_Deployed_Resources.yaml | 4 +++- .../Hunting Queries/Rare_Custom_Script_Extension.yaml | 4 +++- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Solutions/Azure Activity/Data/Solution_AzureActivity.json b/Solutions/Azure Activity/Data/Solution_AzureActivity.json index da8fec9a7e4..82f2b2af2e9 100644 --- a/Solutions/Azure Activity/Data/Solution_AzureActivity.json +++ b/Solutions/Azure Activity/Data/Solution_AzureActivity.json @@ -37,7 +37,7 @@ "Analytic Rules/TimeSeriesAnomaly_Mass_Cloud_Resource_Deletions.yaml" ], "Workbooks": [ - "Workbooks/AzureActivity.json" + "Workbooks/AzureActivity.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\Azure Activity", "Version": "3.0.0", diff --git a/Solutions/Azure Activity/Hunting Queries/AnomalousAzureOperationModel.yaml b/Solutions/Azure Activity/Hunting Queries/AnomalousAzureOperationModel.yaml index 797d69d1253..522f549e90c 100644 --- a/Solutions/Azure Activity/Hunting Queries/AnomalousAzureOperationModel.yaml +++ b/Solutions/Azure Activity/Hunting Queries/AnomalousAzureOperationModel.yaml @@ -1,6 +1,8 @@ id: 43cb0347-bdcc-4e83-af5a-cebbd03971d8 name: Anomalous Azure Operation Hunting Model description: | + 'This query identifies Azure Operation anomalies during threat hunts. It detects new callers, IPs, IP ranges, and anomalous operations. Initially set for Run Command operations, it can be configured for other operations and resource types.' +description_detailed: | 'This query can be used during threat hunts to identify a range of different Azure Operation anomalies. The query is heavily commented inline to explain operation. Anomalies covered are: New Caller, New Caller IP, New Caller IP Range, Anomalous operation based on Jaccard index. By default this query is configured to detect diff --git a/Solutions/Azure Activity/Hunting Queries/Anomalous_Listing_Of_Storage_Keys.yaml b/Solutions/Azure Activity/Hunting Queries/Anomalous_Listing_Of_Storage_Keys.yaml index 0292aaab633..e706ffc747c 100644 --- a/Solutions/Azure Activity/Hunting Queries/Anomalous_Listing_Of_Storage_Keys.yaml +++ b/Solutions/Azure Activity/Hunting Queries/Anomalous_Listing_Of_Storage_Keys.yaml @@ -1,6 +1,8 @@ id: 5d2399f9-ea5c-4e67-9435-1fba745f3a39 name: Azure storage key enumeration description: | + 'Azure's storage key listing can expose secrets, PII, and grant VM access. Monitoring for anomalous accounts or IPs is crucial. The query generates IP clusters, correlates activities, and flags unexpected ones. Single-operation users are excluded.' +description_detailed: | 'Listing of storage keys is an interesting operation in Azure which might expose additional secrets and PII to callers as well as granting access to VMs. While there are many benign operations of this type, it would be interesting to see if the account performing this activity or the source IP address from diff --git a/Solutions/Azure Activity/Hunting Queries/Common_Deployed_Resources.yaml b/Solutions/Azure Activity/Hunting Queries/Common_Deployed_Resources.yaml index 9f24f89635e..a80b53e3ae7 100644 --- a/Solutions/Azure Activity/Hunting Queries/Common_Deployed_Resources.yaml +++ b/Solutions/Azure Activity/Hunting Queries/Common_Deployed_Resources.yaml @@ -1,10 +1,12 @@ id: 0278e3b8-9899-45c5-8928-700cd80d2d80 name: Common deployed resources description: | + 'This query identifies common deployed resources in Azure, like resource names and groups. It can be used with other suspicious deployment signals to evaluate if a resource is commonly deployed or unique.' +description_detailed: | 'This query looks for common deployed resources (resource name and resource groups) and can be used in combination with other signals that show suspicious deployment to evaluate if the resource is one that is commonly being deployed/created or unique. - To understand the basket() function better see - https://docs.microsoft.com/azure/data-explorer/kusto/query/basketplugin' + To understand the basket() function better see - https://docs.microsoft.com/azure/data-explorer/kusto/query/basketplugin' requiredDataConnectors: - connectorId: AzureActivity dataTypes: diff --git a/Solutions/Azure Activity/Hunting Queries/Rare_Custom_Script_Extension.yaml b/Solutions/Azure Activity/Hunting Queries/Rare_Custom_Script_Extension.yaml index c6f6622cd5a..d28258581cb 100644 --- a/Solutions/Azure Activity/Hunting Queries/Rare_Custom_Script_Extension.yaml +++ b/Solutions/Azure Activity/Hunting Queries/Rare_Custom_Script_Extension.yaml @@ -1,7 +1,9 @@ id: 81fd68a2-9ad6-4a1c-7bd7-18efe5c99081 name: Rare Custom Script Extension description: | - 'The Custom Script Extension downloads and executes scripts on Azure virtual machines. This extension is useful for post deployment configuration, software installation, or any other configuration or management tasks. + 'The Custom Script Extension in Azure executes scripts on VMs, useful for post-deployment tasks. Scripts can be from various sources and could be used maliciously. The query identifies rare custom script extensions executed in your environment.' +description_detailed: | + 'The Custom Script Extension downloads and executes scripts on Azure virtual machines. This extension is useful for post deployment configuration, software installation, or any other configuration or management tasks. Scripts could be downloaded from external links, Azure storage, GitHub, or provided to the Azure portal at extension run time. This could also be used maliciously by an attacker. The query tries to identify rare custom script extensions that have been executed in your environment' requiredDataConnectors: From 438bcaa26f299b0af378a9ea9e431bce92bf3d76 Mon Sep 17 00:00:00 2001 From: Github Bot Date: Thu, 2 Nov 2023 12:03:48 +0000 Subject: [PATCH 08/11] [skip ci] Github Bot Added package to Pull Request! --- Solutions/Azure Activity/Package/3.0.0.zip | Bin 26376 -> 25384 bytes .../Package/createUiDefinition.json | 8 +- .../Azure Activity/Package/mainTemplate.json | 220 +++++++++--------- 3 files changed, 114 insertions(+), 114 deletions(-) diff --git a/Solutions/Azure Activity/Package/3.0.0.zip b/Solutions/Azure Activity/Package/3.0.0.zip index bebe5452f1ac88b28e68acd7093f98ee993c24fb..5379d9a73e901e53d93831eba90d7f0954280011 100644 GIT binary patch literal 25384 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 E01>TwuK)l5 literal 26376 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 z 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 Date: Mon, 6 Nov 2023 14:32:10 +0530 Subject: [PATCH 09/11] updated data connector extension --- .../Data Connectors/{AzureActivity.JSON => AzureActivity.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Solutions/Azure Activity/Data Connectors/{AzureActivity.JSON => AzureActivity.json} (100%) diff --git a/Solutions/Azure Activity/Data Connectors/AzureActivity.JSON b/Solutions/Azure Activity/Data Connectors/AzureActivity.json similarity index 100% rename from Solutions/Azure Activity/Data Connectors/AzureActivity.JSON rename to Solutions/Azure Activity/Data Connectors/AzureActivity.json From efc8a4648775eea6a160d3d28ad0ff660570a47c Mon Sep 17 00:00:00 2001 From: v-sudkharat Date: Wed, 8 Nov 2023 13:06:22 +0530 Subject: [PATCH 10/11] updated hunting description --- .../Hunting Queries/PortOpenedForAzureResource.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Azure Activity/Hunting Queries/PortOpenedForAzureResource.yaml b/Solutions/Azure Activity/Hunting Queries/PortOpenedForAzureResource.yaml index e2b0a0fd607..26a1fc68c2e 100644 --- a/Solutions/Azure Activity/Hunting Queries/PortOpenedForAzureResource.yaml +++ b/Solutions/Azure Activity/Hunting Queries/PortOpenedForAzureResource.yaml @@ -1,7 +1,7 @@ id: 9e146876-e303-49af-b847-b029d1a66852 name: Port opened for an Azure Resource description: | - 'Identifies what ports may have been opened for a given Azure Resource over the last 7 days' + 'Identifies what ports may have been opened for a given Azure Resource over the last 7 days.' requiredDataConnectors: - connectorId: AzureActivity dataTypes: From 63360470ab2efd3e7cf936561bb0f0f01dc87463 Mon Sep 17 00:00:00 2001 From: Github Bot Date: Wed, 8 Nov 2023 09:22:18 +0000 Subject: [PATCH 11/11] [skip ci] Github Bot Added package to Pull Request! --- Solutions/Azure Activity/Package/3.0.0.zip | Bin 25384 -> 26375 bytes .../Package/createUiDefinition.json | 28 +- .../Azure Activity/Package/mainTemplate.json | 277 ++++++++++++++---- 3 files changed, 251 insertions(+), 54 deletions(-) diff --git a/Solutions/Azure Activity/Package/3.0.0.zip b/Solutions/Azure Activity/Package/3.0.0.zip index 5379d9a73e901e53d93831eba90d7f0954280011..e0cd87c29a0da789ec5bf816c513e20775d0fa49 100644 GIT binary patch literal 26375 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 literal 25384 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 E01>TwuK)l5 diff --git a/Solutions/Azure Activity/Package/createUiDefinition.json b/Solutions/Azure Activity/Package/createUiDefinition.json index f66ef2636a3..2f093f2d208 100644 --- a/Solutions/Azure Activity/Package/createUiDefinition.json +++ b/Solutions/Azure Activity/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "description": "\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Workbooks:** 1, **Analytic Rules:** 12, **Hunting Queries:** 14\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [Azure Activity](https://docs.microsoft.com/azure/azure-monitor/essentials/activity-log) solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health [logs](https://docs.microsoft.com/azure/azure-monitor/reference/tables/azureactivity) using Diagnostic Settings into Microsoft Sentinel.\n\n**Data Connectors:** 1, **Workbooks:** 1, **Analytic Rules:** 12, **Hunting Queries:** 14\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -51,6 +51,30 @@ } ], "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 Azure Activity. You can get Azure Activity custom log 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-link2", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more about connecting data sources", + "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" + } + } + } + ] + }, { "name": "workbooks", "label": "Workbooks", @@ -488,7 +512,7 @@ "name": "huntingquery13-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days This hunting query depends on AzureActivity data connector (AzureActivity Parser or Table)" + "text": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days. This hunting query depends on AzureActivity data connector (AzureActivity Parser or Table)" } } ] diff --git a/Solutions/Azure Activity/Package/mainTemplate.json b/Solutions/Azure Activity/Package/mainTemplate.json index c59f3b4ea8d..1d2f2091853 100644 --- a/Solutions/Azure Activity/Package/mainTemplate.json +++ b/Solutions/Azure Activity/Package/mainTemplate.json @@ -44,6 +44,15 @@ "_email": "[variables('email')]", "_solutionName": "Azure Activity", "_solutionVersion": "3.0.0", + "uiConfigId1": "AzureActivity", + "_uiConfigId1": "[variables('uiConfigId1')]", + "dataConnectorContentId1": "AzureActivity", + "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", + "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "_dataConnectorId1": "[variables('dataConnectorId1')]", + "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", + "dataConnectorVersion1": "2.0.0", + "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", "workbookVersion1": "2.0.0", "workbookContentId1": "AzureActivityWorkbook", "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", @@ -210,6 +219,165 @@ "_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('dataConnectorTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "Azure Activity data connector with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "StaticUI", + "properties": { + "connectorUiConfig": { + "id": "[variables('_uiConfigId1')]", + "title": "Azure Activity", + "publisher": "Microsoft", + "descriptionMarkdown": "Azure Activity Log is a subscription log that provides insight into subscription-level events that occur in Azure, including events from Azure Resource Manager operational data, service health events, write operations taken on the resources in your subscription, and the status of activities performed in Azure. For more information, see the [Microsoft Sentinel documentation ](https://go.microsoft.com/fwlink/p/?linkid=2219695&wt.mc_id=sentinel_dataconnectordocs_content_cnl_csasci).", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "AzureActivity", + "baseQuery": "AzureActivity" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "AzureActivity\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" + ] + } + ], + "dataTypes": [ + { + "name": "AzureActivity", + "lastDataReceivedQuery": "AzureActivity\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ] + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "Azure Activity", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_dataConnectorContentId1')]", + "contentKind": "DataConnector", + "displayName": "Azure Activity", + "contentProductId": "[variables('_dataConnectorcontentProductId1')]", + "id": "[variables('_dataConnectorcontentProductId1')]", + "version": "[variables('dataConnectorVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "dependsOn": [ + "[variables('_dataConnectorId1')]" + ], + "location": "[parameters('workspace-location')]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "Azure Activity", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Microsoft", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Microsoft", + "name": "Microsoft Corporation", + "email": "support@microsoft.com", + "link": "https://support.microsoft.com/" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "StaticUI", + "properties": { + "connectorUiConfig": { + "title": "Azure Activity", + "publisher": "Microsoft", + "descriptionMarkdown": "Azure Activity Log is a subscription log that provides insight into subscription-level events that occur in Azure, including events from Azure Resource Manager operational data, service health events, write operations taken on the resources in your subscription, and the status of activities performed in Azure. For more information, see the [Microsoft Sentinel documentation ](https://go.microsoft.com/fwlink/p/?linkid=2219695&wt.mc_id=sentinel_dataconnectordocs_content_cnl_csasci).", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "AzureActivity", + "baseQuery": "AzureActivity" + } + ], + "dataTypes": [ + { + "name": "AzureActivity", + "lastDataReceivedQuery": "AzureActivity\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "AzureActivity\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" + ] + } + ], + "id": "[variables('_uiConfigId1')]" + } + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", @@ -349,7 +517,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -359,16 +526,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -466,7 +634,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -476,16 +643,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -585,7 +753,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -595,16 +762,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -702,7 +870,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -716,16 +883,17 @@ "identifier": "AadUserId", "columnName": "AadUserId" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -823,7 +991,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -833,25 +1000,26 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "Host", "fieldMappings": [ { "identifier": "HostName", "columnName": "ComputerName" } - ] + ], + "entityType": "Host" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -957,7 +1125,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -967,16 +1134,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -1070,7 +1238,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1080,16 +1247,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -1183,7 +1351,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1193,25 +1360,26 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "Host", "fieldMappings": [ { "identifier": "HostName", "columnName": "ComputerName" } - ] + ], + "entityType": "Host" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -1309,7 +1477,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1319,16 +1486,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "UserIP" } - ] + ], + "entityType": "IP" } ] } @@ -1426,7 +1594,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1440,16 +1607,17 @@ "identifier": "AadUserId", "columnName": "AadUserId" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -1549,7 +1717,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1559,16 +1726,17 @@ "identifier": "UPNSuffix", "columnName": "UPNSuffix" } - ] + ], + "entityType": "Account" }, { - "entityType": "IP", "fieldMappings": [ { "identifier": "Address", "columnName": "CallerIpAddress" } - ] + ], + "entityType": "IP" } ] } @@ -1666,7 +1834,6 @@ ], "entityMappings": [ { - "entityType": "Account", "fieldMappings": [ { "identifier": "Name", @@ -1680,7 +1847,8 @@ "identifier": "AadUserId", "columnName": "AadUserId" } - ] + ], + "entityType": "Account" } ] } @@ -2777,7 +2945,7 @@ "tags": [ { "name": "description", - "value": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days" + "value": "Identifies what ports may have been opened for a given Azure Resource over the last 7 days." }, { "name": "tactics", @@ -2927,7 +3095,7 @@ "contentSchemaVersion": "3.0.0", "displayName": "Azure Activity", "publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation", - "descriptionHtml": "

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

\n

The Azure Activity solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health logs using Diagnostic Settings into Microsoft Sentinel.

\n

Workbooks: 1, Analytic Rules: 12, Hunting Queries: 14

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

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

\n

The Azure Activity solution for Microsoft Sentinel enables you to ingest Azure Activity Administrative, Security, Service Health, Alert, Recommendation, Policy, Autoscale and Resource Health logs using Diagnostic Settings into Microsoft Sentinel.

\n

Data Connectors: 1, Workbooks: 1, Analytic Rules: 12, Hunting Queries: 14

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -2952,6 +3120,11 @@ "dependencies": { "operator": "AND", "criteria": [ + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId1')]", + "version": "[variables('dataConnectorVersion1')]" + }, { "kind": "Workbook", "contentId": "[variables('_workbookContentId1')]",