Skip to content

Commit

Permalink
Merge pull request #2037 from microsoft/MarchSU
Browse files Browse the repository at this point in the history
March 2024 SU Release
  • Loading branch information
dpaulson45 committed Mar 12, 2024
2 parents e480d3f + 0d73dc1 commit 4e87975
Show file tree
Hide file tree
Showing 37 changed files with 1,476 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .build/cspell-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,15 @@ unconfigured
unrequired
USERDNSDOMAIN
Vianet
Visio
vmxnet
vssadmin
vsstester
Vssx
vuln
wbxml
Webex
Weve
wevtutil
windir
Xlsb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

. $PSScriptRoot\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\Get-DisplayResultsGroupingKey.ps1
. $PSScriptRoot\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerFrequentConfigurationIssues {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,20 @@ function Invoke-AnalyzerKnownBuildIssues {
InformationUrl = (GetKnownIssueInformation @infoParams)
}
TestForKnownBuildIssues @params

Write-Verbose "Work on March 2024 Security Updates"
$infoParams = @{
Name = "Known Issues with Mar 2024 Security Updates"
Url = "https://support.microsoft.com/help/5037171"
}
$params = @{
CurrentVersion = $currentVersion
KnownBuildIssuesToFixes = @((GetKnownIssueBuildInformation "15.2.1544.9" $null),
(GetKnownIssueBuildInformation "15.2.1258.32" $null),
(GetKnownIssueBuildInformation "15.1.2507.37", $null))
InformationUrl = (GetKnownIssueInformation @infoParams)
}
TestForKnownBuildIssues @params
} catch {
Write-Verbose "Failed to run TestForKnownBuildIssues"
Invoke-CatchActions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

. $PSScriptRoot\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\Get-DisplayResultsGroupingKey.ps1
. $PSScriptRoot\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\Shared\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\Shared\VisualCRedistributableVersionFunctions.ps1
. $PSScriptRoot\..\..\..\Shared\Get-NETFrameworkVersion.ps1
function Invoke-AnalyzerOsInformation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\Get-FilteredSettingOverrideInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
# Used to determine the state of the Serialized Data Signing on the server.
function Get-SerializedDataSigningState {
[CmdletBinding()]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1

<#
.DESCRIPTION
Check for ADV24199947 Outside In Module vulnerability
Must be on March 2024 SU and no overrides in place to be considered secure.
Overrides are found in the Configuration.xml file with appending flag of |NO
This only needs to occur on the Mailbox Servers Roles
#>
function Invoke-AnalyzerSecurityADV24199947 {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ref]$AnalyzeResults,

[Parameter(Mandatory = $true)]
[object]$SecurityObject,

[Parameter(Mandatory = $true)]
[object]$DisplayGroupingKey
)
process {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"

$params = @{
AnalyzedInformation = $AnalyzeResults
DisplayGroupingKey = $DisplayGroupingKey
Name = "Security Vulnerability"
DisplayWriteType = "Red"
Details = "{0}"
DisplayTestingValue = "ADV24199947"
}

if ($SecurityObject.IsEdgeServer) {
Write-Verbose "Skipping over test as this is an edge server."
return
}

$isVulnerable = (-not (Test-ExchangeBuildGreaterOrEqualThanSecurityPatch -CurrentExchangeBuild $SecurityObject.BuildInformation -SUName "Mar24SU"))

# if patch is installed, need to check for the override.
if ($isVulnerable -eq $false) {
Write-Verbose "Mar24SU is installed, checking to see if override is set"
# Key for the file content information
$key = [System.IO.Path]::Combine($SecurityObject.ExchangeInformation.RegistryValues.FipFsDatabasePath, "Configuration.xml")
$unknownError = [string]::IsNullOrEmpty($SecurityObject.ExchangeInformation.RegistryValues.FipFsDatabasePath) -or
($null -eq $SecurityObject.ExchangeInformation.FileContentInformation[$key])

if ($unknownError) {
$params.Details += " Unable to determine if override is set due to no data to review."
$params.DisplayWriteType = "Yellow"
$isVulnerable = $true
} else {
$isVulnerable = $null -ne ($SecurityObject.ExchangeInformation.FileContentInformation[$key] | Select-String "\|NO")
}
}

if ($isVulnerable) {
$params.Details = ("$($params.Details)`r`n`t`tSee: https://portal.msrc.microsoft.com/security-guidance/advisory/{0} for more information." -f "ADV24199947")
Add-AnalyzedResultInformation @params
} else {
Write-Verbose "Not vulnerable to ADV24199947"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
. $PSScriptRoot\..\Get-FilteredSettingOverrideInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1

function Invoke-AnalyzerSecurityAMSIConfigState {
[CmdletBinding()]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityCve-2021-1730 {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityCve-2021-34470 {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityCve-MarchSuSpecial {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\Invoke-AnalyzerSecurityADV24199947.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2020-0796.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2020-1147.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2021-1730.ps1
Expand All @@ -12,7 +13,7 @@
. $PSScriptRoot\Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityIISModules.ps1
. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityCveCheck {
[CmdletBinding()]
param(
Expand Down Expand Up @@ -132,6 +133,7 @@ function Invoke-AnalyzerSecurityCveCheck {
"Aug23SU" = (NewCveEntry @("CVE-2023-38181", "CVE-2023-38182", "CVE-2023-38185", "CVE-2023-35368", "CVE-2023-35388", "CVE-2023-36777", "CVE-2023-36757", "CVE-2023-36756", "CVE-2023-36745", "CVE-2023-36744") @($ex2016, $ex2019))
"Oct23SU" = (NewCveEntry @("CVE-2023-36778") @($ex2016, $ex2019))
"Nov23SU" = (NewCveEntry @("CVE-2023-36050", "CVE-2023-36039", "CVE-2023-36035", "CVE-2023-36439") @($ex2016, $ex2019))
"Mar24SU" = (NewCveEntry @("CVE-2024-26198") @($ex2016, $ex2019))
}

# Need to organize the list so oldest CVEs come out first.
Expand Down Expand Up @@ -208,6 +210,7 @@ function Invoke-AnalyzerSecurityCveCheck {
Invoke-AnalyzerSecurityCve-2023-36434 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCveAddressedBySerializedDataSigning -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCve-MarchSuSpecial -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityADV24199947 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
# Make sure that these stay as the last one to keep the output more readable
Invoke-AnalyzerSecurityExtendedProtectionConfigState -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityMitigationService {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
. $PSScriptRoot\..\Get-FilteredSettingOverrideInformation.ps1
. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
function Invoke-AnalyzerSecurityOverrides {
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ function Invoke-AnalyzerSecurityVulnerability {
$buildVersion = $HealthServerObject.ExchangeInformation.BuildInformation.VersionInformation
$noLongerSecureExchange = ($buildVersion.ExtendedSupportDate -le ([DateTime]::Now)) -and $buildVersion.LatestSU -eq $false

if ($null -eq $securityVulnerabilities -and
($null -ne $iisModule -or $iisModule.DisplayValue -eq $false) -and
if ((($null -eq $securityVulnerabilities -and
$HealthServerObject.ExchangeInformation.GetExchangeServer.IsEdgeServer) -or
($null -eq $securityVulnerabilities -and
($null -ne $iisModule -or $iisModule.DisplayValue -eq $false))) -and
(-not $noLongerSecureExchange)) {
$params = $baseParams + @{
Details = "All known security issues in this version of the script passed."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\Invoke-ScriptBlockHandler.ps1
. $PSScriptRoot\..\..\..\..\Shared\ErrorMonitorFunctions.ps1
function Get-ExchangeAES256CBCDetails {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
. $PSScriptRoot\..\..\..\..\Shared\ErrorMonitorFunctions.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeBuildVersionInformation.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeSettingOverride.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-ExSetupFileVersionInfo.ps1
. $PSScriptRoot\..\..\..\..\Shared\Get-FileContentInformation.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeAppPoolsInformation.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeServerIISSettings.ps1
Expand All @@ -16,7 +17,6 @@
. $PSScriptRoot\Get-ExchangeServerMaintenanceState.ps1
. $PSScriptRoot\Get-ExchangeUpdates.ps1
. $PSScriptRoot\Get-ExchangeVirtualDirectories.ps1
. $PSScriptRoot\Get-ExSetupDetails.ps1
. $PSScriptRoot\Get-FIPFSScanEngineVersionState.ps1
. $PSScriptRoot\Get-ServerRole.ps1
function Get-ExchangeInformation {
Expand All @@ -35,7 +35,7 @@ function Get-ExchangeInformation {
$windows2016OrGreater = Invoke-ScriptBlockHandler @params
$getExchangeServer = (Get-ExchangeServer -Identity $Server -Status)
$exchangeCertificates = Get-ExchangeServerCertificates -Server $Server
$exSetupDetails = Get-ExSetupDetails -Server $Server
$exSetupDetails = Get-ExSetupFileVersionInfo -Server $Server -CatchActionFunction ${Function:Invoke-CatchActions}

if ($null -eq $exSetupDetails) {
# couldn't find ExSetup.exe this should be rare so we are just going to handle this by displaying the AdminDisplayVersion from Get-ExchangeServer
Expand Down Expand Up @@ -117,7 +117,23 @@ function Get-ExchangeInformation {
"$([System.IO.Path]::Combine($serverExchangeBinDirectory, "Search\Ceres\Runtime\1.0\noderunner.exe.config"))")
}

$applicationConfigFileStatus = Get-FileContentInformation @configParams
if ($getExchangeServer.IsEdgeServer -eq $false -and
(-not ([string]::IsNullOrEmpty($registryValues.FipFsDatabasePath)))) {
$configParams.FileLocation += "$([System.IO.Path]::Combine($registryValues.FipFsDatabasePath, "Configuration.xml"))"
}

$getFileContentInformation = Get-FileContentInformation @configParams
$applicationConfigFileStatus = @{}
$fileContentInformation = @{}

foreach ($key in $getFileContentInformation.Keys) {
if ($key -like "*.exe.config") {
$applicationConfigFileStatus.Add($key, $getFileContentInformation[$key])
} else {
$fileContentInformation.Add($key, $getFileContentInformation[$key])
}
}

$serverMaintenance = Get-ExchangeServerMaintenanceState -Server $Server -ComponentsToSkip "ForwardSyncDaemon", "ProvisioningRps"
$settingOverrides = Get-ExchangeSettingOverride -Server $Server -CatchActionFunction ${Function:Invoke-CatchActions}

Expand Down Expand Up @@ -192,6 +208,7 @@ function Get-ExchangeInformation {
SettingOverrides = $settingOverrides
FIPFSUpdateIssue = $FIPFSUpdateIssue
AES256CBCInformation = $aes256CbcDetails
FileContentInformation = $fileContentInformation
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ function Get-ExchangeRegistryValues {
ValueType = "String"
}

$fipFsDatabasePathParams = $baseParams + @{
SubKey = "SOFTWARE\Microsoft\ExchangeServer\v15\FIP-FS"
GetValue = "DatabasePath"
ValueType = "String"
}

return [PSCustomObject]@{
DisableBaseTypeCheckForDeserialization = [int](Get-RemoteRegistryValue @baseTypeCheckForDeserializationParams)
CtsProcessorAffinityPercentage = [int](Get-RemoteRegistryValue @ctsParams)
Expand All @@ -65,5 +71,6 @@ function Get-ExchangeRegistryValues {
SerializedDataSigning = [int](Get-RemoteRegistryValue @serializedDataSigningParams)
MsiInstallPath = [string](Get-RemoteRegistryValue @installDirectoryParams)
DisablePreservation = [string](Get-RemoteRegistryValue @disablePreservationParams)
FipFsDatabasePath = [string](Get-RemoteRegistryValue @fipFsDatabasePathParams)
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,12 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2016" {
$cveTests = GetObject "Security Vulnerability"
$cveTests.Contains("CVE-2020-1147") | Should -Be $true
$cveTests.Contains("CVE-2023-36039") | Should -Be $true
$cveTests.Count | Should -Be 49
$cveTests.Contains("ADV24199947") | Should -Be $true
$cveTests.Count | Should -Be 51
$downloadDomains = GetObject "CVE-2021-1730"
$downloadDomains.DownloadDomainsEnabled | Should -Be "false"

$Script:ActiveGrouping.Count | Should -Be 56
$Script:ActiveGrouping.Count | Should -Be 58
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ Describe "Testing Health Checker by Mock Data Imports" {
$cveTests.Contains("CVE-2020-1147") | Should -Be $true
$cveTests.Contains("CVE-2023-36434") | Should -Be $true
$cveTests.Contains("CVE-2023-36039") | Should -Be $true
$cveTests.Count | Should -Be 49
$cveTests.Contains("ADV24199947") | Should -Be $true
$cveTests.Count | Should -Be 51
$downloadDomains = GetObject "CVE-2021-1730"
$downloadDomains.DownloadDomainsEnabled | Should -Be "False"
TestObjectMatch "Extended Protection Vulnerable" "True" -WriteType "Red"
Expand All @@ -173,7 +174,7 @@ Describe "Testing Health Checker by Mock Data Imports" {
-MockWith { return Import-Clixml "$Script:MockDataCollectionRoot\Hardware\Physical_Win32_PhysicalMemory.xml" }
Mock Get-WmiObjectHandler -ParameterFilter { $Class -eq "Win32_Processor" } `
-MockWith { return Import-Clixml "$Script:MockDataCollectionRoot\Hardware\Physical_Win32_Processor.xml" }
Mock Get-ExSetupDetails { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Get-ExSetupFileVersionInfo { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Get-WebSite -ParameterFilter { $Name -eq "Default Web Site" } -MockWith { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\IIS\GetWebSite_DefaultWebSite1.xml" }
Mock Get-WebConfigFile -ParameterFilter { $PSPath -eq "IIS:\Sites\Default Web Site" } -MockWith { return [PSCustomObject]@{ FullName = "$Script:MockDataCollectionRoot\Exchange\IIS\DefaultWebSite_web2.config" } }
Mock Invoke-ScriptBlockHandler -ParameterFilter { $ScriptBlockDescription -eq "Getting applicationHost.config" } -MockWith { return Get-Content "$Script:MockDataCollectionRoot\Exchange\IIS\applicationHost2.config" -Raw }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ Describe "Testing Health Checker by Mock Data Imports" {
Mock Get-OwaVirtualDirectory { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetOwaVirtualDirectory2.xml" }
Mock Get-AcceptedDomain { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\GetAcceptedDomain_Bad.xml" }
Mock Get-DnsClient { return Import-Clixml "$Script:MockDataCollectionRoot\OS\GetDnsClient1.xml" }
Mock Get-ExSetupDetails { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Get-ExSetupFileVersionInfo { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Invoke-ScriptBlockHandler -ParameterFilter { $ScriptBlockDescription -eq "Getting applicationHost.config" } -MockWith { return Get-Content "$Script:MockDataCollectionRoot\Exchange\IIS\applicationHost1.config" -Raw }
Mock Get-Content -ParameterFilter { $Path -eq "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Runtime\1.0\noderunner.exe.config" } -MockWith { Get-Content "$Script:MockDataCollectionRoot\Exchange\noderunner.exe1.config" -Raw }
Mock Get-Content -ParameterFilter { $Path -eq "C:\Program Files\Microsoft\Exchange Server\V15\Bin\EdgeTransport.exe.config" } -MockWith { Get-Content "$Script:MockDataCollectionRoot\Exchange\EdgeTransport.exe1.config" -Raw }
Expand Down Expand Up @@ -308,7 +308,7 @@ Describe "Testing Health Checker by Mock Data Imports" {
-MockWith { return Import-Clixml "$Script:MockDataCollectionRoot\Hardware\Physical_Win32_PhysicalMemory.xml" }
Mock Get-WmiObjectHandler -ParameterFilter { $Class -eq "Win32_Processor" } `
-MockWith { return Import-Clixml "$Script:MockDataCollectionRoot\Hardware\Physical_Win32_Processor1.xml" }
Mock Get-ExSetupDetails { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Get-ExSetupFileVersionInfo { return Import-Clixml "$Script:MockDataCollectionRoot\Exchange\ExSetup1.xml" }
Mock Invoke-ScriptBlockHandler -ParameterFilter { $ScriptBlockDescription -eq "Getting applicationHost.config" } -MockWith { return Get-Content "$Script:MockDataCollectionRoot\Exchange\IIS\applicationHost2.config" -Raw }

SetDefaultRunOfHealthChecker "Debug_Scenario3_Physical_Results.xml"
Expand Down
Loading

0 comments on commit 4e87975

Please sign in to comment.