Skip to content

Commit

Permalink
Merge pull request #2222 from microsoft/NovSU
Browse files Browse the repository at this point in the history
Nov 24 SU
  • Loading branch information
dpaulson45 authored Nov 12, 2024
2 parents 9c6abb0 + 9f116af commit 50a8dff
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ function Get-FilteredSettingOverrideInformation {
[string]$FilterSectionName,

[Parameter(Mandatory = $true)]
[string]$FilterParameterName
[string[]]$FilterParameterName
)
begin {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
Write-Verbose "Trying to filter down results for ComponentName: $FilterComponentName SectionName: $FilterSectionName ParameterName: $FilterParameterName"
Write-Verbose "Trying to filter down results for ComponentName: $FilterComponentName SectionName: $FilterSectionName ParameterName: $([string]::Join(", ", $FilterParameterName))"
$results = New-Object "System.Collections.Generic.List[object]"
$findFromOverride = $null
$usedAdSettings = $false
Expand Down Expand Up @@ -63,47 +63,50 @@ function Get-FilteredSettingOverrideInformation {
Write-Verbose "Working on entry: $($entry.Name)"
foreach ($p in [array]($entry.Parameters)) {
Write-Verbose "Working on parameter: $p"
if ($p.Contains($FilterParameterName)) {
$value = $p.Substring($FilterParameterName.Length + 1) # Add plus 1 for '='
# everything matched, however, only add it to the list for the following reasons
# - Status is Accepted and not from AD and a unique value in the list
# - Or From AD and current logic determines it applies
foreach ($currentFilterParameterName in $FilterParameterName) {
if ($p.Contains($currentFilterParameterName)) {
$value = $p.Substring($currentFilterParameterName.Length + 1) # Add plus 1 for '='
# everything matched, however, only add it to the list for the following reasons
# - Status is Accepted and not from AD and a unique value in the list
# - Or From AD and current logic determines it applies

if ($usedAdSettings) {
# can have it apply by build and server parameter
if (($null -eq $entry.MinVersion -or
$FilterServerVersion -ge $entry.MinVersion) -and
if ($usedAdSettings) {
# can have it apply by build and server parameter
if (($null -eq $entry.MinVersion -or
$FilterServerVersion -ge $entry.MinVersion) -and
(($null -eq $entry.MaxVersion -or
$FilterServerVersion -le $entry.MaxVersion)) -and
$FilterServerVersion -le $entry.MaxVersion)) -and
(($null -eq $entry.Server -or
$entry.Server.ToLower().Contains($adjustedFilterServer)))) {
$status = $entry.Status
$entry.Server -contains $adjustedFilterServer))) {
$status = $entry.Status.ToString()
} else {
$status = "DoesNotApply"
}
} else {
$status = "DoesNotApply"
$status = $entry.Status.ToString()
}
} else {
$status = $entry.Status
}

if ($status -eq "Accepted" -and
# Add to the list if the status is Accepted, and we do not have that ParameterName yet in the list.
if ($status -eq "Accepted" -and
($results.Count -lt 1 -or
-not ($results.ParameterValue.ToLower().Contains($value.ToLower())))) {
$results.Add([PSCustomObject]@{
Name = $entry.Name
Reason = $entry.Reason
ModifiedBy = $entry.ModifiedBy
ComponentName = $entry.ComponentName
SectionName = $entry.SectionName
ParameterName = $FilterParameterName
ParameterValue = $value
Status = $entry.Status
TrueStatus = $status
FromAdSettings = $usedAdSettings
})
} elseif ($status -eq "Accepted") {
Write-Verbose "Already have 1 Accepted value added to list no need to add another one. Skip adding $($entry.Name)"
} else {
Write-Verbose "Already have parameter value added to the. Skip adding $($entry.Name)"
-not ($results.ParameterName -contains $currentFilterParameterName))) {
$results.Add([PSCustomObject]@{
Name = $entry.Name
Reason = $entry.Reason
ModifiedBy = $entry.ModifiedBy
ComponentName = $entry.ComponentName
SectionName = $entry.SectionName
ParameterName = $currentFilterParameterName
ParameterValue = $value
Status = $entry.Status
TrueStatus = $status
FromAdSettings = $usedAdSettings
})
} elseif ($status -eq "Accepted") {
Write-Verbose "Already have 1 Accepted value added to list no need to add another one. Skip adding $($entry.Name)"
} else {
Write-Verbose "Already have parameter value added to the list. Skip adding $($entry.Name)"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
}
Add-AnalyzedResultInformation @params

$detailsValue = $exchangeInformation.RegistryValues.EnableEccCertificateSupport
$displayWriteType = "Grey"

if (-not (Test-ExchangeBuildGreaterOrEqualThanSecurityPatch -CurrentExchangeBuild $exchangeInformation.BuildInformation.VersionInformation -SUName "Nov24SU") -and $detailsValue -eq "1") {
$detailsValue = "1 --- Warning: On a build that doesn't support this configuration yet.`r`n`t`tMore Information: https://aka.ms/HC-EccCertificateChange"
$displayWriteType = "Yellow"
}

$params = $baseParams + @{
Name = "EnableEccCertificateSupport Registry Value"
Details = $detailsValue
DisplayWriteType = $displayWriteType
}
Add-AnalyzedResultInformation @params

$displayValue = $exchangeInformation.RegistryValues.CtsProcessorAffinityPercentage
$displayWriteType = "Green"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function Invoke-AnalyzerSecurityAMSIConfigState {
(Test-ExchangeBuildGreaterOrEqualThanBuild -CurrentExchangeBuild $exchangeInformation.BuildInformation.VersionInformation -Version "Exchange2019" -CU "CU10")) -and
($exchangeInformation.GetExchangeServer.IsEdgeServer -eq $false)) {

$params = @{
$filterSettingOverrideParams = @{
ExchangeSettingOverride = $HealthServerObject.ExchangeInformation.SettingOverrides
GetSettingOverride = $HealthServerObject.OrganizationInformation.GetSettingOverride
FilterServer = $HealthServerObject.ServerName
Expand All @@ -44,14 +44,15 @@ function Invoke-AnalyzerSecurityAMSIConfigState {
}

# Only thing that is returned is Accepted values and unique
[array]$amsiInformation = Get-FilteredSettingOverrideInformation @params

[array]$amsiInformation = Get-FilteredSettingOverrideInformation @filterSettingOverrideParams
$amsiWriteType = "Yellow"
$amsiConfigurationWarning = "`r`n`t`tThis may pose a security risk to your servers`r`n`t`tMore Information: https://aka.ms/HC-AMSIExchange"
$amsiConfigurationWarning = "`r`n`t`tThis may pose a security risk to your servers"
$amsiMoreInfo = "More Information: https://aka.ms/HC-AMSIExchange"
$amsiMoreInformationDisplay = $false
$amsiConfigurationUnknown = "Exchange AMSI integration state is unknown"
$additionalAMSIDisplayValue = $null

if ($null -eq $amsiInformation) {
if ($amsiInformation.Count -eq 0) {
# No results returned, no matches therefore good.
$amsiWriteType = "Green"
$amsiState = "True"
Expand All @@ -60,17 +61,17 @@ function Invoke-AnalyzerSecurityAMSIConfigState {
} elseif ($amsiInformation.Count -eq 1) {
$amsiState = $amsiInformation.ParameterValue
if ($amsiInformation.ParameterValue -eq "False") {
$additionalAMSIDisplayValue = "Setting applies to the server" + $amsiConfigurationWarning
$additionalAMSIDisplayValue = "Setting applies to the server" + $amsiConfigurationWarning + "`r`n`t`t" + $amsiMoreInfo
} elseif ($amsiInformation.ParameterValue -eq "True") {
$amsiWriteType = "Green"
} else {
$additionalAMSIDisplayValue = $amsiConfigurationUnknown + " - Setting Override Name: $($amsiInformation.Name)"
$additionalAMSIDisplayValue += $amsiConfigurationWarning
$additionalAMSIDisplayValue += $amsiConfigurationWarning + "`r`n`t`t" + $amsiMoreInfo
}
} else {
$amsiState = "Multiple overrides detected"
$additionalAMSIDisplayValue = $amsiConfigurationUnknown + " - Multi Setting Overrides Applied: $([string]::Join(", ", $amsiInformation.Name))"
$additionalAMSIDisplayValue += $amsiConfigurationWarning
$additionalAMSIDisplayValue += $amsiConfigurationWarning + "`r`n`t`t" + $amsiMoreInfo
}

$params = $baseParams + @{
Expand All @@ -88,6 +89,81 @@ function Invoke-AnalyzerSecurityAMSIConfigState {
}
Add-AnalyzedResultInformation @params
}

<#
AMSI Needs to be enabled in order for Request Body Scanning to work.
- If request body scanning is enabled, but AMSI is disabled, call out this misconfiguration
- If request body max size is enabled, if the HTTP request body size is over 1MB regardless if AMSI is enabled,
it will be rejected.
- If request body scanning is enabled and AMSI is enabled, then just show enabled.
#>

$amsiStateEnabled = "true" -eq $amsiState
$filterSettingOverrideParams.FilterSectionName = "AmsiRequestBodyScanning"
$filterSettingOverrideParams.FilterParameterName = @("EnabledAll", "EnabledApi", "EnabledAutoD", "EnabledEcp",
"EnabledEws", "EnabledMapi", "EnabledEas", "EnabledOab", "EnabledOwa", "EnabledPowerShell", "EnabledOthers")
[array]$amsiRequestBodyScanning = Get-FilteredSettingOverrideInformation @filterSettingOverrideParams
$filterSettingOverrideParams.FilterSectionName = "BlockRequestBodyGreaterThanMaxScanSize"
[array]$amsiBlockRequestBodyGreater = Get-FilteredSettingOverrideInformation @filterSettingOverrideParams
$amsiRequestBodyScanningEnabled = $amsiRequestBodyScanning.Count -gt 0 -and
($null -ne ($amsiRequestBodyScanning | Where-Object { $_.ParameterValue -eq "True" }))
$amsiBlockRequestBodyEnabled = $amsiBlockRequestBodyGreater.Count -gt 0 -and
($null -ne ($amsiBlockRequestBodyGreater | Where-Object { $_.ParameterValue -eq "True" }))
$requestBodyDisplayValue = $amsiStateEnabled -and $amsiRequestBodyScanningEnabled
$requestBodyDisplayType = $requestBodySizeBlockDisplayType = "Grey"
$requestBodySizeBlockDisplayValue = $false

if ($amsiBlockRequestBodyEnabled) {
$requestBodySizeBlockDisplayValue = "$true - WARNING: Requests over 1MB will be blocked."
$requestBodySizeBlockDisplayType = "Yellow"
$amsiMoreInformationDisplay = $true
}

if ($amsiStateEnabled -eq $false) {
if ($amsiRequestBodyScanningEnabled) {
$requestBodyDisplayValue = "$true - WARNING: AMSI not enabled"
$requestBodyDisplayType = "Yellow"
$amsiMoreInformationDisplay = $true
}
if ($amsiBlockRequestBodyEnabled) {
$requestBodySizeBlockDisplayValue += " AMSI not enabled and this will still be triggered."
$amsiMoreInformationDisplay = $true
}
}

$params = $baseParams + @{
Name = "AMSI Request Body Scanning"
Details = $requestBodyDisplayValue
DisplayWriteType = $requestBodyDisplayType
}
Add-AnalyzedResultInformation @params

$params = $baseParams + @{
Name = "AMSI Request Body Size Block"
Details = $requestBodySizeBlockDisplayValue
DisplayWriteType = $requestBodySizeBlockDisplayType
}
Add-AnalyzedResultInformation @params

if (($amsiRequestBodyScanningEnabled -or
$amsiBlockRequestBodyEnabled) -and
-not (Test-ExchangeBuildGreaterOrEqualThanSecurityPatch -CurrentExchangeBuild $exchangeInformation.BuildInformation.VersionInformation -SUName "Nov24SU")) {
$params = $baseParams + @{
Details = "AMSI Body Scanning Option(s) enabled, but not applicable due to the version of Exchange. Must be on Nov24SU or greater to have this feature enabled."
DisplayCustomTabNumber = 2
DisplayWriteType = "Yellow"
}
Add-AnalyzedResultInformation @params
}

if ($amsiMoreInformationDisplay) {
$params = $baseParams + @{
Details = $amsiMoreInfo
DisplayCustomTabNumber = 2
DisplayWriteType = "Yellow"
}
Add-AnalyzedResultInformation @params
}
} else {
Write-Verbose "AMSI integration is not available because we are on: $($exchangeInformation.BuildInformation.MajorVersion) $exchangeCU"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

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

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

[Parameter(Mandatory = $true)]
[object]$DisplayGroupingKey
)
begin {
Write-Verbose "Calling: $($MyInvocation.MyCommand)"
$exchangeInformation = $SecurityObject.ExchangeInformation
$organizationInformation = $SecurityObject.OrgInformation
$exchangeBuild = $exchangeInformation.BuildInformation.VersionInformation.BuildVersion
# cSpell:disable
# Need to disable cSpell because this is the name of the override
$filterParameterName = "AddDisclaimerforRegexMatch"
# cSpell:enable
}
process {
$params = @{
ExchangeSettingOverride = $exchangeInformation.SettingOverrides
GetSettingOverride = $organizationInformation.GetSettingOverride
FilterServer = $exchangeInformation.GetExchangeServer.Name
FilterServerVersion = $exchangeBuild
FilterComponentName = "Transport"
FilterSectionName = "NonCompliantSenderSettings"
FilterParameterName = $filterParameterName
}
[array]$nonCompliantSenderSettings = Get-FilteredSettingOverrideInformation @params

$overrideDisabled = $nonCompliantSenderSettings.Count -gt 0 -and
($null -ne ($nonCompliantSenderSettings | Where-Object { $_.ParameterValue -eq "false" }))
$isSuApplied = (Test-ExchangeBuildGreaterOrEqualThanSecurityPatch -CurrentExchangeBuild $SecurityObject.BuildInformation -SUName "Nov24SU")

if (-not $isSuApplied -or $overrideDisabled) {
$params = @{
AnalyzedInformation = $AnalyzeResults
DisplayGroupingKey = $DisplayGroupingKey
Name = "Security Vulnerability"
Details = ("{0} - Override Is Set: $overrideDisabled`r`n`t`tSee: https://portal.msrc.microsoft.com/security-guidance/advisory/{0} for more information." -f "CVE-2024-49040")
DisplayWriteType = "Red"
DisplayTestingValue = "CVE-2024-49040"
}
Add-AnalyzedResultInformation @params
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2022-21978.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2023-36434.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCveAddressedBySerializedDataSigning.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-2024-49040.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityCve-MarchSuSpecial.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityExtendedProtectionConfigState.ps1
. $PSScriptRoot\Invoke-AnalyzerSecurityIISModules.ps1
Expand Down Expand Up @@ -211,6 +212,7 @@ function Invoke-AnalyzerSecurityCveCheck {
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
Invoke-AnalyzerSecurityCve-2024-49040 -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
}
Loading

0 comments on commit 50a8dff

Please sign in to comment.