From a43b8c0dde5d19dbdceff2207fceb64305ef7a7b Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Fri, 20 Sep 2024 20:40:25 +1200 Subject: [PATCH 1/8] CIS 2.1.1 --- powershell/Maester.psd1 | 4 +- powershell/public/cis/Test-MtCisSafeLink.md | 42 ++++++ powershell/public/cis/Test-MtCisSafeLink.ps1 | 134 +++++++++++++++++++ tests/cis/Test-MtCisSafeLink.Tests.ps1 | 10 ++ website/docs/tests/cis/readme.md | 3 + 5 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 powershell/public/cis/Test-MtCisSafeLink.md create mode 100644 powershell/public/cis/Test-MtCisSafeLink.ps1 create mode 100644 tests/cis/Test-MtCisSafeLink.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index 41c8f026..165a0136 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -138,6 +138,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisSharedMailboxSignIn', 'Test-MtCisPasswordExpiry', 'Test-MtCisCustomerLockBox', + 'Test-MtCisSafeLink', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', @@ -205,5 +206,4 @@ HelpInfoURI = 'https://maester.dev/docs/commands/' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' -} - +} \ No newline at end of file diff --git a/powershell/public/cis/Test-MtCisSafeLink.md b/powershell/public/cis/Test-MtCisSafeLink.md new file mode 100644 index 00000000..72bd7c8d --- /dev/null +++ b/powershell/public/cis/Test-MtCisSafeLink.md @@ -0,0 +1,42 @@ +2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled + +Safe Links for Office applications extends phishing protection to documents and emails that contain hyperlinks, even after they have been delivered to a user. + +#### Remediation action: + +To create a Safe Links policy: + +1. Navigate to Microsoft 365 admin center [https://admin.microsoft.com](https://admin.microsoft.com). +2. Under **Email & collaboration** select **Policies & rules** +3. Select **Threat policies** then **Safe Links** +4. Click on **+Create** +5. Name the policy then click **Next** +6. In Domains select all valid domains for the organization and Next +7. Ensure the following **URL & click protection settings** are defined: + +**Email** +* Checked **On: Safe Links checks a list of known, malicious links when users click links in email. URLs are rewritten by default** +* Checked **Apply Safe Links to email messages sent within the organization** +* Checked **Apply real-time URL scanning for suspicious links and links that point to files** +* Checked **Wait for URL scanning to complete before delivering the message** +* Unchecked **Do not rewrite URLs, do checks via Safe Links API only**. + +**Teams** +* Checked **On: Safe Links checks a list of known, malicious links when users click links in Microsoft Teams. URLs are not rewritten**. + +**Office 365 Apps** +* Checked On: **Safe Links checks a list of known, malicious links when users click links in Microsoft Office apps. URLs are not rewritten** + +**Click protection settings** +* Checked: **Track user clicks** +* Unchecked: **Let users click through the original URL** +* There is no recommendation for organization branding +8. Click **Next** twice and finally Submit. + +#### Related links + +* [Microsoft 365 Admin Center](https://admin.microsoft.com) +* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 61](https://www.cisecurity.org/benchmark/microsoft_365) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cis/Test-MtCisSafeLink.ps1 b/powershell/public/cis/Test-MtCisSafeLink.ps1 new file mode 100644 index 00000000..ed27ab31 --- /dev/null +++ b/powershell/public/cis/Test-MtCisSafeLink.ps1 @@ -0,0 +1,134 @@ +<# +.SYNOPSIS +Checks if safe links for office applications are Enabled + +.DESCRIPTION +Safe links should be enabled for office applications (Exchange Teams Office 365 Apps) + +.EXAMPLE +Test-MtCisSafeLink + +Returns true safe links are enabled + +.LINK +https://maester.dev/docs/commands/Test-MtCisSafeLink +#> +function Test-MtCisSafeLink { + [CmdletBinding()] + [OutputType([bool])] + param() + + 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 Mdo)) { + Add-MtTestResultDetail -SkippedBecause NotLicensedMdo + return $null + } + + Write-Verbose "Getting Safe Links Policy..." + $policy = Get-MtExo -Request SafeLinksPolicy + + $safeLinkCheckList = @() + + #EnableSafeLinksForEmail + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "EnableSafeLinksForEmail" + "Value" = "True" + } + + #EnableSafeLinksForTeams + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "EnableSafeLinksForTeams" + "Value" = "True" + } + + #EnableSafeLinksForOffice + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "EnableSafeLinksForOffice" + "Value" = "True" + } + + #TrackClicks + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "TrackClicks" + "Value" = "True" + } + + #AllowClickThrough + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "AllowClickThrough" + "Value" = "False" + } + + #ScanUrls + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "ScanUrls" + "Value" = "True" + } + + #EnableForInternalSenders + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "EnableForInternalSenders" + "Value" = "True" + } + + #DeliverMessageAfterScan + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "DeliverMessageAfterScan" + "Value" = "True" + } + + #DisableUrlRewrite + $safeLinkCheckList += [pscustomobject] @{ + "CheckName" = "DisableUrlRewrite" + "Value" = "True" + } + + Write-Verbose "Executing checks" + $failedCheckList = @() + foreach ($check in $safeLinkCheckList) { + + $checkResult = $policy | Where-Object { $_.($check.CheckName) -notmatch $check.Value } + + if ($checkResult) { + #If the check fails, add it to the list so we can report on it later + $failedCheckList += $check.CheckName + } + + } + + $testResult = ($failedCheckList | Measure-Object).Count -eq 0 + Write-Verbose "testResult" $testResult + + $portalLink = "https://security.microsoft.com/presetSecurityPolicies" + + if ($testResult) { + $testResultMarkdown = "Well done. Your tenant has the recommended safelink settings configured ($portalLink).`n`n%TestResult%" + } + else { + $testResultMarkdown = "Your tenant does not have the recommended safelink settings configured ($portalLink).`n`n%TestResult%" + } + + + $resultMd = "| Check Name | Result |`n" + $resultMd += "| --- | --- |`n" + foreach ($item in $safeLinkCheckList) { + $itemResult = "❌ Fail" + if ($item.CheckName -notin $failedCheckList) { + $itemResult = "✅ Pass" + } + $resultMd += "| $($item.CheckName) | $($itemResult) |`n" + } + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $resultMd + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cis/Test-MtCisSafeLink.Tests.ps1 b/tests/cis/Test-MtCisSafeLink.Tests.ps1 new file mode 100644 index 00000000..0aa7a3f9 --- /dev/null +++ b/tests/cis/Test-MtCisSafeLink.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CIS" -Tag "CIS 2.1.1", "L2", "CIS E5 Level 2", "CIS E5", "CIS", "Security", "All", "CIS M365 v3.1.0" { + It "2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled" { + + $result = Test-MtCisSafeLink + + if ($null -ne $result) { + $result | Should -Be $true -Because "safe links office applications are Enabled" + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cis/readme.md b/website/docs/tests/cis/readme.md index 9e1ae774..ad77757c 100644 --- a/website/docs/tests/cis/readme.md +++ b/website/docs/tests/cis/readme.md @@ -35,5 +35,8 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | TBD | 1.3.4 (L1) Ensure 'User owned apps and services' is restricted | | TBD | 1.3.5 (L1) Ensure internal phishing protection for Forms is enabled | | Test-MtCisCustomerLockBox | 1.3.6 (L2) Ensure the customer lockbox feature is enabled | +| TBD | 1.3.7 (L2) Ensure 'third-party storage services' are restricted in 'Microsoft 365 on the web' | +| TBD | 1.3.8 (L2) Ensure that Sways cannot be shared with people outside of your organization | +| Test-MtCisSafeLink | 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled | TBD in this case refers to CIS "manual" checks. It might be possible to automate these, but skipping for now to focus on automated checks. \ No newline at end of file From 0bdeb0feed5dc0a9b41793c1781e7da193b04361 Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Fri, 20 Sep 2024 20:50:11 +1200 Subject: [PATCH 2/8] Removed old comment --- powershell/public/cis/Test-MtCisSafeLink.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/powershell/public/cis/Test-MtCisSafeLink.ps1 b/powershell/public/cis/Test-MtCisSafeLink.ps1 index ed27ab31..4e199be8 100644 --- a/powershell/public/cis/Test-MtCisSafeLink.ps1 +++ b/powershell/public/cis/Test-MtCisSafeLink.ps1 @@ -104,7 +104,6 @@ function Test-MtCisSafeLink { } $testResult = ($failedCheckList | Measure-Object).Count -eq 0 - Write-Verbose "testResult" $testResult $portalLink = "https://security.microsoft.com/presetSecurityPolicies" From 7baebb2f069ebf4f6a0333cbc32ea3f1458b09be Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 10:34:29 +1200 Subject: [PATCH 3/8] CIS 2.1.2 --- powershell/Maester.psd1 | 1 + .../public/cis/Test-MtCisAttachmentFilter.md | 22 ++++++ .../public/cis/Test-MtCisAttachmentFilter.ps1 | 70 +++++++++++++++++++ .../cis/Test-MtCisAttachmentFilter.Tests.ps1 | 10 +++ website/docs/tests/cis/readme.md | 1 + 5 files changed, 104 insertions(+) create mode 100644 powershell/public/cis/Test-MtCisAttachmentFilter.md create mode 100644 powershell/public/cis/Test-MtCisAttachmentFilter.ps1 create mode 100644 tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index db85c88b..adc5a862 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -139,6 +139,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisPasswordExpiry', 'Test-MtCisCustomerLockBox', 'Test-MtCisSafeLink', + 'Test-MtCisAttachmentFilter', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cis/Test-MtCisAttachmentFilter.md b/powershell/public/cis/Test-MtCisAttachmentFilter.md new file mode 100644 index 00000000..fb5b2992 --- /dev/null +++ b/powershell/public/cis/Test-MtCisAttachmentFilter.md @@ -0,0 +1,22 @@ +2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled + +**Rationale:** + +Blocking known malicious file types can help prevent malware-infested files from infecting a host. + +#### Remediation action: + +Ensure the Common Attachment Types Filter is enabled: +1. Navigate to Microsoft 365 Defender [https://security.microsoft.com](https://security.microsoft.com). +2. Click to expand **Email & collaboration** select **Policies & rules**. +3. On the Policies & rules page select **Threat policies**. +4. Under polices select **Anti-malware** and click on the **Default (Default)** policy. +5. On the policy page that appears on the righthand pane, under **Protection settings**, verify that the **Enable the common attachments filter** has the value of **On**. + +#### Related links + +* [Microsoft 365 Defender](https://security.microsoft.com) +* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 33](https://www.cisecurity.org/benchmark/microsoft_365) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 b/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 new file mode 100644 index 00000000..c0044368 --- /dev/null +++ b/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 @@ -0,0 +1,70 @@ +<# +.SYNOPSIS + Checks if the default common attadchment types filter is enabled + +.DESCRIPTION + The common attachment types fileter should be enabled + +.EXAMPLE + Test-MtCisAttachmentFilter + + Returns true if the common attachment types filter is enabled. + +.LINK + https://maester.dev/docs/commands/Test-MtCisAttachmentFilter +#> +function Test-MtCisAttachmentFilter { + [CmdletBinding()] + [OutputType([bool])] + param() + + 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 Mdo)) { + Add-MtTestResultDetail -SkippedBecause NotLicensedMdo + return $null + } + + Write-Verbose "Getting Malware Filter Policy..." + $policy = Get-MtExo -Request MalwareFilterPolicy + + Write-Verbose "Executing checks" + $fileFilter = $policy | Where-Object { + $_.EnableFileFilter + } + + $testResult = ($fileFilter | Measure-Object).Count -ge 1 + + $portalLink = "https://security.microsoft.com/presetSecurityPolicies" + + if ($testResult) { + $testResultMarkdown = "Well done. Your tenant has the common attachment file filter enabled ($portalLink).`n`n%TestResult%" + } + else { + $testResultMarkdown = "Your tenant does not have the common attachment file filter enabled ($portalLink).`n`n%TestResult%" + } + + $resultMd = "| Policy | Result |`n" + $resultMd += "| --- | --- |`n" + + if ($testResult) { + $Result = "✅ Pass" + } + else { + $Result = "❌ Fail" + } + + $resultMd += "| EnableFileFilter | $Result |`n" + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $resultMd + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 b/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 new file mode 100644 index 00000000..0668b8ac --- /dev/null +++ b/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CIS" -Tag "CIS 2.1.2", "L1", "CIS E3 Level 1", "CIS E3", "CIS", "Security", "All", "CIS M365 v3.1.0" { + It "CIS 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled" { + + $result = Test-MtCisAttachmentFilter + + if ($null -ne $result) { + $result | Should -Be $true -Because "common attachment file filter is enabled ." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cis/readme.md b/website/docs/tests/cis/readme.md index ad77757c..a1714511 100644 --- a/website/docs/tests/cis/readme.md +++ b/website/docs/tests/cis/readme.md @@ -38,5 +38,6 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | TBD | 1.3.7 (L2) Ensure 'third-party storage services' are restricted in 'Microsoft 365 on the web' | | TBD | 1.3.8 (L2) Ensure that Sways cannot be shared with people outside of your organization | | Test-MtCisSafeLink | 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled | +| Test-MtCisAttachmentFilter | 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled | TBD in this case refers to CIS "manual" checks. It might be possible to automate these, but skipping for now to focus on automated checks. \ No newline at end of file From c15b144941c28dbe4819c3944342ec44a07a547b Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 15:46:19 +1200 Subject: [PATCH 4/8] message update --- tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 b/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 index 0668b8ac..ebe535aa 100644 --- a/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 +++ b/tests/cis/Test-MtCisAttachmentFilter.Tests.ps1 @@ -4,7 +4,7 @@ Describe "CIS" -Tag "CIS 2.1.2", "L1", "CIS E3 Level 1", "CIS E3", "CIS", "Secur $result = Test-MtCisAttachmentFilter if ($null -ne $result) { - $result | Should -Be $true -Because "common attachment file filter is enabled ." + $result | Should -Be $true -Because "the common attachment file filter is enabled." } } } \ No newline at end of file From 526c68f44819bd084b0a76b2b867893391ee64e2 Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 15:50:02 +1200 Subject: [PATCH 5/8] Fixed attachment filter remediation --- powershell/public/cis/Test-MtCisAttachmentFilter.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/powershell/public/cis/Test-MtCisAttachmentFilter.md b/powershell/public/cis/Test-MtCisAttachmentFilter.md index fb5b2992..dacfda49 100644 --- a/powershell/public/cis/Test-MtCisAttachmentFilter.md +++ b/powershell/public/cis/Test-MtCisAttachmentFilter.md @@ -6,12 +6,15 @@ Blocking known malicious file types can help prevent malware-infested files from #### Remediation action: -Ensure the Common Attachment Types Filter is enabled: + + +To enable the Common Attachment Types Filter: 1. Navigate to Microsoft 365 Defender [https://security.microsoft.com](https://security.microsoft.com). 2. Click to expand **Email & collaboration** select **Policies & rules**. 3. On the Policies & rules page select **Threat policies**. 4. Under polices select **Anti-malware** and click on the **Default (Default)** policy. -5. On the policy page that appears on the righthand pane, under **Protection settings**, verify that the **Enable the common attachments filter** has the value of **On**. +5. On the Policy page that appears on the right hand pane scroll to the bottom and click on **Edit protection settings**, check the **Enable the common attachments filter**. +6. Click Save. #### Related links From 34ef3a9ee4c95a1b817bfec682eeeda1dfe14f79 Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 15:54:50 +1200 Subject: [PATCH 6/8] fixed page number --- powershell/public/cis/Test-MtCisAttachmentFilter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powershell/public/cis/Test-MtCisAttachmentFilter.md b/powershell/public/cis/Test-MtCisAttachmentFilter.md index dacfda49..e5c270aa 100644 --- a/powershell/public/cis/Test-MtCisAttachmentFilter.md +++ b/powershell/public/cis/Test-MtCisAttachmentFilter.md @@ -19,7 +19,7 @@ To enable the Common Attachment Types Filter: #### Related links * [Microsoft 365 Defender](https://security.microsoft.com) -* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 33](https://www.cisecurity.org/benchmark/microsoft_365) +* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 65](https://www.cisecurity.org/benchmark/microsoft_365) %TestResult% \ No newline at end of file From 6e0a967fc7e6c2ba3d711ae650b49402f145f624 Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 18:11:21 +1200 Subject: [PATCH 7/8] Added CIS 2.1.3 --- powershell/Maester.psd1 | 1 + .../public/cis/Test-MtCisAttachmentFilter.ps1 | 2 +- .../Test-MtCisInternalMalwareNotification.md | 23 ++++++ .../Test-MtCisInternalMalwareNotification.ps1 | 82 +++++++++++++++++++ ...MtCisInternalMalwareNotification.Tests.ps1 | 10 +++ website/docs/tests/cis/readme.md | 1 + 6 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 powershell/public/cis/Test-MtCisInternalMalwareNotification.md create mode 100644 powershell/public/cis/Test-MtCisInternalMalwareNotification.ps1 create mode 100644 tests/cis/Test-MtCisInternalMalwareNotification.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index adc5a862..0d77c268 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -140,6 +140,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisCustomerLockBox', 'Test-MtCisSafeLink', 'Test-MtCisAttachmentFilter', + 'Test-MtCisInternalMalwareNotification', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 b/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 index c0044368..985ad10e 100644 --- a/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 +++ b/powershell/public/cis/Test-MtCisAttachmentFilter.ps1 @@ -36,7 +36,7 @@ function Test-MtCisAttachmentFilter { Write-Verbose "Executing checks" $fileFilter = $policy | Where-Object { - $_.EnableFileFilter + $_.EnableFileFilter -match "True" } $testResult = ($fileFilter | Measure-Object).Count -ge 1 diff --git a/powershell/public/cis/Test-MtCisInternalMalwareNotification.md b/powershell/public/cis/Test-MtCisInternalMalwareNotification.md new file mode 100644 index 00000000..4b01bfb5 --- /dev/null +++ b/powershell/public/cis/Test-MtCisInternalMalwareNotification.md @@ -0,0 +1,23 @@ +2.1.3 (L1) Ensure notifications for internal users sending malware is Enabled + +**Rationale:** +This setting alerts administrators that an internal user sent a message that contained malware. This may indicate an account or machine compromise that would need to be investigated. + +#### Remediation action: + +To enable notifications for internal users sending malware: +1. Navigate to Microsoft 365 Defender [https://security.microsoft.com](https://security.microsoft.com). +2. Click to expand **E-mail & Collaboration** select **Policies & rules**. +3. On the Policies & rules page select **Threat policies**. +4. Under Policies select **Anti-malware**. +5. Click on the **Default (Default)** policy. +6. Click on **Edit protection settings** and change the settings for **Notify an admin about undelivered messages from internal senders** to **On** and enter the email address of the administrator who should be notified under **Administrator email address**. +7. Click Save. + +#### Related links + +* [Microsoft 365 Defender](https://security.microsoft.com) +* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 68](https://www.cisecurity.org/benchmark/microsoft_365) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cis/Test-MtCisInternalMalwareNotification.ps1 b/powershell/public/cis/Test-MtCisInternalMalwareNotification.ps1 new file mode 100644 index 00000000..432eedbb --- /dev/null +++ b/powershell/public/cis/Test-MtCisInternalMalwareNotification.ps1 @@ -0,0 +1,82 @@ +<# +.SYNOPSIS +Checks if notifications for internal users sending malware are enabled + +.DESCRIPTION +Notifications for internal users sending malware should be enabled, and an administrator email set + +.EXAMPLE +Test-MtCisInternalMalwareNotification + +Returns true safe malware notifcications are enabled, and an administrator email address is set + +.LINK +https://maester.dev/docs/commands/Test-MtCisInternalMalwareNotification +#> +function Test-MtCisInternalMalwareNotification { + [CmdletBinding()] + [OutputType([bool])] + param() + + 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 Mdo)) { + Add-MtTestResultDetail -SkippedBecause NotLicensedMdo + return $null + } + + Write-Verbose "Getting Malware Filter Policy..." + $policy = Get-MtExo -Request MalwareFilterPolicy + + Write-Verbose "Executing checks" + $enableInternalSenderAdminNotification = $policy | Where-Object { + $_.enableInternalSenderAdminNotifications -match "True" + } + + $internalSenderAdminAddress = $policy | Where-Object { + $null -ne $_.InternalSenderAdminAddress + } + + $testResult = (($enableInternalSenderAdminNotification | Measure-Object).Count -ge 1) -and (($internalSenderAdminAddress | Measure-Object).Count -ge 1) + + $portalLink = "https://security.microsoft.com/antimalwarev2" + + if ($testResult) { + $testResultMarkdown = "Well done. Your tenant has the recommended internal malware notifications configured ($portalLink).`n`n%TestResult%" + } + else { + $testResultMarkdown = "Your tenant does not have the recommended internal malware notifications configured ($portalLink).`n`n%TestResult%" + } + + $resultMd = "| Policy | Result |`n" + $resultMd += "| --- | --- |`n" + + if ($enableInternalSenderAdminNotification) { + $enableInternalSenderAdminNotificationResult = "✅ Pass" + } + else { + $enableInternalSenderAdminNotificationResult = "❌ Fail" + } + + if ($internalSenderAdminAddress) { + $internalSenderAdminAddressResult = "✅ Pass" + } + else { + $internalSenderAdminAddressResult = "❌ Fail" + } + + $resultMd += "| EnableInternalSenderAdminNotification | $enableInternalSenderAdminNotificationResult |`n" + $resultMd += "| InternalSenderAdminAddress | $internalSenderAdminAddressResult |`n" + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $resultMd + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cis/Test-MtCisInternalMalwareNotification.Tests.ps1 b/tests/cis/Test-MtCisInternalMalwareNotification.Tests.ps1 new file mode 100644 index 00000000..fe79f5d1 --- /dev/null +++ b/tests/cis/Test-MtCisInternalMalwareNotification.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CIS" -Tag "CIS 2.1.3", "L1", "CIS E3 Level 1", "CIS E3", "CIS", "Security", "All", "CIS M365 v3.1.0" { + It "2.1.3 (L1) Ensure notifications for internal users sending malware is Enabled" { + + $result = Test-MtCisInternalMalwareNotification + + if ($null -ne $result) { + $result | Should -Be $true -Because "internal malware notifications are enabled." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cis/readme.md b/website/docs/tests/cis/readme.md index a1714511..9bfa6625 100644 --- a/website/docs/tests/cis/readme.md +++ b/website/docs/tests/cis/readme.md @@ -39,5 +39,6 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | TBD | 1.3.8 (L2) Ensure that Sways cannot be shared with people outside of your organization | | Test-MtCisSafeLink | 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled | | Test-MtCisAttachmentFilter | 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled | +| Test-MtCisInternalMalwareNotification | 2.1.3 (L1) Ensure notifications for internal users sending malware is Enabled | TBD in this case refers to CIS "manual" checks. It might be possible to automate these, but skipping for now to focus on automated checks. \ No newline at end of file From f57df8fe3eafecad5d9532fef92b24e3c20a75ef Mon Sep 17 00:00:00 2001 From: NZLostboy Date: Sun, 22 Sep 2024 18:48:55 +1200 Subject: [PATCH 8/8] CIS 2.1.4 --- powershell/Maester.psd1 | 1 + .../public/cis/Test-MtCisSafeAttachment.md | 27 ++++++ .../public/cis/Test-MtCisSafeAttachment.ps1 | 97 +++++++++++++++++++ tests/cis/Test-MtCisSafeAttachment.Tests.ps1 | 10 ++ website/docs/tests/cis/readme.md | 3 +- 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 powershell/public/cis/Test-MtCisSafeAttachment.md create mode 100644 powershell/public/cis/Test-MtCisSafeAttachment.ps1 create mode 100644 tests/cis/Test-MtCisSafeAttachment.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index 0d77c268..246fe22d 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -141,6 +141,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae 'Test-MtCisSafeLink', 'Test-MtCisAttachmentFilter', 'Test-MtCisInternalMalwareNotification', + 'Test-MtCisSafeAttachment', 'Test-MtConditionalAccessWhatIf', 'Test-MtConnection', 'Test-MtEidscaControl', diff --git a/powershell/public/cis/Test-MtCisSafeAttachment.md b/powershell/public/cis/Test-MtCisSafeAttachment.md new file mode 100644 index 00000000..c647ec75 --- /dev/null +++ b/powershell/public/cis/Test-MtCisSafeAttachment.md @@ -0,0 +1,27 @@ +2.1.4 (L2) Ensure Safe Attachments policy is enabled + +R**ationale:** +Enabling Safe Attachments policy helps protect against malware threats in email attachments by analyzing suspicious attachments in a secure, cloud-based environment before they are delivered to the user's inbox. This provides an additional layer of security and can prevent new or unseen types of malware from infiltrating the organization's network. + +#### Remediation action: + +To enable the Safe Attachments policy: +1. Navigate to Microsoft 365 Defender [https://security.microsoft.com](https://security.microsoft.com). +2. Click to expand **E-mail & Collaboration** select **Policies & rules**. +3. On the Policies & rules page select **Threat policies**. +4. Under **Policies** select **Safe Attachments**. +5. Click + **Create**. +6. Create a Policy Name and Description, and then click **Next**. +7. Select all valid domains and click Next. +8. Select **Block**. +9. Quarantine policy is **AdminOnlyAccessPolicy**. +10. Leave **Enable redirect** unchecked. +11. Click **Next** and finally **Submit**. + +#### Related links + +* [Microsoft 365 Defender](https://security.microsoft.com) +* [CIS Microsoft 365 Foundations Benchmark v3.1.0 - Page 71](https://www.cisecurity.org/benchmark/microsoft_365) + + +%TestResult% \ No newline at end of file diff --git a/powershell/public/cis/Test-MtCisSafeAttachment.ps1 b/powershell/public/cis/Test-MtCisSafeAttachment.ps1 new file mode 100644 index 00000000..2b5605f6 --- /dev/null +++ b/powershell/public/cis/Test-MtCisSafeAttachment.ps1 @@ -0,0 +1,97 @@ +<# +.SYNOPSIS +Checks if the Safe Attachments policy is enabled + +.DESCRIPTION +The Safe Attachments policy is enabled + +.EXAMPLE +Test-MtCisSafeAttachment + +Returns true safe attachments policy is enabled + +.LINK +https://maester.dev/docs/commands/Test-MtCisSafeAttachment +#> +function Test-MtCisSafeAttachment { + [CmdletBinding()] + [OutputType([bool])] + param() + + 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 Mdo)) { + Add-MtTestResultDetail -SkippedBecause NotLicensedMdo + return $null + } + + Write-Verbose "Getting Safe Attachment Policy..." + $policy = Get-MtExo -Request SafeAttachmentPolicy + + $safeAttachmentCheckList = @() + + #Enable + $safeAttachmentCheckList += [pscustomobject] @{ + "CheckName" = "Enable" + "Value" = "True" + } + + #Action + $safeAttachmentCheckList += [pscustomobject] @{ + "CheckName" = "Action" + "Value" = "Block" + } + + #QuarantineTag + $safeAttachmentCheckList += [pscustomobject] @{ + "CheckName" = "QuarantineTag" + "Value" = "AdminOnlyAccessPolicy" + } + + Write-Verbose "Executing checks" + $failedCheckList = @() + foreach ($check in $safeAttachmentCheckList) { + + $checkResult = $policy | Where-Object { $_.($check.CheckName) -notmatch $check.Value } + + if ($checkResult) { + #If the check fails, add it to the list so we can report on it later + $failedCheckList += $check.CheckName + } + + } + + $testResult = ($failedCheckList | Measure-Object).Count -eq 0 + + $portalLink = "https://security.microsoft.com/safeattachmentv2" + + if ($testResult) { + $testResultMarkdown = "Well done. Your tenant has the safe attachment policy enabled ($portalLink).`n`n%TestResult%" + } + else { + $testResultMarkdown = "Your tenant does not have the the safe attachment policy enabled ($portalLink).`n`n%TestResult%" + } + + + $resultMd = "| Check Name | Result |`n" + $resultMd += "| --- | --- |`n" + foreach ($item in $safeAttachmentCheckList) { + $itemResult = "❌ Fail" + if ($item.CheckName -notin $failedCheckList) { + $itemResult = "✅ Pass" + } + $resultMd += "| $($item.CheckName) | $($itemResult) |`n" + } + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $resultMd + + Add-MtTestResultDetail -Result $testResultMarkdown + + return $testResult +} \ No newline at end of file diff --git a/tests/cis/Test-MtCisSafeAttachment.Tests.ps1 b/tests/cis/Test-MtCisSafeAttachment.Tests.ps1 new file mode 100644 index 00000000..b480e5ec --- /dev/null +++ b/tests/cis/Test-MtCisSafeAttachment.Tests.ps1 @@ -0,0 +1,10 @@ +Describe "CIS" -Tag "CIS 2.1.4", "L2", "CIS E5 Level 5", "CIS E5", "CIS", "Security", "All", "CIS M365 v3.1.0" { + It "2.1.4 (L2) Ensure Safe Attachments policy is enabled" { + + $result = Test-MtCisSafeAttachment + + if ($null -ne $result) { + $result | Should -Be $true -Because "the Safe Attachement policy is enabled." + } + } +} \ No newline at end of file diff --git a/website/docs/tests/cis/readme.md b/website/docs/tests/cis/readme.md index 9bfa6625..4e23a5fa 100644 --- a/website/docs/tests/cis/readme.md +++ b/website/docs/tests/cis/readme.md @@ -23,7 +23,7 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | Cmdlet Name | CIS Recommendation ID | | - | - | -| Test-MtCisCloudAdmin | CIS 1.1.1: Ensure Administrative accounts are separate and cloud-only | +| Test-MtCisCloudAdmin | 1.1.1 (L1) Ensure Administrative accounts are separate and cloud-only | | TBD | 1.1.2 (L1) Ensure two emergency access accounts have been defined | | Test-MtCisGlobalAdminCount | 1.1.3 (L1) Ensure that between two and four global admins are designated | | N/A | 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly | @@ -40,5 +40,6 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions | Test-MtCisSafeLink | 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled | | Test-MtCisAttachmentFilter | 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled | | Test-MtCisInternalMalwareNotification | 2.1.3 (L1) Ensure notifications for internal users sending malware is Enabled | +| Test-MtCisSafeAttachment | 2.1.4 (L2) Ensure Safe Attachments policy is enabled | TBD in this case refers to CIS "manual" checks. It might be possible to automate these, but skipping for now to focus on automated checks. \ No newline at end of file