From 250cddfd529f242f7f08a123876941e46c72b0fa Mon Sep 17 00:00:00 2001 From: nlepagnez Date: Wed, 13 Sep 2023 23:13:19 +0200 Subject: [PATCH 1/2] readme file for parsers and typo correction. Update Workbook version --- .../CriticalCmdletsUsageDetection.yaml | 4 +- ...rientedWithUserOrientedAdministration.yaml | 4 +- .../Package/3.0.1.zip | Bin 0 -> 67873 bytes .../Package/createUiDefinition.json | 12 +- .../Package/mainTemplate.json | 126 +++++++-------- .../Parsers/ExchangeConfiguration.yaml | 12 +- .../Parsers/ExchangeEnvironmentList.yaml | 9 +- .../Parsers/README.md | 146 ++++++++++++++++++ .../ReleaseNotes.md | 4 +- ...crosoftExchangeSecurityExchangeOnline.json | 2 +- .../Package/3.0.1.zip | Bin 0 -> 25434 bytes .../Package/createUiDefinition.json | 10 +- .../Package/mainTemplate.json | 54 +++---- .../Parsers/ExchangeConfiguration.yaml | 12 +- .../Parsers/ExchangeEnvironmentList.yaml | 9 +- .../Parsers/README.md | 146 ++++++++++++++++++ .../ReleaseNotes.md | 4 +- .../WorkbookMetadata/WorkbooksMetadata.json | 44 +++--- .../common/commonFunctions.ps1 | 2 +- 19 files changed, 447 insertions(+), 153 deletions(-) create mode 100644 Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.0.1.zip create mode 100644 Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md create mode 100644 Solutions/Microsoft Exchange Security - Exchange Online/Package/3.0.1.zip create mode 100644 Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml index 0da6d87b406..5224517bfea 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml @@ -1,7 +1,7 @@ id: 5170c3c4-b8c9-485c-910d-a21d965ee181 name: VIP Mailbox manipulation description: | - 'Alert if an high important Cmdlet is executed on a VIP Mailbox as those Cmdlets can be used for data exfiltration or mailbox access.' + 'Alert if a cmdlet that can be translated to data exfiltration or mailbox access is executed on a VIP Mailbox.' requiredDataConnectors: - connectorId: ESI-ExchangeAdminAuditLogEvents dataTypes: @@ -47,5 +47,5 @@ entityMappings: fieldMappings: - identifier: Name columnName: Caller -version: 1.0.0 +version: 1.0.1 kind: Scheduled \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml index 421fc9dd0e7..7f3c3b972df 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml @@ -1,7 +1,7 @@ id: 7bce901b-9bc8-4948-8dfc-8f68878092d5 name: Server Oriented Cmdlet And User Oriented Cmdlet used description: | - 'Detect if a server oriented Cmdlet and a user oriented cmdlet that are monitored are launched by a same user in a same server in a 10 minutes timeframe' + 'Detect if a server oriented cmdlet and a user oriented cmdlet that are monitored are launched by the same user in the same server within a 10 minutes timeframe' requiredDataConnectors: - connectorId: ESI-ExchangeAdminAuditLogEvents dataTypes: @@ -74,5 +74,5 @@ entityMappings: columnName: Caller - identifier: ObjectGuid columnName: TargetObject -version: 1.0.0 +version: 1.0.1 kind: Scheduled \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.0.1.zip b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.0.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..5ec6b7027bef629167595a113bd8331df5d10aad GIT binary patch literal 67873 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 literal 0 HcmV?d00001 diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json index 1c8da416924..b11cfbb2982 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json @@ -98,8 +98,8 @@ "text": "After installing the solution, configure and enable the data connector that’s most relevant to your Exchange environment by following guidance in Manage solution view." } }, -{ - "name": "dataconnectors-parser", + { +"name": "dataconnectors-parser", "type": "Microsoft.Common.Section", "label": "Parsers", "elements": [ @@ -159,7 +159,7 @@ "name": "workbook1-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector" + "text": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector." } } ] @@ -173,7 +173,7 @@ "name": "workbook2-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent" + "text": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent." } } ] @@ -187,7 +187,7 @@ "name": "workbook3-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent" + "text": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent." } } ] @@ -201,7 +201,7 @@ "name": "workbook4-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector" + "text": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector." } } ] diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json index 61af501dc02..fad4a49c3df 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json @@ -65,7 +65,7 @@ "email": "support@microsoft.com", "_email": "[variables('email')]", "_solutionName": "Microsoft Exchange Security - Exchange On-Premises", - "_solutionVersion": "3.0.0", + "_solutionVersion": "3.0.1", "solutionId": "microsoftsentinelcommunity.azure-sentinel-solution-exchangesecurityinsights", "_solutionId": "[variables('solutionId')]", "uiConfigId1": "ESI-ExchangeAdminAuditLogEvents", @@ -100,7 +100,7 @@ "parserId2": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName2'))]", "_parserId2": "[variables('parserId2')]", "parserTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId2'))))]", - "parserVersion2": "1.0.0", + "parserVersion2": "1.0.1", "parserContentId2": "ExchangeConfiguration-Parser", "_parserContentId2": "[variables('parserContentId2')]", "_parsercontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId2'),'-', variables('parserVersion2'))))]", @@ -109,42 +109,42 @@ "parserId3": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName3'))]", "_parserId3": "[variables('parserId3')]", "parserTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId3'))))]", - "parserVersion3": "1.0.0", + "parserVersion3": "1.0.1", "parserContentId3": "ExchangeEnvironmentList-Parser", "_parserContentId3": "[variables('parserContentId3')]", "_parsercontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId3'),'-', variables('parserVersion3'))))]", - "workbookVersion1": "1.0.0", + "workbookVersion1": "1.0.1", "workbookContentId1": "MicrosoftExchangeLeastPrivilegewithRBAC", "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'))]", "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", - "workbookVersion2": "1.0.0", + "workbookVersion2": "1.0.1", "workbookContentId2": "MicrosoftExchangeSearchAdminAuditLog", "workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]", "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]", "_workbookContentId2": "[variables('workbookContentId2')]", "_workbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId2'),'-', variables('workbookVersion2'))))]", - "workbookVersion3": "1.0.0", + "workbookVersion3": "1.0.1", "workbookContentId3": "MicrosoftExchangeSecurityMonitoring", "workbookId3": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId3'))]", "workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]", "_workbookContentId3": "[variables('workbookContentId3')]", "_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]", - "workbookVersion4": "1.0.0", + "workbookVersion4": "1.0.1", "workbookContentId4": "MicrosoftExchangeSecurityReview", "workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]", "workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]", "_workbookContentId4": "[variables('workbookContentId4')]", "_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]", - "analyticRuleVersion1": "1.0.0", + "analyticRuleVersion1": "1.0.1", "analyticRulecontentId1": "5170c3c4-b8c9-485c-910d-a21d965ee181", "_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": "1.0.0", + "analyticRuleVersion2": "1.0.1", "analyticRulecontentId2": "7bce901b-9bc8-4948-8dfc-8f68878092d5", "_analyticRulecontentId2": "[variables('analyticRulecontentId2')]", "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]", @@ -162,7 +162,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.0.0", + "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -1612,7 +1612,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.0.0", + "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion2')]", @@ -2046,7 +2046,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ExchangeAdminAuditLogs Data Parser with template version 3.0.0", + "description": "ExchangeAdminAuditLogs Data Parser with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserVersion1')]", @@ -2176,7 +2176,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ExchangeConfiguration Data Parser with template version 3.0.0", + "description": "ExchangeConfiguration Data Parser with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserVersion2')]", @@ -2193,7 +2193,7 @@ "displayName": "Parser for ExchangeConfiguration", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeConfiguration", - "query": "let _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SpecificSectionList = '';\n// let SpecificConfigurationDate = 'lastdate';\n// let SpecificConfigurationEnv = 'All';\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", "functionParameters": "SpecificSectionList:string = \"\", SpecificConfigurationDate:string = \"lastdate\", Target:string = \"On-Premises\", SpecificConfigurationEnv:string = \"All\"", "version": 2, "tags": [ @@ -2257,7 +2257,7 @@ "displayName": "Parser for ExchangeConfiguration", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeConfiguration", - "query": "let _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SpecificSectionList = '';\n// let SpecificConfigurationDate = 'lastdate';\n// let SpecificConfigurationEnv = 'All';\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", "functionParameters": "SpecificSectionList:string = \"\", SpecificConfigurationDate:string = \"lastdate\", Target:string = \"On-Premises\", SpecificConfigurationEnv:string = \"All\"", "version": 2, "tags": [ @@ -2306,7 +2306,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ExchangeEnvironmentList Data Parser with template version 3.0.0", + "description": "ExchangeEnvironmentList Data Parser with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserVersion3')]", @@ -2323,7 +2323,7 @@ "displayName": "Parser for ExchangeEnvironmentList", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeEnvironmentList", - "query": "let _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", "functionParameters": "Target:string = \"On-Premises\"", "version": 2, "tags": [ @@ -2387,7 +2387,7 @@ "displayName": "Parser for ExchangeEnvironmentList", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeEnvironmentList", - "query": "let _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", "functionParameters": "Target:string = \"On-Premises\"", "version": 2, "tags": [ @@ -2436,7 +2436,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Least Privilege with RBAC Workbook with template version 3.0.0", + "description": "Microsoft Exchange Least Privilege with RBAC Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion1')]", @@ -2450,7 +2450,7 @@ "kind": "shared", "apiVersion": "2021-08-01", "metadata": { - "description": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment." + "description": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector." }, "properties": { "displayName": "[parameters('workbook1-name')]", @@ -2465,7 +2465,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeLeastPrivilegewithRBAC; logoFileName=Azure_Sentinel.svg; description=This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Least Privilege with RBAC; templateRelativePath=Microsoft Exchange Least Privilege with RBAC.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeLeastPrivilegewithRBAC; logoFileName=Azure_Sentinel.svg; description=This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Least Privilege with RBAC; templateRelativePath=Microsoft Exchange Least Privilege with RBAC.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId1')]", "contentId": "[variables('_workbookContentId1')]", "kind": "Workbook", @@ -2498,7 +2498,7 @@ { "contentId": "ESI-ExchangeAdminAuditLogEvents", "kind": "DataConnector" - } + } ] } } @@ -2527,7 +2527,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Search Admin AuditLog Workbook with template version 3.0.0", + "description": "Microsoft Exchange Search AdminAuditLog Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion2')]", @@ -2541,7 +2541,7 @@ "kind": "shared", "apiVersion": "2021-08-01", "metadata": { - "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment." + "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent." }, "properties": { "displayName": "[parameters('workbook2-name')]", @@ -2556,7 +2556,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId2'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeSearchAdminAuditLog; logoFileName=Azure_Sentinel.svg; description=This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Search AdminAuditLog; templateRelativePath=Microsoft Exchange Search AdminAuditLog.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeSearchAdminAuditLog; logoFileName=Azure_Sentinel.svg; description=This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Search AdminAuditLog; templateRelativePath=Microsoft Exchange Search AdminAuditLog.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId2')]", "contentId": "[variables('_workbookContentId2')]", "kind": "Workbook", @@ -2589,7 +2589,7 @@ { "contentId": "ESI-ExchangeAdminAuditLogEvents", "kind": "DataConnector" - } + } ] } } @@ -2618,7 +2618,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Admin Activity Workbook with template version 3.0.0", + "description": "Microsoft Exchange Admin Activity Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion3')]", @@ -2632,7 +2632,7 @@ "kind": "shared", "apiVersion": "2021-08-01", "metadata": { - "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers." + "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent." }, "properties": { "displayName": "[parameters('workbook3-name')]", @@ -2647,7 +2647,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId3'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeSecurityMonitoring; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Admin Activity; templateRelativePath=Microsoft Exchange Admin Activity.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeSecurityMonitoring; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Admin Activity; templateRelativePath=Microsoft Exchange Admin Activity.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId3')]", "contentId": "[variables('_workbookContentId3')]", "kind": "Workbook", @@ -2680,7 +2680,7 @@ { "contentId": "ESI-ExchangeAdminAuditLogEvents", "kind": "DataConnector" - } + } ] } } @@ -2709,7 +2709,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Security Review Workbook with template version 3.0.0", + "description": "Microsoft Exchange Security Review Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion4')]", @@ -2723,7 +2723,7 @@ "kind": "shared", "apiVersion": "2021-08-01", "metadata": { - "description": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks." + "description": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector." }, "properties": { "displayName": "[parameters('workbook4-name')]", @@ -2738,7 +2738,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId4'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeSecurityReview; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Security Review; templateRelativePath=Microsoft Exchange Security Review.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeSecurityReview; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Security Review; templateRelativePath=Microsoft Exchange Security Review.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId4')]", "contentId": "[variables('_workbookContentId4')]", "kind": "Workbook", @@ -2771,7 +2771,7 @@ { "contentId": "ESI-ExchangeAdminAuditLogEvents", "kind": "DataConnector" - } + } ] } } @@ -2800,7 +2800,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.0.0", + "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleVersion1')]", @@ -2814,7 +2814,7 @@ "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "description": "Alert if an high important Cmdlet is executed on a VIP Mailbox as those Cmdlets can be used for data exfiltration or mailbox access.", + "description": "Alert if a cmdlet that can be translated to data exfiltration or mailbox access is executed on a VIP Mailbox.", "displayName": "VIP Mailbox manipulation", "enabled": false, "query": "ExchangeAdminAuditLogs\n| where ingestion_time() > ago(30m)\n| where IsSensitive == true\n| where UserOriented =~ 'Yes'\n| where IsVIP == true\n", @@ -2848,8 +2848,8 @@ { "fieldMappings": [ { - "columnName": "TargetObject", - "identifier": "MailboxPrimaryAddress" + "identifier": "MailboxPrimaryAddress", + "columnName": "TargetObject" } ], "entityType": "Mailbox" @@ -2857,8 +2857,8 @@ { "fieldMappings": [ { - "columnName": "Computer", - "identifier": "FullName" + "identifier": "FullName", + "columnName": "Computer" } ], "entityType": "Host" @@ -2866,16 +2866,16 @@ { "fieldMappings": [ { - "columnName": "TargetObject", - "identifier": "Sid" + "identifier": "Sid", + "columnName": "TargetObject" }, { - "columnName": "TargetObject", - "identifier": "ObjectGuid" + "identifier": "ObjectGuid", + "columnName": "TargetObject" }, { - "columnName": "TargetObject", - "identifier": "FullName" + "identifier": "FullName", + "columnName": "TargetObject" } ], "entityType": "Account" @@ -2883,8 +2883,8 @@ { "fieldMappings": [ { - "columnName": "Caller", - "identifier": "Name" + "identifier": "Name", + "columnName": "Caller" } ], "entityType": "Account" @@ -2942,7 +2942,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.0.0", + "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('analyticRuleVersion2')]", @@ -2956,7 +2956,7 @@ "kind": "Scheduled", "location": "[parameters('workspace-location')]", "properties": { - "description": "Detect if a server oriented Cmdlet and a user oriented cmdlet that are monitored are launched by a same user in a same server in a 10 minutes timeframe", + "description": "Detect if a server oriented cmdlet and a user oriented cmdlet that are monitored are launched by the same user in the same server within a 10 minutes timeframe", "displayName": "Server Oriented Cmdlet And User Oriented Cmdlet used", "enabled": false, "query": "let timeframe = 1d;\nlet spanoftime = 10m;\nlet threshold = 0;\nExchangeAdminAuditLogs \n | where TimeGenerated > ago(2 * timeframe)\n | where isempty(UserOriented)\n | project serverExecutedTime = TimeGenerated,\n ServerCmdlet = CmdletName,\n ServerCmdletParams = CmdletParameters,\n Computer,\n Caller,\n ServerCmdletTargetObject = TargetObject\n | join kind= inner (\n ExchangeAdminAuditLogs\n | where TimeGenerated > ago(timeframe)\n | where UserOriented =~ 'Yes'\n | lookup kind=leftouter _GetWatchlist('ExchangeVIP') on $left.TargetObject == $right.canonicalName\n | project userExecutedTime = TimeGenerated,\n UserCmdlet = CmdletName,\n UserCmdletParams = CmdletParameters,\n Computer,\n Caller,\n UserCmdletTargetObject = TargetObject,\n userPrincipalName,\n objectGUID,\n sAMAccountName,\n IsVIP)\n on Computer, Caller\n | where userExecutedTime - serverExecutedTime < spanoftime\n | extend TimeDelta = userExecutedTime - serverExecutedTime\n | extend TimeDeltaInverse = serverExecutedTime - userExecutedTime\n | where tolong(TimeDelta) >= threshold or tolong(TimeDeltaInverse) >= threshold\n", @@ -2990,12 +2990,12 @@ { "fieldMappings": [ { - "columnName": "userPrincipalName", - "identifier": "MailboxPrimaryAddress" + "identifier": "MailboxPrimaryAddress", + "columnName": "userPrincipalName" }, { - "columnName": "userPrincipalName", - "identifier": "Upn" + "identifier": "Upn", + "columnName": "userPrincipalName" } ], "entityType": "Mailbox" @@ -3003,8 +3003,8 @@ { "fieldMappings": [ { - "columnName": "Computer", - "identifier": "FullName" + "identifier": "FullName", + "columnName": "Computer" } ], "entityType": "Host" @@ -3012,8 +3012,8 @@ { "fieldMappings": [ { - "columnName": "ServerCmdletTargetObject", - "identifier": "HostName" + "identifier": "HostName", + "columnName": "ServerCmdletTargetObject" } ], "entityType": "Host" @@ -3021,12 +3021,12 @@ { "fieldMappings": [ { - "columnName": "Caller", - "identifier": "Name" + "identifier": "Name", + "columnName": "Caller" }, { - "columnName": "TargetObject", - "identifier": "ObjectGuid" + "identifier": "ObjectGuid", + "columnName": "TargetObject" } ], "entityType": "Account" @@ -3080,7 +3080,7 @@ "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.0.0", + "version": "3.0.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "Microsoft Exchange Security - Exchange On-Premises", diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeConfiguration.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeConfiguration.yaml index 37d0526c648..89f064731c3 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeConfiguration.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeConfiguration.yaml @@ -1,8 +1,8 @@ id: f2ae482d-999c-452e-b108-31880aa99620 Function: Title: Parser for ExchangeConfiguration - Version: '1.0.0' - LastUpdated: '2023-08-23' + Version: '1.0.1' + LastUpdated: '2023-09-13' Category: Microsoft Sentinel Parser FunctionName: ExchangeConfiguration FunctionAlias: ExchangeConfiguration @@ -24,6 +24,14 @@ FunctionParams: Description: The target environment to query. Valid values are "On-Premises" or "Online". Default is "On-Premises". DefaultValue: 'On-Premises' FunctionQuery: | + // Parameters simulation + // If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values. + // + // let SpecificSectionList = ''; + // let SpecificConfigurationDate = 'lastdate'; + // let SpecificConfigurationEnv = 'All'; + // let Target = 'On-Premises'; + // // Parameters definition let _SpecificSectionList = split(SpecificSectionList,','); let _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),"lastdate",tostring(SpecificConfigurationDate)); diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeEnvironmentList.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeEnvironmentList.yaml index 76bab8257d3..5af32170e7b 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeEnvironmentList.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeEnvironmentList.yaml @@ -1,8 +1,8 @@ id: fa748dc3-00ee-41cb-b54e-8acd56041b2a Function: Title: Parser for ExchangeEnvironmentList - Version: '1.0.0' - LastUpdated: '2023-08-23' + Version: '1.0.1' + LastUpdated: '2023-09-13' Category: Microsoft Sentinel Parser FunctionName: ExchangeEnvironmentList FunctionAlias: ExchangeEnvironmentList @@ -12,6 +12,11 @@ FunctionParams: Description: The target environment to query. Valid values are "On-Premises" or "Online". Default is "On-Premises". DefaultValue: 'On-Premises' FunctionQuery: | + // Parameters simulation + // If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values. + // + // let Target = 'On-Premises'; + // // Parameters definition let _target = iff(isnull(Target) or isempty(Target),"On-Premises",Target); let ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md new file mode 100644 index 00000000000..2bb91a6bef8 --- /dev/null +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md @@ -0,0 +1,146 @@ +# Microsoft Exchange Security - Parsers information + +Microsoft Exchange Security solutions use multiple parsers to be able to process correctly the raw data. Those parsers are used to create multiple workbooks, multiple analytic rules but parsers are also here to allow you to format correctly raw data to be used in your own queries. + +Parsers are created [using functions in Azure monitor log queries](https://docs.microsoft.com/azure/azure-monitor/log-query/functions) + +- [Microsoft Exchange Security - Parsers information](#microsoft-exchange-security---parsers-information) + - [ExchangeConfiguration Parser](#exchangeconfiguration-parser) + - [Parser Definition](#parser-definition) + - [Parser Description](#parser-description) + - [Parser Setup](#parser-setup) + - [Linked tables](#linked-tables) + - [Parameters simulation](#parameters-simulation) + - [Exchange Configuration Environment List Parser](#exchange-configuration-environment-list-parser) + - [Parser Definition](#parser-definition-1) + - [Parser Description](#parser-description-1) + - [Parser Setup](#parser-setup-1) + - [Linked tables](#linked-tables-1) + - [Parameters simulation](#parameters-simulation-1) + - [Exchange Admin Audit Logs Parser](#exchange-admin-audit-logs-parser) + - [Parser Definition](#parser-definition-2) + - [Parser Description](#parser-description-2) + - [Parser dependency](#parser-dependency) + - [Parser Setup](#parser-setup-2) + - [Linked tables](#linked-tables-2) + +## ExchangeConfiguration Parser + +### Parser Definition + +- Title: ESI - Exchange Configuration Parser +- Version: 1.6 +- Last Updated: 13/10/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.6 |
  • Change consumption of Identity_Name_S by IdentityString_s. Requires CollectExchSecIns Script version 7.5.1 minimum
| +|v1.5 |
  • Change the usage of TimeGenerated instead of EntryDate for filtering BaseRequest.
  • Change alllife duration to 1080 days instead of 90 days.
| +|v1.4 |
  • Capacity to find all configuration without date limitation with the keyword "alllife" in SpecificConfigurationDate
| +|v1.3 |
  • Adding fuzzy mode to be able to have only On-Premises or Online tables
  • Simplify the request
| + +### Parser Description + +This parser takes raw ESI Exchange Configuration Collector to pivot raw information and retrieve a specific date configuration. This is the same parser for Exchange On-Premises version and Exchange online version of the solution. + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeConfiguration". + +>#### **Parameters:** +> +>4 parameters to add during creation. +> +> 1. SpecificSectionList, type string, default value "" +> 2. SpecificConfigurationDate, type string, default value "lastdate" +> 3. Target, type string, default value "On-Premises" +> 4. SpecificConfigurationEnv, type string, default value "All" + + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes the raw log from the ESI Exchange Collector are on the ESIExchangeConfig_CL and/or ESIExchangeOnlineConfig_CL tables and are uploaded using the builtin REST API uploader of the Collector. + +### Parameters simulation + +If you need to test the parser execution without saving it as a function, add the bellow variable to simulate parameters values at the beginning. + + +``` +let SpecificSectionList = ''; +let SpecificConfigurationDate = 'lastdate'; +let SpecificConfigurationEnv = 'All'; +let Target = 'On-Premises';` +``` + +## Exchange Configuration Environment List Parser + +### Parser Definition + +- Title: Exchange Configuration Environment List Generator +- Version: 1.2 +- Last Updated: 19/09/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.2 |
  • Adding fuzzy mode to be able to have only On-Premises or Online tables
| + +### Parser Description + +This parser takes raw ESI Exchange Configuration Collector to list Exchange Environments that are loaded in the tables. This is the same parser for Exchange On-Premises version and Exchange online version of the solution. + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeEnvironmentList". + +>#### **Parameters:** +> +>1 parameter to add during creation : Target, type string, default value "On-Premises" + + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes the raw log from the ESI Exchange Collector are on the ESIExchangeConfig_CL and/or ESIExchangeOnlineConfig_CL tables and are uploaded using the builtin REST API uploader of the Collector. + +### Parameters simulation + +If you need to test the parser execution without saving it as a function, add the bellow variable to simulate parameters values at the beginning. + + +``` +let Target = 'On-Premises'; +``` + +## Exchange Admin Audit Logs Parser + +### Parser Definition + +- Title: Exchange Admin Audit Logs Parser +- Version: 1.0 +- Last Updated: 15/11/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.0 |
  • Function initilisation for Sentinel Solution
| + +### Parser Description + +This parser takes raw Exchange Admin Audit Logs and add elements like ESI Environment, VIP information, sensitive information, etc... + +### Parser dependency + +This parser is linked to "ExchangeVIP" whatchlist + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeAdminAuditLogs". + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes that MS Exchange Management Logs from Exchange Servers Event Logs are collected in Log Analytics. diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/ReleaseNotes.md b/Solutions/Microsoft Exchange Security - Exchange On-Premises/ReleaseNotes.md index 2c5f059d277..cf332558160 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/ReleaseNotes.md +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/ReleaseNotes.md @@ -1,4 +1,4 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|---------------------------------------------| -| 3.0.0 | 08-23-2023 | **ExchangeEnvironmentList** parser name | -| | | corrected in Workbooks. | +| 3.0.1 | 09-13-2023 | readme file for parsers and typo correction | +| 3.0.0 | 08-23-2023 | **ExchangeEnvironmentList** parser name corrected in Workbooks. | diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Data/Solution_MicrosoftExchangeSecurityExchangeOnline.json b/Solutions/Microsoft Exchange Security - Exchange Online/Data/Solution_MicrosoftExchangeSecurityExchangeOnline.json index a7a78abf932..591ea4db401 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Data/Solution_MicrosoftExchangeSecurityExchangeOnline.json +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Data/Solution_MicrosoftExchangeSecurityExchangeOnline.json @@ -16,7 +16,7 @@ ], "Analytic Rules": [], "BasePath": "C:\\Git Repositories\\Azure-Sentinel\\Solutions\\Microsoft Exchange Security - Exchange Online", - "Version": "3.0.0", + "Version": "3.0.1", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1Pconnector": false diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Package/3.0.1.zip b/Solutions/Microsoft Exchange Security - Exchange Online/Package/3.0.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..46b124cbdb4654990a6ffe7b565ad9dc8e390efc GIT binary patch literal 25434 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 v2+D6WHqpYhuB?R7oW7Y(#`FwY4w2SZyP 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 literal 0 HcmV?d00001 diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Package/createUiDefinition.json b/Solutions/Microsoft Exchange Security - Exchange Online/Package/createUiDefinition.json index 0cbf0f7948e..7af85208a8b 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Package/createUiDefinition.json +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Package/createUiDefinition.json @@ -55,8 +55,8 @@ "name": "dataconnectors", "label": "Data Connectors", "bladeTitle": "Data Connectors", -"elements": [ - { + "elements": [ +{ "name": "dataconnectors1", "type": "Microsoft.Common.Section", "label": "Data Connectors", @@ -65,13 +65,13 @@ "name": "dataconnectors1-text", "type": "Microsoft.Common.TextBlock", "options": { - "text": "This solution installs the data connector for collecting exchange online 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." + "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange Online. You can get Microsoft Exchange Security - Exchange Online 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-parser", + { +"name": "dataconnectors-parser", "type": "Microsoft.Common.Section", "label": "Parsers", "elements": [ diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Package/mainTemplate.json b/Solutions/Microsoft Exchange Security - Exchange Online/Package/mainTemplate.json index 9865240561e..19f2967fe88 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Package/mainTemplate.json +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Package/mainTemplate.json @@ -49,7 +49,7 @@ "email": "support@microsoft.com", "_email": "[variables('email')]", "_solutionName": "Microsoft Exchange Security - Exchange Online", - "_solutionVersion": "3.0.0", + "_solutionVersion": "3.0.1", "solutionId": "microsoftsentinelcommunity.azure-sentinel-solution-esionline", "_solutionId": "[variables('solutionId')]", "uiConfigId1": "ESI-ExchangeOnlineCollector", @@ -66,7 +66,7 @@ "parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]", "_parserId1": "[variables('parserId1')]", "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId1'))))]", - "parserVersion1": "1.0.0", + "parserVersion1": "1.0.1", "parserContentId1": "ExchangeConfiguration-Parser", "_parserContentId1": "[variables('parserContentId1')]", "_parsercontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId1'),'-', variables('parserVersion1'))))]", @@ -75,18 +75,18 @@ "parserId2": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName2'))]", "_parserId2": "[variables('parserId2')]", "parserTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId2'))))]", - "parserVersion2": "1.0.0", + "parserVersion2": "1.0.1", "parserContentId2": "ExchangeEnvironmentList-Parser", "_parserContentId2": "[variables('parserContentId2')]", "_parsercontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId2'),'-', variables('parserVersion2'))))]", - "workbookVersion1": "1.0.0", + "workbookVersion1": "1.0.1", "workbookContentId1": "MicrosoftExchangeLeastPrivilegewithRBAC-Online", "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'))]", "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", - "workbookVersion2": "1.0.0", + "workbookVersion2": "1.0.1", "workbookContentId2": "MicrosoftExchangeSecurityReview-Online", "workbookId2": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId2'))]", "workbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId2'))))]", @@ -104,7 +104,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Security - Exchange Online data connector with template version 3.0.0", + "description": "Microsoft Exchange Security - Exchange Online data connector with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -632,7 +632,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ExchangeConfiguration Data Parser with template version 3.0.0", + "description": "ExchangeConfiguration Data Parser with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserVersion1')]", @@ -649,7 +649,7 @@ "displayName": "Parser for ExchangeConfiguration", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeConfiguration", - "query": "let _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SpecificSectionList = '';\n// let SpecificConfigurationDate = 'lastdate';\n// let SpecificConfigurationEnv = 'All';\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", "functionParameters": "SpecificSectionList:string = \"\", SpecificConfigurationDate:string = \"lastdate\", Target:string = \"On-Premises\", SpecificConfigurationEnv:string = \"All\"", "version": 2, "tags": [ @@ -713,8 +713,8 @@ "displayName": "Parser for ExchangeConfiguration", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeConfiguration", - "query": "let _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", - "functionParameters": "SpecificSectionList:string = \"\", SpecificConfigurationDate:string = \"lastdate\", Target:string = \"On-Premises\", SpecificConfigurationEnv:string = \"All\"", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SpecificSectionList = '';\n// let SpecificConfigurationDate = 'lastdate';\n// let SpecificConfigurationEnv = 'All';\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _SpecificSectionList = split(SpecificSectionList,',');\nlet _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),\"lastdate\",tostring(SpecificConfigurationDate));\nlet _configurationEnv = split(iff(isnull(SpecificConfigurationEnv) or isempty(SpecificConfigurationEnv) or tolower(SpecificConfigurationEnv) == \"all\",\"All\",tostring(SpecificConfigurationEnv)),',');\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\n// Building Base Request\nlet _targetDate = iff(_configurationDate == \"lastdate\", ago(7d), iif(_configurationDate == \"alllife\",ago(1080d),todatetime(_configurationDate)));\nlet baseRequest = materialize (union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* \n | where TimeGenerated > _targetDate\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target\n | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \n | where ScopedEnvironment in (_configurationEnv)\n | extend EntryDate = todatetime(EntryDate_s)\n | project-away EntryDate_s);\n// Find Config Id (can be multiple id in all)\nlet findConfigDate = baseRequest\n | extend Env =strcat(Source, \"_\",ESIEnvironment_s)\n | summarize count() by GenerationInstanceID_g,Env,EntryDate\n | extend distance = iff(_configurationDate == \"lastdate\" or _configurationDate == \"alllife\", now() - EntryDate, (EntryDate - todatetime(_configurationDate)))\n | top-nested of Env by Ignore0=max(1), \n top-nested 1 of distance by Ignore1 = min(distance) asc nulls last, \n top-nested of GenerationInstanceID_g by Ignore2=max(2) \n | project GenerationInstanceID_g;\n// Parse Result\nlet ParseExchangeConfig = () { baseRequest \n | join kind=leftsemi (findConfigDate) on $left.GenerationInstanceID_g == $right.GenerationInstanceID_g\n | where isempty(_SpecificSectionList[0]) or Section_s in (_SpecificSectionList)\n | extend TimeGenerated = EntryDate\n | extend Identity = IdentityString_s\n | extend CmdletResultValue = parse_json(rawData_s)\n | project-rename ConfigurationInstanceID = GenerationInstanceID_g, ESIEnvironment = ESIEnvironment_s, Section = Section_s, PSCmdlet = PSCmdL_s, CmdletResultType = ExecutionResult_s, WhenChanged = WhenChanged_t, WhenCreated = WhenCreated_t, Name = Name_s\n | project-away TenantId,SourceSystem,Type,EntryDate\n};\nParseExchangeConfig\n", + "functionParameters": "SpecificSectionList:string,SpecificConfigurationDate:string,SpecificConfigurationEnv:string,Target:string", "version": 2, "tags": [ { @@ -762,7 +762,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ExchangeEnvironmentList Data Parser with template version 3.0.0", + "description": "ExchangeEnvironmentList Data Parser with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('parserVersion2')]", @@ -779,7 +779,7 @@ "displayName": "Parser for ExchangeEnvironmentList", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeEnvironmentList", - "query": "let _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", "functionParameters": "Target:string = \"On-Premises\"", "version": 2, "tags": [ @@ -843,8 +843,8 @@ "displayName": "Parser for ExchangeEnvironmentList", "category": "Microsoft Sentinel Parser", "functionAlias": "ExchangeEnvironmentList", - "query": "let _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", - "functionParameters": "Target:string = \"On-Premises\"", + "query": "// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let Target = 'On-Premises';\n//\n// Parameters definition\nlet _target = iff(isnull(Target) or isempty(Target),\"On-Premises\",Target);\nlet ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange*\n | extend Source = iff (TableName contains \"Online\", \"Online\", \"On-Premises\")\n | where _target == 'All' or Source == _target;\n// Base Request\nScalarbaseRequest | summarize by ESIEnvironment_s | project-rename ESIEnvironment = ESIEnvironment_s\n", + "functionParameters": "Target:string", "version": 2, "tags": [ { @@ -892,7 +892,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Least Privilege with RBAC - Online Workbook with template version 3.0.0", + "description": "Microsoft Exchange Least Privilege with RBAC - Online Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion1')]", @@ -921,7 +921,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeLeastPrivilegewithRBAC-Online; logoFileName=Azure_Sentinel.svg; description=This Workbook, dedicated to Exchange Online environments is built to have a simple view of non-standard RBAC delegations on an Exchange Online tenant. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Least Privilege with RBAC - Online; templateRelativePath=Microsoft Exchange Least Privilege with RBAC - Online.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeLeastPrivilegewithRBAC-Online; logoFileName=Azure_Sentinel.svg; description=This Workbook, dedicated to Exchange Online environments is built to have a simple view of non-standard RBAC delegations on an Exchange Online tenant. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Least Privilege with RBAC - Online; templateRelativePath=Microsoft Exchange Least Privilege with RBAC - Online.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId1')]", "contentId": "[variables('_workbookContentId1')]", "kind": "Workbook", @@ -947,14 +947,6 @@ "contentId": "ESIExchangeOnlineConfig_CL", "kind": "DataType" }, - { - "contentId": "ESI-ExchangeOnPremisesCollector", - "kind": "DataConnector" - }, - { - "contentId": "ESI-ExchangeAdminAuditLogEvents", - "kind": "DataConnector" - }, { "contentId": "ESI-ExchangeOnlineCollector", "kind": "DataConnector" @@ -987,7 +979,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "Microsoft Exchange Security Review - Online Workbook with template version 3.0.0", + "description": "Microsoft Exchange Security Review - Online Workbook with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('workbookVersion2')]", @@ -1016,7 +1008,7 @@ "apiVersion": "2022-01-01-preview", "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId2'),'/'))))]", "properties": { - "description": "@{workbookKey=MicrosoftExchangeSecurityReview-Online; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to Exchange Online tenants. It displays and highlights current Security configuration on various Exchange components specific to Online including delegations, the transport configuration and the linked security risks, and risky protocols.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Microsoft Exchange Security Review - Online; templateRelativePath=Microsoft Exchange Security Review - Online.json; subtitle=; provider=Microsoft}.description", + "description": "@{workbookKey=MicrosoftExchangeSecurityReview-Online; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to Exchange Online tenants. It displays and highlights current Security configuration on various Exchange components specific to Online including delegations, the transport configuration and the linked security risks, and risky protocols.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Security Review - Online; templateRelativePath=Microsoft Exchange Security Review - Online.json; subtitle=; provider=Microsoft}.description", "parentId": "[variables('workbookId2')]", "contentId": "[variables('_workbookContentId2')]", "kind": "Workbook", @@ -1042,14 +1034,6 @@ "contentId": "ESIExchangeOnlineConfig_CL", "kind": "DataType" }, - { - "contentId": "ESI-ExchangeOnPremisesCollector", - "kind": "DataConnector" - }, - { - "contentId": "ESI-ExchangeAdminAuditLogEvents", - "kind": "DataConnector" - }, { "contentId": "ESI-ExchangeOnlineCollector", "kind": "DataConnector" @@ -1078,7 +1062,7 @@ "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.0.0", + "version": "3.0.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "Microsoft Exchange Security - Exchange Online", diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeConfiguration.yaml b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeConfiguration.yaml index 37d0526c648..89f064731c3 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeConfiguration.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeConfiguration.yaml @@ -1,8 +1,8 @@ id: f2ae482d-999c-452e-b108-31880aa99620 Function: Title: Parser for ExchangeConfiguration - Version: '1.0.0' - LastUpdated: '2023-08-23' + Version: '1.0.1' + LastUpdated: '2023-09-13' Category: Microsoft Sentinel Parser FunctionName: ExchangeConfiguration FunctionAlias: ExchangeConfiguration @@ -24,6 +24,14 @@ FunctionParams: Description: The target environment to query. Valid values are "On-Premises" or "Online". Default is "On-Premises". DefaultValue: 'On-Premises' FunctionQuery: | + // Parameters simulation + // If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values. + // + // let SpecificSectionList = ''; + // let SpecificConfigurationDate = 'lastdate'; + // let SpecificConfigurationEnv = 'All'; + // let Target = 'On-Premises'; + // // Parameters definition let _SpecificSectionList = split(SpecificSectionList,','); let _configurationDate = iff(isnull(SpecificConfigurationDate) or isempty(SpecificConfigurationDate),"lastdate",tostring(SpecificConfigurationDate)); diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeEnvironmentList.yaml b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeEnvironmentList.yaml index 76bab8257d3..5af32170e7b 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeEnvironmentList.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/ExchangeEnvironmentList.yaml @@ -1,8 +1,8 @@ id: fa748dc3-00ee-41cb-b54e-8acd56041b2a Function: Title: Parser for ExchangeEnvironmentList - Version: '1.0.0' - LastUpdated: '2023-08-23' + Version: '1.0.1' + LastUpdated: '2023-09-13' Category: Microsoft Sentinel Parser FunctionName: ExchangeEnvironmentList FunctionAlias: ExchangeEnvironmentList @@ -12,6 +12,11 @@ FunctionParams: Description: The target environment to query. Valid values are "On-Premises" or "Online". Default is "On-Premises". DefaultValue: 'On-Premises' FunctionQuery: | + // Parameters simulation + // If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values. + // + // let Target = 'On-Premises'; + // // Parameters definition let _target = iff(isnull(Target) or isempty(Target),"On-Premises",Target); let ScalarbaseRequest = union isfuzzy=true withsource=TableName ESIAPIExchange*,ESIExchange* diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md new file mode 100644 index 00000000000..2bb91a6bef8 --- /dev/null +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md @@ -0,0 +1,146 @@ +# Microsoft Exchange Security - Parsers information + +Microsoft Exchange Security solutions use multiple parsers to be able to process correctly the raw data. Those parsers are used to create multiple workbooks, multiple analytic rules but parsers are also here to allow you to format correctly raw data to be used in your own queries. + +Parsers are created [using functions in Azure monitor log queries](https://docs.microsoft.com/azure/azure-monitor/log-query/functions) + +- [Microsoft Exchange Security - Parsers information](#microsoft-exchange-security---parsers-information) + - [ExchangeConfiguration Parser](#exchangeconfiguration-parser) + - [Parser Definition](#parser-definition) + - [Parser Description](#parser-description) + - [Parser Setup](#parser-setup) + - [Linked tables](#linked-tables) + - [Parameters simulation](#parameters-simulation) + - [Exchange Configuration Environment List Parser](#exchange-configuration-environment-list-parser) + - [Parser Definition](#parser-definition-1) + - [Parser Description](#parser-description-1) + - [Parser Setup](#parser-setup-1) + - [Linked tables](#linked-tables-1) + - [Parameters simulation](#parameters-simulation-1) + - [Exchange Admin Audit Logs Parser](#exchange-admin-audit-logs-parser) + - [Parser Definition](#parser-definition-2) + - [Parser Description](#parser-description-2) + - [Parser dependency](#parser-dependency) + - [Parser Setup](#parser-setup-2) + - [Linked tables](#linked-tables-2) + +## ExchangeConfiguration Parser + +### Parser Definition + +- Title: ESI - Exchange Configuration Parser +- Version: 1.6 +- Last Updated: 13/10/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.6 |
  • Change consumption of Identity_Name_S by IdentityString_s. Requires CollectExchSecIns Script version 7.5.1 minimum
| +|v1.5 |
  • Change the usage of TimeGenerated instead of EntryDate for filtering BaseRequest.
  • Change alllife duration to 1080 days instead of 90 days.
| +|v1.4 |
  • Capacity to find all configuration without date limitation with the keyword "alllife" in SpecificConfigurationDate
| +|v1.3 |
  • Adding fuzzy mode to be able to have only On-Premises or Online tables
  • Simplify the request
| + +### Parser Description + +This parser takes raw ESI Exchange Configuration Collector to pivot raw information and retrieve a specific date configuration. This is the same parser for Exchange On-Premises version and Exchange online version of the solution. + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeConfiguration". + +>#### **Parameters:** +> +>4 parameters to add during creation. +> +> 1. SpecificSectionList, type string, default value "" +> 2. SpecificConfigurationDate, type string, default value "lastdate" +> 3. Target, type string, default value "On-Premises" +> 4. SpecificConfigurationEnv, type string, default value "All" + + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes the raw log from the ESI Exchange Collector are on the ESIExchangeConfig_CL and/or ESIExchangeOnlineConfig_CL tables and are uploaded using the builtin REST API uploader of the Collector. + +### Parameters simulation + +If you need to test the parser execution without saving it as a function, add the bellow variable to simulate parameters values at the beginning. + + +``` +let SpecificSectionList = ''; +let SpecificConfigurationDate = 'lastdate'; +let SpecificConfigurationEnv = 'All'; +let Target = 'On-Premises';` +``` + +## Exchange Configuration Environment List Parser + +### Parser Definition + +- Title: Exchange Configuration Environment List Generator +- Version: 1.2 +- Last Updated: 19/09/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.2 |
  • Adding fuzzy mode to be able to have only On-Premises or Online tables
| + +### Parser Description + +This parser takes raw ESI Exchange Configuration Collector to list Exchange Environments that are loaded in the tables. This is the same parser for Exchange On-Premises version and Exchange online version of the solution. + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeEnvironmentList". + +>#### **Parameters:** +> +>1 parameter to add during creation : Target, type string, default value "On-Premises" + + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes the raw log from the ESI Exchange Collector are on the ESIExchangeConfig_CL and/or ESIExchangeOnlineConfig_CL tables and are uploaded using the builtin REST API uploader of the Collector. + +### Parameters simulation + +If you need to test the parser execution without saving it as a function, add the bellow variable to simulate parameters values at the beginning. + + +``` +let Target = 'On-Premises'; +``` + +## Exchange Admin Audit Logs Parser + +### Parser Definition + +- Title: Exchange Admin Audit Logs Parser +- Version: 1.0 +- Last Updated: 15/11/2022 + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.0 |
  • Function initilisation for Sentinel Solution
| + +### Parser Description + +This parser takes raw Exchange Admin Audit Logs and add elements like ESI Environment, VIP information, sensitive information, etc... + +### Parser dependency + +This parser is linked to "ExchangeVIP" whatchlist + +### Parser Setup + + 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeAdminAuditLogs". + 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +### Linked tables + +This parser assumes that MS Exchange Management Logs from Exchange Servers Event Logs are collected in Log Analytics. diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md b/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md index b4b0e1d9655..eb1bad6a518 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md +++ b/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md @@ -1,4 +1,4 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|---------------------------------------------| -| 3.0.0 | 08-23-2023 |**ExchangeEnvironmentList** parser name | -| | | corrected in Workbooks. | +| 3.0.1 | 09-13-2023 | readme file for parsers and typo correction | +| 3.0.0 | 08-23-2023 |**ExchangeEnvironmentList** parser name corrected in Workbooks. | diff --git a/Tools/Create-Azure-Sentinel-Solution/V2/WorkbookMetadata/WorkbooksMetadata.json b/Tools/Create-Azure-Sentinel-Solution/V2/WorkbookMetadata/WorkbooksMetadata.json index c6959fa29d0..0faca55f0bb 100644 --- a/Tools/Create-Azure-Sentinel-Solution/V2/WorkbookMetadata/WorkbooksMetadata.json +++ b/Tools/Create-Azure-Sentinel-Solution/V2/WorkbookMetadata/WorkbooksMetadata.json @@ -4589,12 +4589,10 @@ "ESIExchangeOnlineConfig_CL" ], "dataConnectorsDependencies": [ - "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", "ESI-ExchangeOnlineCollector" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Least Privilege with RBAC - Online", "templateRelativePath": "Microsoft Exchange Least Privilege with RBAC - Online.json", "subtitle": "", @@ -4603,17 +4601,16 @@ { "workbookKey": "MicrosoftExchangeLeastPrivilegewithRBAC", "logoFileName": "Azure_Sentinel.svg", - "description": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment.", + "description": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Least Privilege with RBAC", "templateRelativePath": "Microsoft Exchange Least Privilege with RBAC.json", "subtitle": "", @@ -4622,17 +4619,16 @@ { "workbookKey": "MicrosoftExchangeSearchAdminAuditLog", "logoFileName": "Azure_Sentinel.svg", - "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment.", + "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Search AdminAuditLog", "templateRelativePath": "Microsoft Exchange Search AdminAuditLog.json", "subtitle": "", @@ -4641,17 +4637,16 @@ { "workbookKey": "MicrosoftExchangeSecurityMonitoring", "logoFileName": "Azure_Sentinel.svg", - "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers.", + "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Admin Activity", "templateRelativePath": "Microsoft Exchange Admin Activity.json", "subtitle": "", @@ -4665,12 +4660,10 @@ "ESIExchangeOnlineConfig_CL" ], "dataConnectorsDependencies": [ - "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", "ESI-ExchangeOnlineCollector" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Security Review - Online", "templateRelativePath": "Microsoft Exchange Security Review - Online.json", "subtitle": "", @@ -4679,17 +4672,16 @@ { "workbookKey": "MicrosoftExchangeSecurityReview", "logoFileName": "Azure_Sentinel.svg", - "description": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks.", + "description": "This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], "previewImagesFileNames": [], - "version": "1.0.0", + "version": "1.0.1", "title": "Microsoft Exchange Security Review", "templateRelativePath": "Microsoft Exchange Security Review.json", "subtitle": "", diff --git a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 index c397c6c4ae3..7a0afcd9445 100644 --- a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 @@ -2711,7 +2711,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe Write-Output "Missing arm-ttk validations. Downloading module..." Invoke-Expression "$armTtkFolder/download-arm-ttk.ps1" } - Invoke-Expression "$armTtkFolder/run-arm-ttk-in-automation.ps1 '$solutionName'" + Invoke-Expression "& '$armTtkFolder/run-arm-ttk-in-automation.ps1' '$solutionName'" } } From a00a20a5cc6416fdda63272969ce8605428ce8b1 Mon Sep 17 00:00:00 2001 From: nlepagnez Date: Fri, 15 Sep 2023 16:37:47 +0200 Subject: [PATCH 2/2] Revert CommonFunctions --- Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 index 7a0afcd9445..c397c6c4ae3 100644 --- a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 @@ -2711,7 +2711,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe Write-Output "Missing arm-ttk validations. Downloading module..." Invoke-Expression "$armTtkFolder/download-arm-ttk.ps1" } - Invoke-Expression "& '$armTtkFolder/run-arm-ttk-in-automation.ps1' '$solutionName'" + Invoke-Expression "$armTtkFolder/run-arm-ttk-in-automation.ps1 '$solutionName'" } }