<# .SYNOPSIS CVE Detection - CVE-2024-30103 .DESCRIPTION This script checks the installed version of Office "Click-to-Run" installations to ascertain whether the installed version is vulnerable to CVE-2024-30103 which affects Outlook for Windows. PLEASE NOTE: The checks in this script are "static" that is to say they will become outdated as new updates are released. This script should be used as a reference and not as a definitive source of information. It is intended for a short-term response to a specific vulnerability. .NOTES 2023-06-15: Initial version .LINK Blog post: https://homotechsual.dev/2024/02/13/CVE-Monitoring-NinjaOne/ CVE Details: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-30103 Discovery: https://blog.morphisec.com/cve-2024-30103-microsoft-outlook-vulnerability #> $IsC2R = Test-Path 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun' if ($IsC2R) { # Get the installed Office Version $OfficeVersion = [version]( Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration' | Select-Object -ExpandProperty VersionToReport ) # Get the installed Office Product IDs $OfficeProductIds = ( Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration' | Select-Object -ExpandProperty ProductReleaseIds ) } else { Write-Error 'No Click-to-Run Office installation detected. This script only works with Click-to-Run Office installations.' Exit 1 } $IsM365 = ($OfficeProductIds -like '*O365*') -or ($OfficeProductIds -like '*M365*') $M365Channels = @( @{ ID = 'Current' Name = 'Current' PatchedVersion = [version]'16.0.17628.20144' }, @{ ID = 'FirstReleaseCurrent' Name = 'Current (Preview)' PatchedVersion = [version]'16.0.17726.20078' }, @{ ID = 'MonthlyEnterprise' Name = 'Monthly Enterprise' PatchedVersion = @( [version]'16.0.17531.20190', [version]'16.0.17425.20258' ) }, @{ ID = 'Deferred' Name = 'Semi-Annual Enterprise' PatchedVersion = @( [version]'16.0.16731.20716', [version]'16.0.16130.21026' ) }, @{ # This does not match Microsoft's documented version but is the latest available update on tested SAE-Preview channel installations. ID = 'FirstReleaseDeferred' Name = 'Semi-Annual Enterprise (Preview)' PatchedVersion = [version]'16.0.17328.20414' }, @{ ID = 'InsiderFast' Name = 'Beta' PatchedVersion = [version]'16.0.17809.20000' } ) $Vulnerable = $false if ($IsM365) { # Check the Office GPO settings for the update channel. $OfficeUpdateChannelGPO = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Office\16.0\Common\OfficeUpdate' -ErrorAction 'SilentlyContinue' | Select-Object -ExpandProperty UpdateBranch -ErrorAction 'SilentlyContinue') if ($OfficeUpdateChannelGPO) { Write-Output 'Office is configured to use a GPO update channel.' foreach ($Channel in $M365Channels) { if ($OfficeUpdateChannelGPO -eq $Channel.ID) { $OfficeChannel = $Channel } elseif ($OfficeVersion.Build -in $Channel.PatchedVersion.Build) { $OfficeChannel = $Channel } } } else { $C2RConfigurationPath = 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration' Write-Output 'Office is not configured to use a GPO update channel.' # Get the UpdateUrl if set $OfficeUpdateURL = [System.Uri](Get-ItemProperty -Path $C2RConfigurationPath -ErrorAction 'SilentlyContinue' | Select-Object -ExpandProperty UpdateURL -ErrorAction 'SilentlyContinue') # Get the UnmanagedUpdateUrl if set $OfficeUnmanagedUpdateURL = [System.Uri](Get-ItemProperty -Path $C2RConfigurationPath -ErrorAction 'SilentlyContinue' | Select-Object -ExpandProperty UnmanagedUpdateURL -ErrorAction 'SilentlyContinue') # Get the Office Update CDN URL $OfficeUpdateChannelCDNURL = [System.Uri](Get-ItemProperty -Path $C2RConfigurationPath -ErrorAction 'SilentlyContinue' | Select-Object -ExpandProperty CDNBaseUrl -ErrorAction 'SilentlyContinue') # Get just the channel GUID if ($OfficeUpdateURL.IsAbsoluteUri) { $OfficeUpdateGUID = $OfficeUpdateURL.Segments[2] } elseif ($OfficeUnmanagedUpdateURL.IsAbsoluteUri) { $OfficeUpdateGUID = $OfficeUnmanagedUpdateURL.Segments[2] } elseif ($OfficeUpdateChannelCDNURL.IsAbsoluteUri) { $OfficeUpdateGUID = $OfficeUpdateChannelCDNURL.Segments[2] } else { Write-Error 'Unable to determine Office update channel URL.' Exit 1 } foreach ($Channel in $M365Channels) { if ($OfficeUpdateGUID -eq $Channel.ID) { $OfficeChannel = $Channel } elseif ($OfficeVersion.Build -in $Channel.PatchedVersion.Build) { $OfficeChannel = $Channel } } } if (-not $OfficeChannel) { Write-Error 'Unable to determine Office update channel.' Exit 1 } else { Write-Output ("{0} found using the {1} update channel. `r`nChannel ID: {2}. `r`nTarget Version: {3}. `r`nDetected Version: {4}" -f 'Microsoft 365 Apps', $OfficeChannel.Name, $OfficeChannel.ID, $OfficeChannel.PatchedVersion, $OfficeVersion) } } if ( $OfficeVersion.Major -eq '16' ) { if ($IsO365) { # Handle Microsoft 365 Apps foreach ($PatchedVersion in $OfficeChannel.PatchedVersion) { if ($OfficeVersion.Build -eq $PatchedVersion.Build) { if ($OfficeVersion.Revision -lt $PatchedVersion.Revision) { Write-Output ("{0} found. `r`nTarget Version: {1}. `r`nDetected Version: {2}" -f 'Microsoft 365 Apps', $PatchedVersion, $OfficeVersion) $Vulnerable = $true } } } if ($OfficeVersion -lt $OfficeChannel.PatchedVersion) { $Vulnerable = $true } } elseif ( ( $OfficeVersion.Build -ge 10356) -and ( $OfficeVersion.Build -le 10411 ) -and ( $OfficeProductIds -like '*2019Volume*' ) -and ( $OfficeProductIds -like '*2019Volume*' ) ) { # Handle VL Office 2019 if ( ( $OfficeVersion.Build -lt 10411 ) -and ( $OfficeVersion.Revision -lt 20011 ) ) { Write-Output ("{0} found. `r`nTarget Version: {1}. `r`nDetected Version: {2}" -f 'Office 2019 VL', [Version]'16.0.10396.20023', $OfficeVersion) $Vulnerable = $true } } elseif ( ( $OfficeVersion.Build -ge 12527 ) -and ( $OfficeVersion.Build -le 17628 ) -and ( $OfficeProductIds -like '*Retail*' ) ) { # Handle Office 2021 Retail, Office 2019 Retail and Office 2016 Retail if ( ( $OfficeVersion.Build -lt 17628 ) -and ( $OfficeVersion.Revision -lt 20144 ) ) { Write-Output ("{0} found. `r`nTarget Version: {1}. `r`nDetected Version: {2}" -f 'Office 2021, 2019 or 2016 Retail', [Version]'16.0.16130.20306', $OfficeVersion) $Vulnerable = $true } } elseif ( ( $OfficeVersion.Build -eq 14332 ) -and ( $OfficeProductIds -like '*2021Volume*' ) ) { # Handle VL Office LTSC 2021 if ( ( $OfficeVersion.Build -ne 14332 ) -and ( $OfficeVersion.Revision -lt 20721 ) ) { Write-Output ("{0} found. `r`nTarget Version: {1}. `r`nDetected Version: {2}" -f 'Office LTSC 2021', [Version]'16.0.14332.20481', $OfficeVersion) $Vulnerable = $true } } } if ($true -eq $Vulnerable) { Write-Warning 'This version of Office is vulnerable to CVE-2024-30103.' Ninja-Property-Set CVE202430103 1 } elseif ($false -eq $Vulnerable) { Write-Output 'This version of Office is not vulnerable to CVE-2024-30103.' Ninja-Property-Set CVE202430103 0 } else { Write-Warning 'Could not determine vulnerability status.' }