From 13b541f0c5bdc36df57e4f5a7d887a4fa3ad8d45 Mon Sep 17 00:00:00 2001 From: Lukas Sassl Date: Mon, 29 Aug 2022 18:32:01 +0200 Subject: [PATCH] Adjustments to check for IP Filtering --- ...rSecurityExtendedProtectionConfigState.ps1 | 84 +- .../Tests/HealthChecker.E16.Tests.ps1 | 2 +- .../Get-ExtendedProtectionConfiguration.ps1 | 18 + ...Configured_IPFilter_ApplicationHost.config | 2466 ++++++++++++++++ ...Configured_IPFilter_ApplicationHost.config | 2467 +++++++++++++++++ ...-ExtendedProtectionConfiguration.Tests.ps1 | 83 +- .../ExchangeExtendedProtectionManagement.ps1 | 21 +- 7 files changed, 5112 insertions(+), 29 deletions(-) create mode 100644 Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E16_Configured_IPFilter_ApplicationHost.config create mode 100644 Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E19_Configured_IPFilter_ApplicationHost.config diff --git a/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1 b/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1 index cb1de9a2ed..5389ffd45b 100644 --- a/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1 +++ b/Diagnostics/HealthChecker/Analyzer/Security/Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1 @@ -34,7 +34,7 @@ function Invoke-AnalyzerSecurityExtendedProtectionConfigState { # Fix: Install Aug 2022 SU & enable extended protection # Extended protection is available with IIS 7.5 or higher Write-Verbose "Testing CVE: CVE-2022-24516, CVE-2022-21979, CVE-2022-21980, CVE-2022-24477, CVE-2022-30134" - if (($extendedProtection.ExtendedProtectionConfiguration.SupportedExtendedProtection.Contains($false)) -or + if (($extendedProtection.ExtendedProtectionConfiguration.ProperlySecuredConfiguration.Contains($false)) -or ($extendedProtection.SupportedVersionForExtendedProtection -eq $false)) { Write-Verbose "At least one vDir is not configured properly and so, the system may be at risk" if (($extendedProtection.ExtendedProtectionConfiguration.SupportedExtendedProtection.Contains($false)) -and @@ -42,17 +42,28 @@ function Invoke-AnalyzerSecurityExtendedProtectionConfigState { # This combination means that EP is configured for at least one vDir, but the Exchange build doesn't support it. # Such a combination can break several things like mailbox access, EMS... . # Recommended action: Disable EP, upgrade to a supported build (Aug 2022 SU+) and enable afterwards. - $epDetails = "Extended Protection is configured, but not supported on this Exchange Server build." + $epDetails = "Extended Protection is configured, but not supported on this Exchange Server build" } elseif ((-not($extendedProtection.ExtendedProtectionConfiguration.SupportedExtendedProtection.Contains($false))) -and ($extendedProtection.SupportedVersionForExtendedProtection -eq $false)) { # This combination means that EP is not configured and the Exchange build doesn't support it. # Recommended action: Upgrade to a supported build (Aug 2022 SU+) and enable EP afterwards. - $epDetails = "Your Exchange server is at risk. Install the latest SU and enable Extended Protection." + $epDetails = "Your Exchange server is at risk. Install the latest SU and enable Extended Protection" } else { + if ($extendedProtection.ExtendedProtectionConfiguration | Where-Object { + (($_.MitigationEnabled) -and + ($_.ProperlySecuredConfiguration -eq $false)) + }) { + # This means that EP is supported and configured. On at least 1 vDir is IP filtering configured to mitigate known issues with Extended Protection. + # We've detected that EP was not set to "None" on the vDir for which the IP filtering was turned on. This can cause issues. + # Recommended action: Set EP to "None" on the vDir where IP filtering is enabled and was configured. + $epDetails = "Extended Protection should be set to 'None' on the vDir where IP filtering is enabled`n`t`t" + } + # This means that EP is supported but not configured for at least one vDir. # Recommended action: Enable EP for each vDir on the system by using the script provided by us. - $epDetails = "Extended Protection should be configured." + $epDetails += "Extended Protection isn't configured as expected" } + $epCveParams = $baseParams + @{ Name = "Security Vulnerability" Details = "CVE-2022-24516, CVE-2022-21979, CVE-2022-21980, CVE-2022-24477, CVE-2022-30134" @@ -61,24 +72,41 @@ function Invoke-AnalyzerSecurityExtendedProtectionConfigState { $epBasicParams = $baseParams + @{ DisplayWriteType = "Red" DisplayCustomTabNumber = 2 - Details = "$epDetails Current config:" + Details = "$epDetails" } Add-AnalyzedResultInformation @epCveParams Add-AnalyzedResultInformation @epBasicParams - $epOutputObjectDisplayValue = New-Object 'System.Collections.Generic.List[object]' + $epFrontEndOutputObjectDisplayValue = New-Object 'System.Collections.Generic.List[object]' + $epBackEndOutputObjectDisplayValue = New-Object 'System.Collections.Generic.List[object]' + $mitigationOutputObjectDisplayValue = New-Object 'System.Collections.Generic.List[object]' + foreach ($entry in $extendedProtection.ExtendedProtectionConfiguration) { + $vDirArray = $entry.VirtualDirectoryName.Split("/", 2) $ssl = $entry.Configuration.SslSettings - $epOutputObjectDisplayValue.Add(([PSCustomObject]@{ - VirtualDirectory = $entry.VirtualDirectoryName + $listToAdd = $epFrontEndOutputObjectDisplayValue + if ($vDirArray[0] -eq "Exchange Back End") { + $listToAdd = $epBackEndOutputObjectDisplayValue + } + + $listToAdd.Add(([PSCustomObject]@{ + $vDirArray[0] = $vDirArray[1] Value = $entry.ExtendedProtection - SupportedValue = $entry.ExpectedExtendedConfiguration - ConfigSupported = $entry.SupportedExtendedProtection + SupportedValue = if ($entry.MitigationEnabled) { "None" } else { $entry.ExpectedExtendedConfiguration } + ConfigSupported = $entry.ProperlySecuredConfiguration RequireSSL = "$($ssl.RequireSSL) $(if($ssl.Ssl128Bit) { "(128-bit)" })".Trim() ClientCertificate = $ssl.ClientCertificate + IPFilterEnabled = $entry.MitigationEnabled }) ) + + if ($entry.MitigationEnabled) { + $mitigationOutputObjectDisplayValue.Add([PSCustomObject]@{ + VirtualDirectory = $entry.VirtualDirectoryName + Details = $entry.Configuration.MitigationSettings.Restrictions + }) + } } $epConfig = { @@ -89,23 +117,51 @@ function Invoke-AnalyzerSecurityExtendedProtectionConfigState { } else { "Green" } + } elseif ($p -eq "IPFilterEnabled") { + if ($o.$p -eq $true) { + "Green" + } } } - $epParams = $baseParams + @{ + $epFrontEndParams = $baseParams + @{ + Name = "Security Vulnerability" + OutColumns = ([PSCustomObject]@{ + DisplayObject = $epFrontEndOutputObjectDisplayValue + ColorizerFunctions = @($epConfig) + IndentSpaces = 8 + }) + DisplayTestingValue = "CVE-2022-24516, CVE-2022-21979, CVE-2022-21980, CVE-2022-24477, CVE-2022-30134" + } + + $epBackEndParams = $baseParams + @{ Name = "Security Vulnerability" OutColumns = ([PSCustomObject]@{ - DisplayObject = $epOutputObjectDisplayValue + DisplayObject = $epBackEndOutputObjectDisplayValue ColorizerFunctions = @($epConfig) IndentSpaces = 8 }) DisplayTestingValue = "CVE-2022-24516, CVE-2022-21979, CVE-2022-21980, CVE-2022-24477, CVE-2022-30134" } - Add-AnalyzedResultInformation @epParams + + Add-AnalyzedResultInformation @epFrontEndParams + Add-AnalyzedResultInformation @epBackEndParams + if ($mitigationOutputObjectDisplayValue.Count -ge 1) { + foreach ($mitigation in $mitigationOutputObjectDisplayValue) { + $epMitigationvDir = $baseParams + @{ + Details = "$($mitigation.Details.Count) IPs in filter list on vDir: '$($mitigation.VirtualDirectory)'" + DisplayWriteType = "Yellow" + } + Add-AnalyzedResultInformation @epMitigationvDir + $mitigationOutputObjectDisplayValue.Details.GetEnumerator() | ForEach-Object { + Write-Verbose "IP Address: $($_.key) is allowed to connect? $($_.value)" + } + } + } $moreInformationParams = $baseParams + @{ DisplayWriteType = "Red" - Details = "For more information about Extended Protection and how to configure, please read this article: https://aka.ms/HC-ExchangeEPDoc" + Details = "For more information about Extended Protection and how to configure, please read this article:`n`thttps://aka.ms/HC-ExchangeEPDoc" } Add-AnalyzedResultInformation @moreInformationParams } else { diff --git a/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Tests.ps1 b/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Tests.ps1 index 8dcf052a2d..2a63cc9798 100644 --- a/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Tests.ps1 +++ b/Diagnostics/HealthChecker/Tests/HealthChecker.E16.Tests.ps1 @@ -135,7 +135,7 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2016" { $downlaodDomains = GetObject "CVE-2021-1730" $downlaodDomains.DownloadDomainsEnabled | Should -Be "false" - $Script:ActiveGrouping.Count | Should -Be 20 + $Script:ActiveGrouping.Count | Should -Be 21 } } diff --git a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Get-ExtendedProtectionConfiguration.ps1 b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Get-ExtendedProtectionConfiguration.ps1 index 25e122843d..29b20cdceb 100644 --- a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Get-ExtendedProtectionConfiguration.ps1 +++ b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Get-ExtendedProtectionConfiguration.ps1 @@ -110,6 +110,7 @@ function Get-ExtendedProtectionConfiguration { try { $nodePath = [string]::Empty $extendedProtection = "None" + $ipRestictionsHashTable = @{} $pathIndex = [array]::IndexOf(($Xml.configuration.location.path).ToLower(), $Path.ToLower()) $rootIndex = [array]::IndexOf(($Xml.configuration.location.path).ToLower(), ($Path.Split("/")[0]).ToLower()) @@ -117,6 +118,7 @@ function Get-ExtendedProtectionConfiguration { $configNode = $Xml.configuration.location[$pathIndex] $nodePath = $configNode.Path $ep = $configNode.'system.webServer'.security.authentication.windowsAuthentication.extendedProtection.tokenChecking + $ipRestrictions = $configNode.'system.webServer'.security.ipSecurity if (-not ([string]::IsNullOrEmpty($ep))) { Write-Verbose "Found tokenChecking: $ep" @@ -137,6 +139,13 @@ function Get-ExtendedProtectionConfiguration { } } + if (-not([string]::IsNullOrEmpty($ipRestrictions))) { + Write-Verbose "IP-filtered restrictions detected" + foreach ($restriction in $ipRestrictions.add) { + $ipRestictionsHashTable.Add($restriction.ipAddress, $restriction.allowed) + } + } + Write-Verbose "SSLSettings: $sslSettings" if ($null -ne $sslSettings) { @@ -181,6 +190,10 @@ function Get-ExtendedProtectionConfiguration { ClientCertificate = $clientCertificate Value = $sslSettings } + MitigationSettings = [PScustomObject]@{ + AllowUnlisted = $ipRestrictions.allowUnlisted + Restrictions = $ipRestictionsHashTable + } } } } @@ -323,6 +336,11 @@ function Get-ExtendedProtectionConfiguration { ExtendedProtection = $extendedConfiguration.ExtendedProtection SupportedExtendedProtection = $expectedExtendedConfiguration -eq $extendedConfiguration.ExtendedProtection ExpectedExtendedConfiguration = $expectedExtendedConfiguration + MitigationEnabled = ($extendedConfiguration.MitigationSettings.AllowUnlisted -eq $false) + ProperlySecuredConfiguration = ((($extendedConfiguration.MitigationSettings.AllowUnlisted -eq $false) -and + ($extendedConfiguration.ExtendedProtection -eq "None")) -or + (($extendedConfiguration.MitigationSettings.AllowUnlisted -ne $false) -and + ($expectedExtendedConfiguration -eq $extendedConfiguration.ExtendedProtection))) ExpectedSslFlags = $matchEntry.SslFlags SslFlagsSetCorrectly = $sslFlagsToSet.Split(",").Count -eq $currentSetFlags.Count SslFlagsToSet = $sslFlagsToSet diff --git a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E16_Configured_IPFilter_ApplicationHost.config b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E16_Configured_IPFilter_ApplicationHost.config new file mode 100644 index 0000000000..99de2088d0 --- /dev/null +++ b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E16_Configured_IPFilter_ApplicationHost.config @@ -0,0 +1,2466 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E19_Configured_IPFilter_ApplicationHost.config b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E19_Configured_IPFilter_ApplicationHost.config new file mode 100644 index 0000000000..a39084f284 --- /dev/null +++ b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Data/E19_Configured_IPFilter_ApplicationHost.config @@ -0,0 +1,2467 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Get-ExtendedProtectionConfiguration.Tests.ps1 b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Get-ExtendedProtectionConfiguration.Tests.ps1 index 0858ea810e..7893885337 100644 --- a/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Get-ExtendedProtectionConfiguration.Tests.ps1 +++ b/Security/src/ExchangeExtendedProtectionManagement/DataCollection/Tests/Get-ExtendedProtectionConfiguration.Tests.ps1 @@ -51,8 +51,12 @@ BeforeAll { param( [object]$TestingExtendedProtectionResults, [int]$ExtendedProtectionNoneCount = 21, + [int]$ExpectedExtendedProtectionNoneCount = 21, [bool]$SkipAllow = $false, - [bool]$SkipAutoDiscover = $false + [bool]$SkipAutoDiscover = $false, + [bool]$IPFilterEnabled = $false, + [string]$IPFilteredvDir = $null, + [string[]]$AllowedIpAddresses ) $TestingExtendedProtectionResults.SupportedVersionForExtendedProtection | Should -Be $true @@ -61,10 +65,16 @@ BeforeAll { Should -Be $ExtendedProtectionNoneCount ($TestingExtendedProtectionResults.ExtendedProtectionConfiguration | Where-Object { $_.ExpectedExtendedConfiguration -ne "None" }).count | - Should -Be $ExtendedProtectionNoneCount - $TestingExtendedProtectionResults.ExtendedProtectionConfiguration | - Where-Object { $_.SupportedExtendedProtection -eq $false } | - Should -Be $null + Should -Be $ExpectedExtendedProtectionNoneCount + if ($IPFilterEnabled -eq $false) { + $TestingExtendedProtectionResults.ExtendedProtectionConfiguration | + Where-Object { $_.SupportedExtendedProtection -eq $false } | + Should -Be $null + } else { + ($TestingExtendedProtectionResults.ExtendedProtectionConfiguration | + Where-Object { $_.SupportedExtendedProtection -eq $false }).Count | + Should -Be 1 + } # Special configs if (-not $SkipAllow) { $allow = $TestingExtendedProtectionResults.ExtendedProtectionConfiguration | @@ -83,6 +93,21 @@ BeforeAll { $none.Configuration.NodePath.Contains("Default Web Site/Autodiscover") | Should -Be $true $none.Configuration.NodePath.Contains("Exchange Back End/Autodiscover") | Should -Be $true } + + if ($IPFilterEnabled) { + $ipFilter = $TestingExtendedProtectionResults.ExtendedProtectionConfiguration | + Where-Object { + ($_.ExtendedProtection -eq "None") -and + ($_.VirtualDirectoryName -eq $IPFilteredvDir) + } + $ipFilter.MitigationEnabled | Should -Be $true + $ipFilter.ProperlySecuredConfiguration | Should -Be $true + $ipFilter.Configuration.MitigationSettings.AllowUnlisted | Should -Be "false" + $ipFilter.Configuration.MitigationSettings.Restrictions.keys.Count | Should -Be $AllowedIpAddresses.Count + ($ipFilter.Configuration.MitigationSettings.Restrictions.GetEnumerator() | + Where-Object { $_.key -in $AllowedIpAddresses }).Count | Should -Be $AllowedIpAddresses.Count + $ipFilter.Configuration.MitigationSettings.Restrictions.values | Should -Not -Contain "false" + } } $Script:E15_NotConfigured_Both_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E15_NotConfigured_Both_ApplicationHost.config @@ -95,7 +120,9 @@ BeforeAll { $Script:E15_Configured_Cas_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E15_Configured_Cas_ApplicationHost.config $Script:E15_Configured_Mbx_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E15_Configured_Mbx_ApplicationHost.config $Script:E16_Configured_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E16_Configured_ApplicationHost.config + $Script:E16_Configured_IPFilter_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E16_Configured_IPFilter_ApplicationHost.config $Script:E19_Configured_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E19_Configured_ApplicationHost.config + $Script:E19_Configured_IPFilter_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E19_Configured_IPFilter_ApplicationHost.config $Script:E19_MisConfigured_ApplicationHost = LoadApplicationHostConfig -Path $Script:parentPath\Tests\Data\E19_MisConfigured_ApplicationHost.config } @@ -185,7 +212,7 @@ Describe "Testing Get-ExtendedProtectionConfiguration.ps1" { ExSetupVersion = "15.00.1497.038" ApplicationHostConfig = $E15_Configured_Both_ApplicationHost } - TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 19 + TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 19 -ExpectedExtendedProtectionNoneCount 19 } It "Exchange 2013 Cas" { @@ -195,7 +222,7 @@ Describe "Testing Get-ExtendedProtectionConfiguration.ps1" { IsMailboxServer = $false ApplicationHostConfig = $E15_Configured_Cas_ApplicationHost } - TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 9 -SkipAutoDiscover $true + TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 9 -ExpectedExtendedProtectionNoneCount 9 -SkipAutoDiscover $true } It "Exchange 2013 Mbx" { @@ -205,7 +232,7 @@ Describe "Testing Get-ExtendedProtectionConfiguration.ps1" { IsClientAccessServer = $false ApplicationHostConfig = $E15_Configured_Mbx_ApplicationHost } - TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 12 -SkipAllow $true -SkipAutoDiscover $true + TestSupportedConfiguredExtendedProtection -TestingExtendedProtectionResults (Get-ExtendedProtectionConfiguration @mockParams) -ExtendedProtectionNoneCount 12 -ExpectedExtendedProtectionNoneCount 12 -SkipAllow $true -SkipAutoDiscover $true } It "Exchange 2016" { @@ -227,6 +254,46 @@ Describe "Testing Get-ExtendedProtectionConfiguration.ps1" { } } + Context "Extended Protection Is Configured On Supported Exchange Version And IP Filter Is Configured" { + It "Exchange 2016 - IPs filtered: Exchange Back End/EWS" { + $epMockParams = @{ + ComputerName = $Server + ExSetupVersion = "15.2.1118.29" + ApplicationHostConfig = $E16_Configured_IPFilter_ApplicationHost + } + $e16ExtendedProtectionResults = Get-ExtendedProtectionConfiguration @epMockParams + + $mockParams = @{ + TestingExtendedProtectionResults = $e16ExtendedProtectionResults + ExtendedProtectionNoneCount = 20 + SkipAutoDiscover = $true + IPFilterEnabled = $true + IPFilteredvDir = "Exchange Back End/EWS" + AllowedIpAddresses = "192.168.100.5", "fe80::de2:4f45:21dc:6c5a%14", "::1", "127.0.0.1" + } + TestSupportedConfiguredExtendedProtection @mockParams + } + + It "Exchange 2019 - IPs filtered: Exchange Back End/EWS" { + $epMockParams = @{ + ComputerName = $Server + ExSetupVersion = "15.2.1118.29" + ApplicationHostConfig = $E19_Configured_IPFilter_ApplicationHost + } + $e19ExtendedProtectionResults = Get-ExtendedProtectionConfiguration @epMockParams + + $mockParams = @{ + TestingExtendedProtectionResults = $e19ExtendedProtectionResults + ExtendedProtectionNoneCount = 20 + SkipAutoDiscover = $true + IPFilterEnabled = $true + IPFilteredvDir = "Exchange Back End/EWS" + AllowedIpAddresses = "192.168.100.5", "fe80::de2:4f45:21dc:6c5a%14", "::1", "127.0.0.1" + } + TestSupportedConfiguredExtendedProtection @mockParams + } + } + Context "Supported/Unsupported Versions Tests" { BeforeAll { function TestVersionSupportedOnly { diff --git a/Security/src/ExchangeExtendedProtectionManagement/ExchangeExtendedProtectionManagement.ps1 b/Security/src/ExchangeExtendedProtectionManagement/ExchangeExtendedProtectionManagement.ps1 index a4d337700c..85a678e35f 100644 --- a/Security/src/ExchangeExtendedProtectionManagement/ExchangeExtendedProtectionManagement.ps1 +++ b/Security/src/ExchangeExtendedProtectionManagement/ExchangeExtendedProtectionManagement.ps1 @@ -294,22 +294,31 @@ begin { foreach ($configuration in $extendedProtectionConfigurations) { Write-Verbose "Working on server $($configuration.ComputerName)" - $epOutputObjectDisplayValue = New-Object 'System.Collections.Generic.List[object]' + $epFrontEndList = New-Object 'System.Collections.Generic.List[object]' + $epBackEndList = New-Object 'System.Collections.Generic.List[object]' foreach ($entry in $configuration.ExtendedProtectionConfiguration) { + $vDirArray = $entry.VirtualDirectoryName.Split("/", 2) $ssl = $entry.Configuration.SslSettings - $epOutputObjectDisplayValue.Add(([PSCustomObject]@{ - VirtualDirectory = $entry.VirtualDirectoryName + $listToAdd = $epFrontEndList + if ($vDirArray[0] -eq "Exchange Back End") { + $listToAdd = $epBackEndList + } + + $listToAdd.Add(([PSCustomObject]@{ + $vDirArray[0] = $vDirArray[1] Value = $entry.ExtendedProtection - SupportedValue = $entry.ExpectedExtendedConfiguration - ConfigSupported = $entry.SupportedExtendedProtection + SupportedValue = if ($entry.MitigationEnabled) { "None" } else { $entry.ExpectedExtendedConfiguration } + ConfigSupported = $entry.ProperlySecuredConfiguration RequireSSL = "$($ssl.RequireSSL) $(if($ssl.Ssl128Bit) { "(128-bit)" })".Trim() ClientCertificate = $ssl.ClientCertificate + IPFilterEnabled = $entry.MitigationEnabled })) } Write-Host "Results for Server: $($configuration.ComputerName)" - $epOutputObjectDisplayValue | Format-Table | Out-String | Write-Host + $epFrontEndList | Format-Table | Out-String | Write-Host + $epBackEndList | Format-Table | Out-String | Write-Host Write-Host "" Write-Host "" }