From b9e70bfde94c09265882356710b8317955e009bb Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 18:36:16 -0700 Subject: [PATCH 1/7] dlpPii test --- powershell/Maester.psd1 | 2 +- .../public/cisa/exchange/Test-MtCisaDlpPii.md | 46 +++++++++++ .../cisa/exchange/Test-MtCisaDlpPii.ps1 | 76 +++++++++++++++++++ .../cisa/exchange/Test-MtCisaDlpPii.Tests.ps1 | 10 +++ website/docs/tests/cisa/exo.md | 1 + 5 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpPii.md create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 create mode 100644 tests/cisa/exchange/Test-MtCisaDlpPii.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index bdd3636a..a6bd6297 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -120,7 +120,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisaSpfRestriction', 'Test-MtCisaSpfDirective', 'Test-MtCisaDkim', 'Test-MtCisaDmarcRecordExist', 'Test-MtCisaDmarcRecordReject', 'Test-MtCisaDmarcAggregateCisa', 'Test-MtCisaDmarcReport', - 'Test-MtCisaDlp', + 'Test-MtCisaDlp', 'Test-MtCisaDlpPii', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.md b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.md new file mode 100644 index 00000000..008af28e --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.md @@ -0,0 +1,46 @@ +The DLP solution SHALL protect personally identifiable information (PII) and sensitive information, as defined by the agency. + +> Reference your organization's policy defining PII. + +Rationale: Users may inadvertently share sensitive information with others who should not have access to it. Data loss prevention policies provide a way for agencies to detect and prevent unauthorized disclosures. + +#### Remediation action: + +1. Sign in to the **Microsoft Purview compliance portal**. +2. Under the **Solutions** section, select **Data loss prevention**. +3. Select [**Policies**](https://purview.microsoft.com/datalossprevention/policies) from the left menu. +4. Select **Create policy**. +5. From the **Categories** list, select **Custom**. +6. From the **Templates** list, select **Custom policy** and then click **Next**. +7. Edit the name and description of the policy if desired, then click **Next**. +8. Under **Choose locations to apply the policy**, set **Status** to **On** for at least the Exchange email, OneDrive accounts, SharePoint sites, Teams chat and channel messages, and Devices locations, then click **Next**. +9. Under **Define policy settings**, select **Create or customize advanced DLP rules**, and then click **Next**. +10. Click **Create rule**. Assign the rule an appropriate name and description. +11. Click **Add condition**, then **Content contains**. +12. Click **Add**, then **Sensitive info types**. +13. Add information types that protect information sensitive to the agency. + + At a minimum, the agency should protect: + - Credit card numbers + - U.S. Individual Taxpayer Identification Numbers (ITIN) + - U.S. Social Security Numbers (SSN) + - All agency-defined PII and sensitive information + +14. Click **Add**. +15. Under **Actions**, click **Add an action**. +16. Check **Restrict Access or encrypt the content in Microsoft 365 locations**. +17. Under this action, select **Block Everyone**. +18. Under **User notifications**, turn on **Use notifications to inform your users and help educate them on the proper use of sensitive info**. +19. Under **Microsoft 365 services**, a section that appears after user notifications are turned on, check the box next to **Notify users in Office 365 service with a policy tip**. +20. Click **Save**, then **Next**. +21. Select **Turn it on right away**, then click **Next**. +22. Click **Submit**. + +#### Related links + +* [Purview admin center - Data loss prevention policies](https://purview.microsoft.com/datalossprevention/policies) +* [CISA 8 Data Loss Prevention Solutions - MS.EXO.8.2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo82v2) +* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/EXOConfig.rego#L438) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 new file mode 100644 index 00000000..6e16db3e --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 @@ -0,0 +1,76 @@ +<# +.SYNOPSIS + Checks state of DLP for EXO + +.DESCRIPTION + The DLP solution SHALL protect personally identifiable information (PII) and sensitive information, as defined by the agency. + +.EXAMPLE + Test-MtCisaDlpPii + + Returns true if + +.LINK + https://maester.dev/docs/commands/Test-MtCisaDlpPii +#> +function Test-MtCisaDlpPii { + [CmdletBinding()] + [OutputType([bool])] + param() + + if(!(Test-MtConnection ExchangeOnline)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedExchange + return $null + }elseif(!(Test-MtConnection SecurityCompliance)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance + return $null + } + + $policies = Get-DlpCompliancePolicy + + $resultPolicies = $policies | Where-Object {` + $_.ExchangeLocation.DisplayName -contains "All" -and ` + $_.Workload -like "*Exchange*" -and ` + -not $_.IsSimulationPolicy -and ` + $_.Enabled + } + + # This is a really slow call + $rules = $resultPolicies | foreach { + Get-DlpComplianceRule -Policy $_.Name + } + + $resultRules = $rules | Where-Object {` + -not $_.Disabled -and ` + $_.Mode -eq "Enforce" -and ` + $_.AdvancedRule -like "*50b8b56b-4ef8-44c2-a924-03374f5831ce*" # All Full Names Sensitive Info Type + } + + $testResult = ($resultRules | Measure-Object).Count -ge 1 + + $portalLink = "https://purview.microsoft.com/datalossprevention/policies" + + if ($testResult) { + $testResultMarkdown = "Well done. Your tenant has [Purview Data Loss Prevention Policies]($portalLink) enabled with the Sensitive Info Type of All Full Names.`n`n%TestResult%" + } else { + $testResultMarkdown = "Your tenant does not have [Purview Data Loss Prevention Policies]($portalLink) enabled with the Sensitive Info Type of All Full Names.`n`n%TestResult%" + } + + $passResult = "✅ Pass" + $failResult = "❌ Fail" + $result = "| Status | Policy | Rule |`n" + $result += "| --- | --- | --- |`n" + foreach ($item in ($rules | Sort-Object -Property ParentPolicyName,Name)) { + $itemResult = $failResult + if($item.Guid -in $resultRules.Guid){ + $itemResult = $passResult + } + $result += "| $($itemResult) | $($item.ParentPolicyName) | $($item.Name) |`n" + } + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cisa/exchange/Test-MtCisaDlpPii.Tests.ps1 b/tests/cisa/exchange/Test-MtCisaDlpPii.Tests.ps1 new file mode 100644 index 00000000..518f6b58 --- /dev/null +++ b/tests/cisa/exchange/Test-MtCisaDlpPii.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CISA SCuBA" -Tag "MS.EXO", "MS.EXO.8.2", "CISA", "Security", "All" { + It "MS.EXO.8.2: The DLP solution SHALL protect personally identifiable information (PII) and sensitive information, as defined by the agency." { + + $cisaDlpPii = Test-MtCisaDlpPii + + if ($null -ne $cisaDlpPii) { + $cisaDlpPii | Should -Be $true -Because "DLP protects sensitive information." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cisa/exo.md b/website/docs/tests/cisa/exo.md index 58b15e69..7f1770de 100644 --- a/website/docs/tests/cisa/exo.md +++ b/website/docs/tests/cisa/exo.md @@ -32,6 +32,7 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | Test-MtCisaCalendarSharing | [MS.EXO.6.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo62v1) | | Test-MtCisaExternalSenderWarning | [MS.EXO.7.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo71v1) | | Test-MtCisaDlp | [MS.EXO.8.1v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo81v2) | +| Test-MtCisaDlpPii | [MS.EXO.8.2v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo82v2) | | Test-MtCisaAntiSpamAllowList | [MS.EXO.12.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo121v1) | | Test-MtCisaAntiSpamSafeList | [MS.EXO.12.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo122v1) | | Test-MtCisaMailboxAuditing | [MS.EXO.13.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo131v1) | \ No newline at end of file From bd3c616afe21641a7e2368a119477552e9ae1660 Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 18:37:28 -0700 Subject: [PATCH 2/7] Added TODO --- powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 | 1 + powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 | 1 + 2 files changed, 2 insertions(+) diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 index 549bdc4c..de7a266c 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 @@ -18,6 +18,7 @@ function Test-MtCisaDlp { [OutputType([bool])] param() + #Add License Check if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 index 6e16db3e..0cbcef93 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 @@ -18,6 +18,7 @@ function Test-MtCisaDlpPii { [OutputType([bool])] param() + #Add License Check if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null From ee5352deb2ff9c523eda435b05183ad9a847780e Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 18:43:25 -0700 Subject: [PATCH 3/7] alternate DLP test --- powershell/Maester.psd1 | 2 +- .../cisa/exchange/Test-MtCisaDlpAlternate.md | 14 +++++++++ .../cisa/exchange/Test-MtCisaDlpAlternate.ps1 | 31 +++++++++++++++++++ .../Test-MtCisaDlpAlternate.Tests.ps1 | 10 ++++++ website/docs/tests/cisa/exo.md | 1 + 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.md create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.ps1 create mode 100644 tests/cisa/exchange/Test-MtCisaDlpAlternate.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index a6bd6297..1033dc4c 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -120,7 +120,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisaSpfRestriction', 'Test-MtCisaSpfDirective', 'Test-MtCisaDkim', 'Test-MtCisaDmarcRecordExist', 'Test-MtCisaDmarcRecordReject', 'Test-MtCisaDmarcAggregateCisa', 'Test-MtCisaDmarcReport', - 'Test-MtCisaDlp', 'Test-MtCisaDlpPii', + 'Test-MtCisaDlp', 'Test-MtCisaDlpPii', 'Test-MtCisaDlpAlternate', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.md b/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.md new file mode 100644 index 00000000..e60534e5 --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.md @@ -0,0 +1,14 @@ +The selected DLP solution SHOULD offer services comparable to the native DLP solution offered by Microsoft. + +Rationale: Any alternative DLP solution should be able to detect sensitive information in Exchange Online and block access to unauthorized entities. + +> This test will always skip by default. + +#### Related links + +* [Purview admin center - Data loss prevention policies](https://purview.microsoft.com/datalossprevention/policies) +* [CISA 8 Data Loss Prevention Solutions - MS.EXO.8.3](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo83v1) +* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/EXOConfig.rego#L453) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.ps1 new file mode 100644 index 00000000..952d2264 --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpAlternate.ps1 @@ -0,0 +1,31 @@ +<# +.SYNOPSIS + This will always return $null + +.DESCRIPTION + The selected DLP solution SHOULD offer services comparable to the native DLP solution offered by Microsoft. + +.EXAMPLE + Test-MtCisaDlpAlternate + + Always will return $null + +.LINK + https://maester.dev/docs/commands/Test-MtCisaDlpAlternate +#> +function Test-MtCisaDlpAlternate { + [CmdletBinding()] + [OutputType([bool])] + param() + + #Add License Check + if(!(Test-MtConnection ExchangeOnline)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedExchange + return $null + }elseif(!(Test-MtConnection SecurityCompliance)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance + return $null + }else{ + return $null + } +} \ No newline at end of file diff --git a/tests/cisa/exchange/Test-MtCisaDlpAlternate.Tests.ps1 b/tests/cisa/exchange/Test-MtCisaDlpAlternate.Tests.ps1 new file mode 100644 index 00000000..36f41770 --- /dev/null +++ b/tests/cisa/exchange/Test-MtCisaDlpAlternate.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CISA SCuBA" -Tag "MS.EXO", "MS.EXO.8.3", "CISA", "Security", "All" { + It "MS.EXO.8.3: The selected DLP solution SHOULD offer services comparable to the native DLP solution offered by Microsoft." { + + $cisa = Test-MtCisaDlpAlternate + + if ($null -ne $cisa) { + $cisa | Should -Be $true -Because "will not reach here." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cisa/exo.md b/website/docs/tests/cisa/exo.md index 7f1770de..acdf38bb 100644 --- a/website/docs/tests/cisa/exo.md +++ b/website/docs/tests/cisa/exo.md @@ -33,6 +33,7 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | Test-MtCisaExternalSenderWarning | [MS.EXO.7.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo71v1) | | Test-MtCisaDlp | [MS.EXO.8.1v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo81v2) | | Test-MtCisaDlpPii | [MS.EXO.8.2v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo82v2) | +| Test-MtCisaDlpAlternate | [MS.EXO.8.3v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo83v1) | | Test-MtCisaAntiSpamAllowList | [MS.EXO.12.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo121v1) | | Test-MtCisaAntiSpamSafeList | [MS.EXO.12.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo122v1) | | Test-MtCisaMailboxAuditing | [MS.EXO.13.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo131v1) | \ No newline at end of file From 833400f78d84f3666605959b2da53c78c0f1893f Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 19:23:59 -0700 Subject: [PATCH 4/7] exoDlpBaseline --- powershell/Maester.psd1 | 1 + .../exchange/Test-MtCisaDlpBaselineRule.md | 46 +++++++++ .../exchange/Test-MtCisaDlpBaselineRule.ps1 | 97 +++++++++++++++++++ .../Test-MtCisaDlpBaselineRule.Tests.ps1 | 10 ++ website/docs/tests/cisa/exo.md | 1 + 5 files changed, 155 insertions(+) create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.md create mode 100644 powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 create mode 100644 tests/cisa/exchange/Test-MtCisaDlpBaselineRule.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index 1033dc4c..38fa1d96 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -121,6 +121,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisaDmarcRecordExist', 'Test-MtCisaDmarcRecordReject', 'Test-MtCisaDmarcAggregateCisa', 'Test-MtCisaDmarcReport', 'Test-MtCisaDlp', 'Test-MtCisaDlpPii', 'Test-MtCisaDlpAlternate', + 'Test-MtCisaDlpBaselineRule', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.md b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.md new file mode 100644 index 00000000..0d0c3029 --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.md @@ -0,0 +1,46 @@ +At a minimum, the DLP solution SHALL restrict sharing credit card numbers, U.S. Individual Taxpayer Identification Numbers (ITIN), and U.S. Social Security numbers (SSN) via email. + +> Reference your organization's policy defining restricted information. + +Rationale: Users may inadvertently share sensitive information with others who should not have access to it. Data loss prevention policies provide a way for agencies to detect and prevent unauthorized disclosures. + +#### Remediation action: + +1. Sign in to the **Microsoft Purview compliance portal**. +2. Under the **Solutions** section, select **Data loss prevention**. +3. Select [**Policies**](https://purview.microsoft.com/datalossprevention/policies) from the left menu. +4. Select **Create policy**. +5. From the **Categories** list, select **Custom**. +6. From the **Templates** list, select **Custom policy** and then click **Next**. +7. Edit the name and description of the policy if desired, then click **Next**. +8. Under **Choose locations to apply the policy**, set **Status** to **On** for at least the Exchange email, OneDrive accounts, SharePoint sites, Teams chat and channel messages, and Devices locations, then click **Next**. +9. Under **Define policy settings**, select **Create or customize advanced DLP rules**, and then click **Next**. +10. Click **Create rule**. Assign the rule an appropriate name and description. +11. Click **Add condition**, then **Content contains**. +12. Click **Add**, then **Sensitive info types**. +13. Add information types that protect information sensitive to the agency. + + At a minimum, the agency should protect: + - Credit card numbers + - U.S. Individual Taxpayer Identification Numbers (ITIN) + - U.S. Social Security Numbers (SSN) + - All agency-defined PII and sensitive information + +14. Click **Add**. +15. Under **Actions**, click **Add an action**. +16. Check **Restrict Access or encrypt the content in Microsoft 365 locations**. +17. Under this action, select **Block Everyone**. +18. Under **User notifications**, turn on **Use notifications to inform your users and help educate them on the proper use of sensitive info**. +19. Under **Microsoft 365 services**, a section that appears after user notifications are turned on, check the box next to **Notify users in Office 365 service with a policy tip**. +20. Click **Save**, then **Next**. +21. Select **Turn it on right away**, then click **Next**. +22. Click **Submit**. + +#### Related links + +* [Purview admin center - Data loss prevention policies](https://purview.microsoft.com/datalossprevention/policies) +* [CISA 8 Data Loss Prevention Solutions - MS.EXO.8.4](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo84v1) +* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/EXOConfig.rego#L468) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 new file mode 100644 index 00000000..d6bd2fad --- /dev/null +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 @@ -0,0 +1,97 @@ +<# +.SYNOPSIS + Checks state of baseline CISA rules for DLP in EXO + +.DESCRIPTION + At a minimum, the DLP solution SHALL restrict sharing credit card numbers, U.S. Individual Taxpayer Identification Numbers (ITIN), and U.S. Social Security numbers (SSN) via email. + +.EXAMPLE + Test-MtCisaDlpBaselineRule + + Returns true if baseline rules are enforced + +.LINK + https://maester.dev/docs/commands/Test-MtCisaDlpBaselineRule +#> +function Test-MtCisaDlpBaselineRule { + [CmdletBinding()] + [OutputType([bool])] + param() + + #Add License Check + if(!(Test-MtConnection ExchangeOnline)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedExchange + return $null + }elseif(!(Test-MtConnection SecurityCompliance)){ + Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance + return $null + } + + $policies = Get-DlpCompliancePolicy + + $resultPolicies = $policies | Where-Object {` + $_.ExchangeLocation.DisplayName -contains "All" -and ` + $_.Workload -like "*Exchange*" -and ` + -not $_.IsSimulationPolicy -and ` + $_.Enabled + } + + # This is a really slow call + $rules = $resultPolicies | foreach { + Get-DlpComplianceRule -Policy $_.Name + } + + $sits = [pscustomobject]@{ + ccn = "*50842eb7-edc8-4019-85dd-5a5c1f2bb085*" # Credit Card Number + ssn = "*a44669fe-0d48-453d-a9b1-2cc83f2cba77*" # U.S. Social Security Number (SSN) + itin = "*e55e2a32-f92d-4985-a35d-a0b269eb687b*" # U.S. Individual Taxpayer Identification Number (ITIN) + } + + $resultRules = $rules | Where-Object {` + -not $_.Disabled -and ` + $_.Mode -eq "Enforce" -and (` + $_.AdvancedRule -like $sits.ccn -or` + $_.AdvancedRule -like $sits.ssn -or` + $_.AdvancedRule -like $sits.itin + ) + } + + $resultCcn = $resultRules.AdvancedRule -join "`n" -like $sits.ccn + $resultSsn = $resultRules.AdvancedRule -join "`n" -like $sits.ssn + $resultItin = $resultRules.AdvancedRule -join "`n" -like $sits.itin + + $resultComposite = $resultCcn -and $resultSsn -and $resultItin + + $testResult = ($resultComposite | Measure-Object).Count -ge 1 + + $portalLink = "https://purview.microsoft.com/datalossprevention/policies" + + if ($resultComposite) { + $testResultMarkdown = "Well done. Your tenant has [Purview Data Loss Prevention Policies]($portalLink) enabled with the Sensitive Info Type of credit card numbers, U.S. Individual Taxpayer Identification Numbers (ITIN), and U.S. Social Security numbers (SSN).`n`n%TestResult%" + } else { + $testResultMarkdown = "Your tenant does not have [Purview Data Loss Prevention Policies]($portalLink) enabled with the Sensitive Info Type of credit card numbers, U.S. Individual Taxpayer Identification Numbers (ITIN), and U.S. Social Security numbers (SSN).`n`n%TestResult%" + } + + $passResult = "✅ Pass" + $failResult = "❌ Fail" + $result = "Required Rules:`n`n" + $result += "| Credit Card Number | U.S. Social Security Number | U.S. Individual Taxpayer Identification Number |`n" + $result += "| --- | --- | --- |`n" + $result += "| $(if($resultCcn){$passResult}else{$failResult}) | $(if($resultSsn){$passResult}else{$failResult}) | $(if($resultItin){$passResult}else{$failResult}) |`n`n" + $result += "Rule Relationships:`n`n" + $result += "| Status | Policy | Rule |`n" + $result += "| --- | --- | --- |`n" + foreach ($item in ($rules | Sort-Object -Property ParentPolicyName,Name)) { + $itemResult = $failResult + if($item.Guid -in $resultRules.Guid){ + $itemResult = $passResult + } + $result += "| $($itemResult) | $($item.ParentPolicyName) | $($item.Name) |`n" + } + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cisa/exchange/Test-MtCisaDlpBaselineRule.Tests.ps1 b/tests/cisa/exchange/Test-MtCisaDlpBaselineRule.Tests.ps1 new file mode 100644 index 00000000..2fba79f1 --- /dev/null +++ b/tests/cisa/exchange/Test-MtCisaDlpBaselineRule.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CISA SCuBA" -Tag "MS.EXO", "MS.EXO.8.4", "CISA", "Security", "All" { + It "MS.EXO.8.4: At a minimum, the DLP solution SHALL restrict sharing credit card numbers, U.S. Individual Taxpayer Identification Numbers (ITIN), and U.S. Social Security numbers (SSN) via email." { + + $cisa = Test-MtCisaDlpBaselineRule + + if ($null -ne $cisa) { + $cisa | Should -Be $true -Because "baseline DLP rules are in use." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cisa/exo.md b/website/docs/tests/cisa/exo.md index acdf38bb..cd6f6e55 100644 --- a/website/docs/tests/cisa/exo.md +++ b/website/docs/tests/cisa/exo.md @@ -34,6 +34,7 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | Test-MtCisaDlp | [MS.EXO.8.1v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo81v2) | | Test-MtCisaDlpPii | [MS.EXO.8.2v2](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo82v2) | | Test-MtCisaDlpAlternate | [MS.EXO.8.3v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo83v1) | +| Test-MtCisaDlpBaselineRules | [MS.EXO.8.4v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo84v1) | | Test-MtCisaAntiSpamAllowList | [MS.EXO.12.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo121v1) | | Test-MtCisaAntiSpamSafeList | [MS.EXO.12.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo122v1) | | Test-MtCisaMailboxAuditing | [MS.EXO.13.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo131v1) | \ No newline at end of file From 02d170729ea589b884a1e93bbca6ba3c0be2d833 Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 19:41:25 -0700 Subject: [PATCH 5/7] add properties --- .../public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 | 5 ++++- powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 index d6bd2fad..3a45831a 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 @@ -49,7 +49,10 @@ function Test-MtCisaDlpBaselineRule { $resultRules = $rules | Where-Object {` -not $_.Disabled -and ` - $_.Mode -eq "Enforce" -and (` + $_.Mode -eq "Enforce" -and ` + $_.BlockAccess -and ` + $_.BlockAccessScope -eq "All" -and ` + $_.NotifyPolicyTipDisplayOption -eq "Tip" -and (` $_.AdvancedRule -like $sits.ccn -or` $_.AdvancedRule -like $sits.ssn -or` $_.AdvancedRule -like $sits.itin diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 index 0cbcef93..6c6d2825 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 @@ -44,6 +44,9 @@ function Test-MtCisaDlpPii { $resultRules = $rules | Where-Object {` -not $_.Disabled -and ` $_.Mode -eq "Enforce" -and ` + $_.BlockAccess -and ` + $_.BlockAccessScope -eq "All" -and ` + $_.NotifyPolicyTipDisplayOption -eq "Tip" -and ` $_.AdvancedRule -like "*50b8b56b-4ef8-44c2-a924-03374f5831ce*" # All Full Names Sensitive Info Type } From af516bbac207670db9912cbe206d725d43f61e29 Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 20:19:01 -0700 Subject: [PATCH 6/7] Add license check --- powershell/internal/Get-MtSkippedReason.ps1 | 1 + powershell/public/Add-MtTestResultDetail.ps1 | 2 +- .../public/Get-MtLicenseInformation.ps1 | 24 ++++++++++++++++++- .../public/cisa/exchange/Test-MtCisaDlp.ps1 | 4 +++- .../exchange/Test-MtCisaDlpBaselineRule.ps1 | 4 +++- .../cisa/exchange/Test-MtCisaDlpPii.ps1 | 4 +++- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/powershell/internal/Get-MtSkippedReason.ps1 b/powershell/internal/Get-MtSkippedReason.ps1 index 893196da..41659ae8 100644 --- a/powershell/internal/Get-MtSkippedReason.ps1 +++ b/powershell/internal/Get-MtSkippedReason.ps1 @@ -18,6 +18,7 @@ function Get-MtSkippedReason { "NotLicensedEntraIDP2" { "This test is for tenants that are licensed for Entra ID P2. See [Entra ID licensing](https://learn.microsoft.com/entra/fundamentals/licensing)"; break} "NotLicensedEntraIDGovernance" { "This test is for tenants that are licensed for Entra ID Governance. See [Entra ID Governance licensing](https://learn.microsoft.com/entra/fundamentals/licensing#microsoft-entra-id-governance)"; break} "NotLicensedEntraWorkloadID" { "This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)"; break} + "NotLicensedExoDlp" { "This test is for tenants that are licensed for Exchange Online DLP. See [Microsoft Purview Data Loss Prevention: Data Loss Prevention (DLP) for Exchange Online, SharePoint Online, and OneDrive for Business](https://learn.microsoft.com/en-us/office365/servicedescriptions/microsoft-365-service-descriptions/microsoft-365-tenantlevel-services-licensing-guidance/microsoft-365-security-compliance-licensing-guidance#which-licenses-provide-the-rights-for-a-user-to-benefit-from-the-service-7)"; break} "LicensedEntraIDPremium" { "This test is for tenants that are not licensed for any Entra ID Premium license. See [Entra ID licensing](https://learn.microsoft.com/entra/fundamentals/licensing)"; break} "NotSupported" { "This test relies on capabilities not currently available (e.g., cmdlets that are not available on all platforms, Resolve-DnsName)"; break} default { $SkippedBecause; break} diff --git a/powershell/public/Add-MtTestResultDetail.ps1 b/powershell/public/Add-MtTestResultDetail.ps1 index f28a1de5..4b036047 100644 --- a/powershell/public/Add-MtTestResultDetail.ps1 +++ b/powershell/public/Add-MtTestResultDetail.ps1 @@ -65,7 +65,7 @@ function Add-MtTestResultDetail { [Parameter(Mandatory = $false)] [ValidateSet('NotConnectedAzure', 'NotConnectedExchange', 'NotDotGovDomain', 'NotLicensedEntraIDP1', 'NotConnectedSecurityCompliance', - 'NotLicensedEntraIDP2', 'NotLicensedEntraIDGovernance', 'NotLicensedEntraWorkloadID', "LicensedEntraIDPremium", 'NotSupported', 'Custom' + 'NotLicensedEntraIDP2', 'NotLicensedEntraIDGovernance', 'NotLicensedEntraWorkloadID', 'NotLicensedExoDlp', "LicensedEntraIDPremium", 'NotSupported', 'Custom' )] # Common reasons for why the test was skipped. [string] $SkippedBecause, diff --git a/powershell/public/Get-MtLicenseInformation.ps1 b/powershell/public/Get-MtLicenseInformation.ps1 index dd66ef8c..e538de98 100644 --- a/powershell/public/Get-MtLicenseInformation.ps1 +++ b/powershell/public/Get-MtLicenseInformation.ps1 @@ -19,7 +19,7 @@ function Get-MtLicenseInformation { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0, Mandatory)] - [ValidateSet('EntraID', 'EntraWorkloadID')] + [ValidateSet('EntraID', 'EntraWorkloadID', 'ExoDlp')] [string] $Product ) @@ -55,6 +55,28 @@ function Get-MtLicenseInformation { return $LicenseType Break } + "ExoDlp" { + Write-Verbose "Retrieving license SKU for ExoDlp" + $skus = Invoke-MtGraphRequest -RelativeUri "subscribedSkus" + $requiredSkus = @( + #skuId + "cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46", #Microsoft 365 Business Premium + "a3f586b6-8cce-4d9b-99d6-55238397f77a", #Microsoft 365 Business Premium EEA (no Teams) + #servicePlanId + "efb87545-963c-4e0d-99df-69c6916d9eb0" #Exchange Online (Plan 2) + ) + $LicenseType = $null + foreach($sku in $requiredSkus){ + $skuId = $sku -in $skus.skuId + $servicePlanId = $sku -in $skus.servicePlans.servicePlanId + if($skuId -or $servicePlanId){ + $LicenseType = "ExoDlp" + } + } + Write-Information "The license type for Entra ID is $LicenseType" + return $LicenseType + Break + } Default {} } diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 index de7a266c..69f5b1a1 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlp.ps1 @@ -18,13 +18,15 @@ function Test-MtCisaDlp { [OutputType([bool])] param() - #Add License Check if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null }elseif(!(Test-MtConnection SecurityCompliance)){ Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance return $null + }elseif($null -eq (Get-MtLicenseInformation -Product ExoDlp)){ + Add-MtTestResultDetail -SkippedBecause NotLicensedExoDlp + return $null } $policies = Get-DlpCompliancePolicy diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 index 3a45831a..da380ae6 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 @@ -18,13 +18,15 @@ function Test-MtCisaDlpBaselineRule { [OutputType([bool])] param() - #Add License Check if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null }elseif(!(Test-MtConnection SecurityCompliance)){ Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance return $null + }elseif($null -eq (Get-MtLicenseInformation -Product ExoDlp)){ + Add-MtTestResultDetail -SkippedBecause NotLicensedExoDlp + return $null } $policies = Get-DlpCompliancePolicy diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 index 6c6d2825..6b0e9643 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 @@ -18,13 +18,15 @@ function Test-MtCisaDlpPii { [OutputType([bool])] param() - #Add License Check if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null }elseif(!(Test-MtConnection SecurityCompliance)){ Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance return $null + }elseif($null -eq (Get-MtLicenseInformation -Product ExoDlp)){ + Add-MtTestResultDetail -SkippedBecause NotLicensedExoDlp + return $null } $policies = Get-DlpCompliancePolicy From f36093bfbb203a61d05a480a1b97d65c097508ff Mon Sep 17 00:00:00 2001 From: Snozz Date: Tue, 6 Aug 2024 20:23:31 -0700 Subject: [PATCH 7/7] alias --- powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 | 2 +- powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 index da380ae6..209071b3 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpBaselineRule.ps1 @@ -39,7 +39,7 @@ function Test-MtCisaDlpBaselineRule { } # This is a really slow call - $rules = $resultPolicies | foreach { + $rules = $resultPolicies | ForEach-Object { Get-DlpComplianceRule -Policy $_.Name } diff --git a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 index 6b0e9643..14446750 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDlpPii.ps1 @@ -39,7 +39,7 @@ function Test-MtCisaDlpPii { } # This is a really slow call - $rules = $resultPolicies | foreach { + $rules = $resultPolicies | ForEach-Object { Get-DlpComplianceRule -Policy $_.Name }