Skip to content

Commit

Permalink
Merge pull request #1795 from microsoft/main
Browse files Browse the repository at this point in the history
Release 8-8-23
  • Loading branch information
dpaulson45 authored Aug 8, 2023
2 parents 3247953 + 5d268ec commit b75765e
Show file tree
Hide file tree
Showing 17 changed files with 597 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .build/cspell-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ hsts
httperr
ietf
imap
inetsrv
Infoworker
Inproc
INSUFF
Expand Down Expand Up @@ -90,6 +91,7 @@ msdcs
MSDTC
MSERT
msert
msipc
msrc
Multiplexor
nato
Expand Down
7 changes: 7 additions & 0 deletions .build/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
".vscode",
"/cspell-words.txt"
],
"patterns": [
{
"name": "return-newline-tab-tab",
"pattern": "\\`r\\`n\\`t\\`t"
}
],
"ignoreRegExpList": ["return-newline-tab-tab"],
"caseSensitive": true,
"overrides": [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\Add-AnalyzedResultInformation.ps1
function Invoke-AnalyzerSecurityCve-2023-21709 {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ref]$AnalyzeResults,

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

[Parameter(Mandatory = $true)]
[object]$DisplayGroupingKey
)

Write-Verbose "Calling: $($MyInvocation.MyCommand)"

<#
Description: Check for CVE-2023-21709 vulnerability
Affected Exchange versions: 2016, 2019
Fix: Remove TokenCacheModule from IIS
Workaround: N/A
#>

if ($SecurityObject.IsEdgeServer -eq $false) {
Write-Verbose "Testing CVE: CVE-2023-21709"

if ($SecurityObject.ExchangeInformation.IISSettings.IISModulesInformation.ModuleList.Name -contains "TokenCacheModule") {
Write-Verbose "TokenCacheModule detected - system is vulnerable to CVE-2023-21709 vulnerability"
$params = @{
AnalyzedInformation = $AnalyzeResults
DisplayGroupingKey = $DisplayGroupingKey
Name = "Security Vulnerability"
Details = ("{0}`r`n`t`tSee: https://portal.msrc.microsoft.com/security-guidance/advisory/{0} for more information." -f "CVE-2023-21709")
DisplayWriteType = "Red"
DisplayTestingValue = "CVE-2023-21709"
AddHtmlDetailRow = $false
}
Add-AnalyzedResultInformation @params
} else {
Write-Verbose "TokenCacheModule wasn't detected and as a result, system is not vulnerable to CVE-2023-21709 vulnerability"
}
} else {
Write-Verbose "Edge Server Role is not affected by this vulnerability as it has no IIS installed"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2021-1730.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2021-34470.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2022-21978.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2023-21709.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-MarchSuSpecial.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityIISModules.ps1
Expand Down Expand Up @@ -127,6 +128,7 @@ function Invoke-AnalyzerSecurityCveCheck {
"Feb23SU" = (@(NewCveEntry @("CVE-2023-21529", "CVE-2023-21706", "CVE-2023-21707") $ex131619) + (NewCveEntry "CVE-2023-21710" @($ex2016, $ex2019)))
"Mar23SU" = (@(NewCveEntry ("CVE-2023-21707") $ex131619))
"Jun23SU" = (NewCveEntry @("CVE-2023-28310", "CVE-2023-32031") @($ex2016, $ex2019))
"Aug23SU" = (NewCveEntry @("CVE-2023-38181", "CVE-2023-38182", "CVE-2023-38185", "CVE-2023-35368", "CVE-2023-35388") @($ex2016, $ex2019))
}

# Need to organize the list so oldest CVEs come out first.
Expand Down Expand Up @@ -200,6 +202,7 @@ function Invoke-AnalyzerSecurityCveCheck {
Invoke-AnalyzerSecurityCve-2021-1730 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCve-2021-34470 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCve-2022-21978 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCve-2023-21709 -AnalyzeResults $AnalyzeResults -SecurityObject $securityObject -DisplayGroupingKey $DisplayGroupingKey
Invoke-AnalyzerSecurityCve-MarchSuSpecial -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ function Invoke-AnalyzerSecuritySettings {

Write-Verbose "Calling: $($MyInvocation.MyCommand)"
$osInformation = $HealthServerObject.OSInformation
$aes256CbcInformation = $HealthServerObject.ExchangeInformation.AES256CBCInformation
$keySecuritySettings = (Get-DisplayResultsGroupingKey -Name "Security Settings" -DisplayOrder $Order)
$baseParams = @{
AnalyzedInformation = $AnalyzeResults
Expand Down Expand Up @@ -331,6 +332,30 @@ function Invoke-AnalyzerSecuritySettings {
}
Add-AnalyzedResultInformation @params

# AES256-CBC encryption support check
$params = $baseParams + @{
Name = "AES256-CBC Protected Content Support"
Details = $true
DisplayWriteType = "Green"
}

if (($aes256CbcInformation.AES256CBCSupportedBuild) -and
($aes256CbcInformation.ValidAESConfiguration -eq $false)) {
$params.Details = ("True" +
"`r`n`t`tThis build supports AES256-CBC protected content, but the configuration is not complete. Exchange Server is not able to decrypt" +
"`r`n`t`tprotected messages which could impact eDiscovery and Journaling tasks. If you use Rights Management Service (RMS) on-premises," +
"`r`n`t`tplease follow the instructions as outlined in the documentation: https://aka.ms/ExchangeCBCKB")
$params.DisplayWriteType = "Yellow"
} elseif ($aes256CbcInformation.AES256CBCSupportedBuild -eq $false) {
$params.Details = ("False" +
"`r`n`t`tThis could lead to scenarios where Exchange Server is no longer able to decrypt protected messages," +
"`r`n`t`tfor example, when sending rights management protected messages using AES256-CBC encryption algorithm," +
"`r`n`t`tor when performing eDiscovery and Journaling tasks." +
"`r`n`t`tMore Information: https://aka.ms/Purview/CBCDetails")
$params.DisplayWriteType = "Red"
}
Add-AnalyzedResultInformation @params

$additionalDisplayValue = [string]::Empty
$smb1Settings = $osInformation.Smb1ServerSettings

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

. $PSScriptRoot\..\..\Helpers\CompareExchangeBuildLevel.ps1
. $PSScriptRoot\..\..\..\..\Shared\Invoke-ScriptBlockHandler.ps1
. $PSScriptRoot\..\..\..\..\Shared\ErrorMonitorFunctions.ps1
function Get-ExchangeAES256CBCDetails {
param(
[Parameter(Mandatory = $false)]
[String]$Server = $env:COMPUTERNAME,

[Parameter(Mandatory = $true)]
[System.Object]$VersionInformation
)

<#
AES256-CBC encryption support check
https://techcommunity.microsoft.com/t5/security-compliance-and-identity/encryption-algorithm-changes-in-microsoft-purview-information/ba-p/3831909
#>

begin {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
$aes256CBCSupported = $false
$msipcRegistryAclAsExpected = $false
$regPathToCheck = "HKLM:\SOFTWARE\Microsoft\MSIPC\Server"
# Translates to: "NetworkService", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"
# See: https://learn.microsoft.com/dotnet/api/system.security.accesscontrol.registryaccessrule.-ctor?view=net-7.0#system-security-accesscontrol-registryaccessrule-ctor(system-security-principal-identityreference-system-security-accesscontrol-registryrights-system-security-accesscontrol-inheritanceflags-system-security-accesscontrol-propagationflags-system-security-accesscontrol-accesscontroltype)
$networkServiceAcl = New-Object System.Security.AccessControl.RegistryAccessRule(
[System.Security.Principal.SecurityIdentifier]::new("S-1-5-20"), 983103, 3, 0, 0
)
} process {
# First, check if the build running on the server supports AES256-CBC
if (Test-ExchangeBuildGreaterOrEqualThanSecurityPatch -CurrentExchangeBuild $VersionInformation -SU "Aug23SU") {

Write-Verbose "AES256-CBC encryption for information protection is supported by this Exchange Server build"
$aes256CBCSupported = $true

# As build supports AES256-CBC, next step is to check that the registry key exists and permissions are set as expected
$params = @{
ComputerName = $Server
ScriptBlock = { Test-Path -Path $regPathToCheck }
CatchActionFunction = ${Function:Invoke-CatchActions}
}

if ((Invoke-ScriptBlockHandler @params) -eq $false) {
Write-Verbose "Unable to query Acl of registry key $regPathToCheck assuming that the key doesn't exist"
} else {
$params.ScriptBlock = { Get-Acl -Path $regPathToCheck }
$acl = Invoke-ScriptBlockHandler @params

# ToDo: As we have multiple places in HC where we query acls, we should consider creating a function
# that can be used to do the acl call, similar to what we do in Get-ExchangeRegistryValues.ps1.
Write-Verbose "Registry key exists and Acl was successfully queried - validating Acl now"
try {
$aclMatch = $acl.Access.Where({
($_.RegistryRights -eq $networkServiceAcl.RegistryRights) -and
($_.AccessControlType -eq $networkServiceAcl.AccessControlType) -and
($_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $networkServiceAcl.IdentityReference) -and
($_.InheritanceFlags -eq $networkServiceAcl.InheritanceFlags) -and
($_.PropagationFlags -eq $networkServiceAcl.PropagationFlags)
})

if (@($aclMatch).Count -ge 1) {
Write-Verbose "Acl for NetworkService is as expected"
$msipcRegistryAclAsExpected = $true
} else {
Write-Verbose "Acl for NetworkService was not found or is not as expected"
}
} catch {
Write-Verbose "Unable to verify Acl on registry key $regPathToCheck"
Invoke-CatchActions
}
}
} else {
Write-Verbose "AES256-CBC encryption for information protection is not supported by this Exchange Server build"
}
} end {
return [PSCustomObject]@{
AES256CBCSupportedBuild = $aes256CBCSupported
RegistryKeyConfiguredAsExpected = $msipcRegistryAclAsExpected
ValidAESConfiguration = (($aes256CBCSupported) -and ($msipcRegistryAclAsExpected))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
. $PSScriptRoot\..\..\..\..\Shared\Get-ExchangeSettingOverride.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeAppPoolsInformation.ps1
. $PSScriptRoot\IISInformation\Get-ExchangeServerIISSettings.ps1
. $PSScriptRoot\Get-ExchangeAES256CBCDetails.ps1
. $PSScriptRoot\Get-ExchangeApplicationConfigurationFileValidation.ps1
. $PSScriptRoot\Get-ExchangeConnectors.ps1
. $PSScriptRoot\Get-ExchangeDependentServices.ps1
Expand Down Expand Up @@ -147,6 +148,13 @@ function Get-ExchangeInformation {
}
}
$eemsEndpointResults = Invoke-ScriptBlockHandler @eemsEndpointParams

Write-Verbose "Checking AES256-CBC information protection readiness and configuration"
$aes256CbcParams = @{
Server = $Server
VersionInformation = $versionInformation
}
$aes256CbcDetails = Get-ExchangeAES256CBCDetails @aes256CbcParams
} end {

Write-Verbose "Exiting: Get-ExchangeInformation"
Expand All @@ -169,6 +177,7 @@ function Get-ExchangeInformation {
IISSettings = $iisSettings
SettingOverrides = $settingOverrides
FIPFSUpdateIssue = $FIPFSUpdateIssue
AES256CBCInformation = $aes256CbcDetails
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2013" {
TestObjectMatch "SMB1 Installed" "True" -WriteType "Red"
TestObjectMatch "SMB1 Blocked" "False" -WriteType "Red"

$Script:ActiveGrouping.Count | Should -Be 82
$Script:ActiveGrouping.Count | Should -Be 83
}

It "Display Results - Security Vulnerability" {
SetActiveDisplayGrouping "Security Vulnerability"

$cveTests = $Script:ActiveGrouping.TestingValue | Where-Object { ($_.GetType().Name -eq "String") -and ($_.StartsWith("CVE")) }
$cveTests.Contains("CVE-2020-1147") | Should -Be $true
$cveTests.Count | Should -Be 53
$cveTests.Count | Should -Be 54
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,19 @@ Describe "Testing Health Checker by Mock Data Imports - Exchange 2016" {
TestObjectMatch "Pattern service" "Unreachable`r`n`t`tMore information: https://aka.ms/HelpConnectivityEEMS" -WriteType "Yellow"
TestObjectMatch "Telemetry enabled" "False"

$Script:ActiveGrouping.Count | Should -Be 95
$Script:ActiveGrouping.Count | Should -Be 96
}

It "Display Results - Security Vulnerability" {
SetActiveDisplayGrouping "Security Vulnerability"

$cveTests = GetObject "Security Vulnerability"
$cveTests.Contains("CVE-2020-1147") | Should -Be $true
$cveTests.Count | Should -Be 33
$cveTests.Count | Should -Be 39
$downloadDomains = GetObject "CVE-2021-1730"
$downloadDomains.DownloadDomainsEnabled | Should -Be "false"

$Script:ActiveGrouping.Count | Should -Be 40
$Script:ActiveGrouping.Count | Should -Be 46
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,15 @@ Describe "Testing Health Checker by Mock Data Imports" {
TestObjectMatch "Strict Mode disabled" "False" -WriteType "Green"
TestObjectMatch "BaseTypeCheckForDeserialization disabled" "False" -WriteType "Green"

$Script:ActiveGrouping.Count | Should -Be 78
$Script:ActiveGrouping.Count | Should -Be 79
}

It "Display Results - Security Vulnerability" {
SetActiveDisplayGrouping "Security Vulnerability"

$cveTests = GetObject "Security Vulnerability"
$cveTests.Contains("CVE-2020-1147") | Should -Be $true
$cveTests.Count | Should -Be 33
$cveTests.Count | Should -Be 39
$downloadDomains = GetObject "CVE-2021-1730"
$downloadDomains.DownloadDomainsEnabled | Should -Be "False"
TestObjectMatch "Extended Protection Vulnerable" "True" -WriteType "Red"
Expand Down
Loading

0 comments on commit b75765e

Please sign in to comment.