diff --git a/Security/README.md b/Security/README.md index eab48b72bd..02f2650fe5 100644 --- a/Security/README.md +++ b/Security/README.md @@ -173,17 +173,11 @@ For more information on each mitigation please visit https://aka.ms/exchangevuln For this script to work you must have the IIS URL Rewrite Module installed which can be done via this script using the -FullPathToMSI parameter. -For IIS 10 and higher URL Rewrite Module 2.1 must be installed, you can download version 2.1 here: +URL Rewrite Module 2.1 must be installed, you can download version 2.1 here: * x86 & x64 -https://www.iis.net/downloads/microsoft/url-rewrite -For IIS 8.5 and lower Rewrite Module 2.0 must be installed, you can download version 2.0 here: - -* x86 - https://www.microsoft.com/en-us/download/details.aspx?id=5747 - -* x64 - https://www.microsoft.com/en-us/download/details.aspx?id=7435 - -Installing URL Rewrite version 2.1 on IIS versions 8.5 and lower may cause IIS and Exchange to become unstable. If there is a mismatch between the URL Rewrite module and IIS version, ExchangeMitigations.ps1 will not apply the mitigation for CVE-2021-26855. You must uninstall the URL Rewrite module and reinstall the correct version. +For systems running IIS 8.5 and lower KB2999226 must be installed. Please review the pre-reqs for this KB and download from https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c" Script requires PowerShell 3.0 and later and must be executed from an elevated PowerShell Session. @@ -218,4 +212,4 @@ For usage information, please read the top of the file. Download the latest release here: -[Download http-vuln-cve2021-26855.nse](https://github.com/microsoft/CSS-Exchange/releases/latest/download/http-vuln-cve2021-26855.nse) +[Download http-vuln-cve2021-26855.nse](https://github.com/microsoft/CSS-Exchange/releases/latest/download/http-vuln-cve2021-26855.nse) \ No newline at end of file diff --git a/Security/src/ExchangeMitigations.ps1 b/Security/src/ExchangeMitigations.ps1 index a5d5c0ae7b..df07f2b667 100644 --- a/Security/src/ExchangeMitigations.ps1 +++ b/Security/src/ExchangeMitigations.ps1 @@ -122,84 +122,105 @@ param( [switch]$AutoDownloadURLRewrite ) -function GetMsiProductVersion { - param ( - [string]$filename +function BackendCookieMitigation { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Justification = 'Invalid rule result')] + param( + [string]$WebSiteName = "Default Web Site", + [switch]$RollbackMitigation ) - try { - $windowsInstaller = New-Object -com WindowsInstaller.Installer - - $database = $windowsInstaller.GetType().InvokeMember( - "OpenDatabase", "InvokeMethod", $Null, - $windowsInstaller, @($filename, 0) - ) - - $q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'" - - $View = $database.GetType().InvokeMember( - "OpenView", "InvokeMethod", $Null, $database, ($q) + function Get-MsiProductVersion { + param ( + [string]$filename ) try { - $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null) | Out-Null + $windowsInstaller = New-Object -com WindowsInstaller.Installer - $record = $View.GetType().InvokeMember( - "Fetch", "InvokeMethod", $Null, $View, $Null + $database = $windowsInstaller.GetType().InvokeMember( + "OpenDatabase", "InvokeMethod", $Null, + $windowsInstaller, @($filename, 0) ) - $productVersion = $record.GetType().InvokeMember( - "StringData", "GetProperty", $Null, $record, 1 + $q = "SELECT Value FROM Property WHERE Property = 'ProductVersion'" + + $View = $database.GetType().InvokeMember( + "OpenView", "InvokeMethod", $Null, $database, ($q) ) - return $productVersion - } finally { - if ($View) { - $View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null) | Out-Null + try { + $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null) | Out-Null + + $record = $View.GetType().InvokeMember( + "Fetch", "InvokeMethod", $Null, $View, $Null + ) + + $productVersion = $record.GetType().InvokeMember( + "StringData", "GetProperty", $Null, $record, 1 + ) + + return $productVersion + } finally { + if ($View) { + $View.GetType().InvokeMember("Close", "InvokeMethod", $Null, $View, $Null) | Out-Null + } } + } catch { + throw "Failed to get MSI file version the error was: {0}." -f $_ } - } catch { - throw "Failed to get MSI file version the error was: {0}." -f $_ } -} -function Get-InstalledSoftwareVersion { - param ( - [ValidateNotNullOrEmpty()] - [string[]]$Name - ) - try { - $UninstallKeys = @( - "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", - "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" + function Get-InstalledSoftwareVersion { + param ( + [ValidateNotNullOrEmpty()] + [string[]]$Name ) - New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null + try { + $UninstallKeys = @( + "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", + "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" + ) - $UninstallKeys += Get-ChildItem HKU: | Where-Object { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | ForEach-Object { - "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" - } + New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null - foreach ($UninstallKey in $UninstallKeys) { - $SwKeys = Get-ChildItem -Path $UninstallKey -ErrorAction SilentlyContinue - foreach ($n in $Name) { - $SwKeys = $SwKeys | Where-Object { $_.GetValue('DisplayName') -like "$n" } + $UninstallKeys += Get-ChildItem HKU: | Where-Object { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | ForEach-Object { + "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" } - if ($SwKeys) { - foreach ($SwKey in $SwKeys) { - if ($SwKey.GetValueNames().Contains("DisplayVersion")) { - return $SwKey.GetValue("DisplayVersion") + + foreach ($UninstallKey in $UninstallKeys) { + $SwKeys = Get-ChildItem -Path $UninstallKey -ErrorAction SilentlyContinue + foreach ($n in $Name) { + $SwKeys = $SwKeys | Where-Object { $_.GetValue('DisplayName') -like "$n" } + } + if ($SwKeys) { + foreach ($SwKey in $SwKeys) { + if ($SwKey.GetValueNames().Contains("DisplayVersion")) { + return $SwKey.GetValue("DisplayVersion") + } } } } + } catch { + Write-Error -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" } - } catch { - Write-Error -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" } -} -function GetURLRewriteLink { - $DownloadLinks = @{ - "v2.1" = @{ + + function Test-IIS10 { + $iisRegPath = "hklm:\SOFTWARE\Microsoft\InetStp" + + if (Test-Path $iisRegPath) { + $properties = Get-ItemProperty $iisRegPath + if ($properties.MajorVersion -eq 10) { + return $true + } + } + + return $false + } + + function Get-URLRewriteLink { + $DownloadLinks = @{ "x86" = @{ "de-DE" = "https://download.microsoft.com/download/D/8/1/D81E5DD6-1ABB-46B0-9B4B-21894E18B77F/rewrite_x86_de-DE.msi" "en-US" = "https://download.microsoft.com/download/D/8/1/D81E5DD6-1ABB-46B0-9B4B-21894E18B77F/rewrite_x86_en-US.msi" @@ -212,7 +233,6 @@ function GetURLRewriteLink { "zh-CN" = "https://download.microsoft.com/download/D/8/1/D81E5DD6-1ABB-46B0-9B4B-21894E18B77F/rewrite_x86_zh-CN.msi" "zh-TW" = "https://download.microsoft.com/download/D/8/1/D81E5DD6-1ABB-46B0-9B4B-21894E18B77F/rewrite_x86_zh-TW.msi" } - "x64" = @{ "de-DE" = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_de-DE.msi" "en-US" = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi" @@ -226,64 +246,87 @@ function GetURLRewriteLink { "zh-TW" = "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_zh-TW.msi" } } - "v2.0" = @{ - "x86" = @{ - "de-DE" = "https://download.microsoft.com/download/0/5/0/05045383-D280-4DC6-AE8C-81764118B0F9/rewrite_x86_de-DE.msi" - "en-US" = "https://download.microsoft.com/download/6/9/C/69C1195A-123E-4BE8-8EDF-371CDCA4EC6C/rewrite_2.0_rtw_x86.msi" - "es-ES" = "https://download.microsoft.com/download/1/D/9/1D9464B8-9F3B-4A86-97F2-AEC2AB48F481/rewrite_x86_es-ES.msi" - "fr-FR" = "https://download.microsoft.com/download/1/2/9/129A2686-9654-4B2A-82ED-FC7BCE2BCE93/rewrite_x86_fr-FR.msi" - "it-IT" = "https://download.microsoft.com/download/2/4/A/24AE553F-CA8F-43B3-ACF8-DAC526FC84F2/rewrite_x86_it-IT.msi" - "ja-JP" = "https://download.microsoft.com/download/A/6/9/A69D23A5-7CE3-4F80-B5AE-CF6478A5DE19/rewrite_x86_ja-JP.msi" - "ko-KR" = "https://download.microsoft.com/download/2/6/F/26FCA84A-48BC-4AEE-BD6A-B28ED595832E/rewrite_x86_ko-KR.msi" - "ru-RU" = "https://download.microsoft.com/download/B/1/F/B1FDE19F-B4F9-4EBF-9E50-5C9CDF0302D2/rewrite_x86_ru-RU.msi" - "zh-CN" = "https://download.microsoft.com/download/4/9/C/49CD28DB-4AA6-4A51-9437-AA001221F606/rewrite_x86_zh-CN.msi" - "zh-TW" = "https://download.microsoft.com/download/1/9/4/1947187A-8D73-4C3E-B62C-DC6C7E1B353C/rewrite_x86_zh-TW.msi" - } - "x64" = @{ - "de-DE" = "https://download.microsoft.com/download/3/1/C/31CE0BF6-31D7-415D-A70A-46A430DE731F/rewrite_x64_de-DE.msi" - "en-US" = "https://download.microsoft.com/download/6/7/D/67D80164-7DD0-48AF-86E3-DE7A182D6815/rewrite_2.0_rtw_x64.msi" - "es-ES" = "https://download.microsoft.com/download/9/5/5/955337F6-5A11-417E-A95A-E45EE8C7E7AC/rewrite_x64_es-ES.msi" - "fr-FR" = "https://download.microsoft.com/download/3/D/3/3D359CD6-147B-42E9-BD5B-407D3A1F0B97/rewrite_x64_fr-FR.msi" - "it-IT" = "https://download.microsoft.com/download/6/8/B/68B8EFA8-9404-45A3-A51B-53D940D5E742/rewrite_x64_it-IT.msi" - "ja-JP" = "https://download.microsoft.com/download/3/7/5/375C965C-9D98-438A-8F11-7F417D071DC9/rewrite_x64_ja-JP.msi" - "ko-KR" = "https://download.microsoft.com/download/2/A/7/2A746C73-467A-4BC6-B5CF-C4E88BB40406/rewrite_x64_ko-KR.msi" - "ru-RU" = "https://download.microsoft.com/download/7/4/E/74E569F7-44B9-4D3F-BCA7-87C5FE36BD62/rewrite_x64_ru-RU.msi" - "zh-CN" = "https://download.microsoft.com/download/4/E/7/4E7ECE9A-DF55-4F90-A354-B497072BDE0A/rewrite_x64_zh-CN.msi" - "zh-TW" = "https://download.microsoft.com/download/8/2/C/82CE350D-2068-4DAC-99D5-AEB2241DB545/rewrite_x64_zh-TW.msi" - } + + if ([Environment]::Is64BitOperatingSystem) { + $Architecture = "x64" + } else { + $Architecture = "x86" } - } - $IISVersion = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp\ | Select-Object versionstring + if ((Get-Culture).Name -in @("de-DE", "en-US", "es-ES", "fr-FR", "it-IT", "ja-JP", "ko-KR", "ru-RU", "zn-CN", "zn-TW")) { + $Language = (Get-Culture).Name + } else { + $Language = "en-US" + } - if ($IISVersion.VersionString -like "* 10.*") { - $Version = "v2.1" - } else { - $Version = "v2.0" + return $DownloadLinks[$Architecture][$Language] } - if ([Environment]::Is64BitOperatingSystem) { - $Architecture = "x64" - } else { - $Architecture = "x86" - } + function Confirm-Signature { + param( + [string]$Filepath, + [string]$Stage + ) + $MicrosoftSigningRoot2010 = 'CN=Microsoft Root Certificate Authority 2010, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' + $MicrosoftSigningRoot2011 = 'CN=Microsoft Root Certificate Authority 2011, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' - if ((Get-Culture).Name -in @("de-DE", "en-US", "es-ES", "fr-FR", "it-IT", "ja-JP", "ko-KR", "ru-RU", "zn-CN", "zn-TW")) { - $Language = (Get-Culture).Name - } else { - $Language = "en-US" - } + $IsValid = $false + $failMsg = "Signature of $Filepath not as expected. " + try { + if (!(Test-Path $Filepath)) { + $IsValid = $false + $failMsg += "Filepath does not exist" + throw + } - return $DownloadLinks[$Version][$Architecture][$Language] -} -Function BackendCookieMitigation { - [CmdLetBinding()] - param( - [System.IO.FileInfo]$FullPathToMSI, - [ValidateNotNullOrEmpty()] - [string[]]$WebSiteNames, - [switch]$RollbackMitigation - ) + $sig = Get-AuthenticodeSignature -FilePath $Filepath + + if ($sig.Status -ne 'Valid') { + $IsValid = $false + $failMsg += "Signature is not trusted by machine as Valid, status: $($sig.Status)" + throw + } + + $chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain + $chain.ChainPolicy.VerificationFlags = "IgnoreNotTimeValid" + + $chainsCorrectly = $chain.Build($sig.SignerCertificate) + + if (!$chainsCorrectly) { + $IsValid = $false + $failMsg += "Signer certificate doesn't chain correctly" + throw + } + + if ($chain.ChainElements.Count -le 1) { + $IsValid = $false + $failMsg += "Certificate Chain shorter than expected" + throw + } + + $rootCert = $chain.ChainElements[$chain.ChainElements.Count - 1] + + if ($rootCert.Certificate.Subject -ne $rootCert.Certificate.Issuer) { + $IsValid = $false + $failMsg += "Top-level certifcate in chain is not a root certificate" + throw + } + + if ($rootCert.Certificate.Subject -eq $MicrosoftSigningRoot2010 -or $rootCert.Certificate.Subject -eq $MicrosoftSigningRoot2011) { + $IsValid = $true + Write-Verbose "[INFO] $Filepath is signed by Microsoft as expected, trusted by machine as Valid, signed by: $($sig.SignerCertificate.Subject), Issued by: $($sig.SignerCertificate.Issuer), with Root certificate: $($rootCert.Certificate.Subject)" -Verbose + } else { + $IsValid = $false + $failMsg += "Unexpected root cert. Expected $MicrosoftSigningRoot2010 or $MicrosoftSigningRoot2011, but found $($rootCert.Certificate.Subject)" + throw $failMsg + } + } catch { + $IsValid = $false + throw $failMsg + } + + return $IsValid + } #Configure Rewrite Rule consts $HttpCookieInput = '{HTTP_COOKIE}' @@ -296,41 +339,48 @@ Function BackendCookieMitigation { $filter = "{0}/rule[@name='{1}']" -f $root, $name $filter2 = "{0}/rule[@name='{1}']" -f $root, $name2 - if (!$RollbackMitigation) { - Write-Verbose "[INFO] Starting mitigation process on $env:computername" -Verbose - - #Check if IIS URL Rewrite Module 2 is installed - Write-Verbose "[INFO] Checking for IIS URL Rewrite Module 2 on $env:computername" -Verbose + Import-Module WebAdministration - #If IIS 10 check for URL rewrite 2.1 else URL rewrite 2.0 - $RewriteModule = Get-InstalledSoftwareVersion -Name "*IIS*", "*URL*", "*2*" - $IISVersion = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp\ | Select-Object versionstring - - $RewriteModuleInstallLog = ($PSScriptRoot + '\' + 'RewriteModuleInstallLog.log') - - #Install module - if ($RewriteModule) { + if ($RollbackMitigation) { + Write-Verbose "[INFO] Starting mitigation rollback process on $env:computername" + $site = "IIS:\Sites\$WebSiteName" - #Throwing an exception if incorrect rewrite module version is installed - if ($IISVersion.VersionString -like "*10.*" -and ($RewriteModule.Version -eq "7.2.2")) { - throw "Incorrect IIS URL Rewrite Module 2.0 Installed. You need to install IIS URL Rewrite Module 2.1 to avoid instability issues." + $mitigationFound = $false + foreach ($f in @($filter, $filter2)) { + if (Get-WebConfiguration -Filter $f -PSPath $site) { + $mitigationFound = $true + Clear-WebConfiguration -Filter $f -PSPath $site } - if ($IISVersion.VersionString -notlike "*10.*" -and ($RewriteModule.Version -eq "7.2.1993")) { - throw "Incorrect IIS URL Rewrite Module 2.1 Installed. You need to install IIS URL Rewrite Module 2.0 to avoid instability issues." + } + + if ($mitigationFound) { + $Rules = Get-WebConfiguration -Filter 'system.webServer/rewrite/rules/rule' -Recurse + if ($null -eq $Rules) { + Clear-WebConfiguration -PSPath $site -Filter 'system.webServer/rewrite/rules' } - Write-Verbose "[INFO] IIS URL Rewrite Module 2 already installed on $env:computername" -Verbose + Write-Verbose "[OK] Rewrite rule mitigation removed for $env:COMPUTERNAME :: $website" + } else { + Write-Verbose "[INFO] Rewrite rule mitigation does not exist for $env:COMPUTERNAME :: $website" + } + } else { + Write-Verbose "[INFO] Starting mitigation process on $env:computername" -Verbose + Write-Verbose "[INFO] Checking for IIS URL Rewrite Module on $env:computername" -Verbose + $RewriteModule = Get-InstalledSoftwareVersion -Name "*IIS*", "*URL*", "*2*" + + if ($RewriteModule) { + Write-Verbose "[INFO] IIS URL Rewrite Module already installed on $env:computername" -Verbose } else { - #IfAutoDownloadURLRewrite if ($AutoDownloadURLRewrite) { Write-Verbose -Message "ExchangeMitigations.ps1 will now attempt to download and install the IIS URL Rewrite Module on $env:computername" -Verbose try { # Force TLS1.2 to make sure we can download from HTTPS [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $ProgressPreference = "SilentlyContinue" + $DownloadLink = Get-URLRewriteLink $DownloadDir = Join-Path $env:TEMP "IISUrlRewrite" - $DownloadLink = GetURLRewriteLink + $RewriteModuleInstallLog = Join-Path $DownloadDir "\RewriteModuleInstall.log" $FullPathToMSI = Join-Path $DownloadDir "\$($DownloadLink.Split("/")[-1])" if (!(Test-Path $DownloadDir)) { New-Item -ItemType Directory $DownloadDir | Out-Null @@ -339,92 +389,77 @@ Function BackendCookieMitigation { $response = Invoke-WebRequest $DownloadLink -UseBasicParsing [IO.File]::WriteAllBytes($FullPathToMSI, $response.Content) } catch { - throw $_ + throw "[ERROR] $_" } - } - - if ($FullPathToMSI) { - - $MSIProductVersion = GetMsiProductVersion -filename $FullPathToMSI - - #If IIS 10 assert URL rewrite 2.1 else URL rewrite 2.0 - if ($IISVersion.VersionString -like "*10.*" -and $MSIProductVersion -eq "7.2.2") { - throw "Incorrect MSI for IIS $($IISVersion.VersionString), please use URL rewrite 2.1" - } - if ($IISVersion.VersionString -notlike "*10.*" -and $MSIProductVersion -eq "7.2.1993") { - throw "Incorrect MSI for IIS $($IISVersion.VersionString), please use URL rewrite 2.0" - } - - Write-Verbose "[INFO] Installing IIS URL Rewrite Module 2" -Verbose - $arguments = " /i " + '"' + $FullPathToMSI.FullName + '"' + " /quiet /log " + '"' + $RewriteModuleInstallLog + '"' - $msiexecPath = $env:WINDIR + "\System32\msiexec.exe" - Start-Process -FilePath $msiexecPath -ArgumentList $arguments -Wait - Start-Sleep -Seconds 15 - $RewriteModule = Get-InstalledSoftware -Name *IIS* | Where-Object { $_.Name -like "*URL*" -and $_.Name -like "*2*" } - if ($RewriteModule) { - Write-Verbose "[OK] IIS URL Rewrite Module 2 installed on $env:computername" - } else { - throw "[ERROR] Issue installing IIS URL Rewrite Module 2, please review $($RewriteModuleInstallLog)" + } elseif ($FullPathToMSI -and (Test-Path $FullPathToMSI)) { + try { + $MSIPath = (Resolve-Path $FullPathToMSI).Path + $RewriteModuleInstallLog = Join-Path (Get-Item $MSIPath).DirectoryName -ChildPath "RewriteModuleInstall.log" + } catch { + throw "[ERROR $_" } - } else { - throw "[ERROR] Unable to proceed on $env:computername, path to IIS URL Rewrite Module MSI not provided and module is not installed." } - } - foreach ($website in $WebSiteNames) { - Write-Verbose "[INFO] Applying rewrite rule configuration to $env:COMPUTERNAME :: $website" + $MSIProductVersion = Get-MsiProductVersion -filename $FullPathToMSI - $site = "IIS:\Sites\$($website)" + if ($MSIProductVersion -lt "7.2.1993") { + throw "[ERROR] Incorrect IIS URL Rewrite Module downloaded on $env:computername" + } - try { - if ((Get-WebConfiguration -Filter $filter -PSPath $site).name -eq $name) { - Clear-WebConfiguration -Filter $filter -PSPath $site - } + #KB2999226 required for IIS Rewrite 2.1 on IIS ver under 10 + if (!(Test-IIS10) -and !(Get-HotFix -Id "KB2999226" -ErrorAction SilentlyContinue)) { + throw "[ERROR] Did not detect the KB2999226 on $env:computername. Please review the pre-reqs for this KB and download from https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c" + } - if ((Get-WebConfiguration -Filter $filter2 -PSPath $site).name -eq $name2) { - Clear-WebConfiguration -Filter $filter2 -PSPath $site - } + Write-Verbose "Installing the IIS URL Rewrite Module on $env:computername" -Verbose + $arguments = "/i `"$FullPathToMSI`" /quiet /log `"$RewriteModuleInstallLog`"" + $msiexecPath = $env:WINDIR + "\System32\msiexec.exe" - Add-WebConfigurationProperty -PSPath $site -filter $root -name '.' -value @{name = $name; patternSyntax = 'Regular Expressions'; stopProcessing = 'False' } - Set-WebConfigurationProperty -PSPath $site -filter "$filter/match" -name 'url' -value $inbound - Set-WebConfigurationProperty -PSPath $site -filter "$filter/conditions" -name '.' -value @{input = $HttpCookieInput; matchType = '0'; pattern = $pattern; ignoreCase = 'True'; negate = 'False' } - Set-WebConfigurationProperty -PSPath $site -filter "$filter/action" -name 'type' -value 'AbortRequest' + if (!(Confirm-Signature -filepath $FullPathToMSI -Stage $stage)) { + throw "[ERROR] File present at $FullPathToMSI does not seem to be signed as expected, stopping execution." + } - Add-WebConfigurationProperty -PSPath $site -filter $root -name '.' -value @{name = $name2; patternSyntax = 'Regular Expressions'; stopProcessing = 'True' } - Set-WebConfigurationProperty -PSPath $site -filter "$filter2/match" -name 'url' -value $inbound - Set-WebConfigurationProperty -PSPath $site -filter "$filter2/conditions" -name '.' -value @{input = $HttpCookieInput; matchType = '0'; pattern = $pattern2; ignoreCase = 'True'; negate = 'False' } - Set-WebConfigurationProperty -PSPath $site -filter "$filter2/action" -name 'type' -value 'AbortRequest' + Start-Process -FilePath $msiexecPath -ArgumentList $arguments -Wait + Start-Sleep -Seconds 15 + $RewriteModule = Get-InstalledSoftwareVersion -Name "*IIS*", "*URL*", "*2*" - Write-Verbose "[OK] Rewrite rule configuration complete for $env:COMPUTERNAME :: $website" - Get-WebConfiguration -Filter $filter -PSPath $site - Get-WebConfiguration -Filter $filter2 -PSPath $site - } catch { - throw $_ + if ($RewriteModule) { + Write-Verbose "[OK] IIS URL Rewrite Module installed on $env:computername" + } else { + throw "[ERROR] Issue installing IIS URL Rewrite Module, please review $($RewriteModuleInstallLog)" } } - } else { - Write-Verbose "[INFO] Starting mitigation rollback process on $env:computername" - foreach ($website in $WebSiteNames) { - $site = "IIS:\Sites\$($website)" + Write-Verbose "[INFO] Applying URL Rewrite configuration to $env:COMPUTERNAME :: $WebSiteName" -Verbose + $site = "IIS:\Sites\$WebSiteName" - $MitigationConfig = Get-WebConfiguration -Filter $filter -PSPath $site - if ($MitigationConfig) { + try { + if ((Get-WebConfiguration -Filter $filter -PSPath $site).name -eq $name) { Clear-WebConfiguration -Filter $filter -PSPath $site - Clear-WebConfiguration -Filter $filter2 -PSPath $site + } - $Rules = Get-WebConfiguration -Filter 'system.webServer/rewrite/rules/rule' -Recurse - if ($null -eq $Rules) { - Clear-WebConfiguration -PSPath $site -Filter 'system.webServer/rewrite/rules' - } - Write-Verbose "[OK] Rewrite rule mitigation removed for $env:COMPUTERNAME :: $website" - } else { - Write-Verbose "[INFO] Rewrite rule mitigation does not exist for $env:COMPUTERNAME :: $website" + if ((Get-WebConfiguration -Filter $filter2 -PSPath $site).name -eq $name2) { + Clear-WebConfiguration -Filter $filter2 -PSPath $site } + + Add-WebConfigurationProperty -PSPath $site -filter $root -name '.' -value @{name = $name; patternSyntax = 'Regular Expressions'; stopProcessing = 'False' } + Set-WebConfigurationProperty -PSPath $site -filter "$filter/match" -name 'url' -value $inbound + Set-WebConfigurationProperty -PSPath $site -filter "$filter/conditions" -name '.' -value @{input = $HttpCookieInput; matchType = '0'; pattern = $pattern; ignoreCase = 'True'; negate = 'False' } + Set-WebConfigurationProperty -PSPath $site -filter "$filter/action" -name 'type' -value 'AbortRequest' + + Add-WebConfigurationProperty -PSPath $site -filter $root -name '.' -value @{name = $name2; patternSyntax = 'Regular Expressions'; stopProcessing = 'True' } + Set-WebConfigurationProperty -PSPath $site -filter "$filter2/match" -name 'url' -value $inbound + Set-WebConfigurationProperty -PSPath $site -filter "$filter2/conditions" -name '.' -value @{input = $HttpCookieInput; matchType = '0'; pattern = $pattern2; ignoreCase = 'True'; negate = 'False' } + Set-WebConfigurationProperty -PSPath $site -filter "$filter2/action" -name 'type' -value 'AbortRequest' + + Write-Verbose "[OK] Rewrite rule configuration complete for $env:COMPUTERNAME :: $website" + } catch { + throw "[ERROR] Mitigation failed on $env:COMPUTERNAME :: $WebSiteName - $_" } } } + Function UnifiedMessagingMitigation { [CmdLetBinding()] param( @@ -474,6 +509,7 @@ Function UnifiedMessagingMitigation { Get-Service MSExchangeUMCR } } + Function ECPAppPoolMitigation { [CmdLetBinding()] param(