CVE-2022-0001

We have this vulnerability on all endpoints, the solution is installing KB5065426 and that KB is installed on all endpoints. Is anyone else experiencing this?

1 Like

Yes, confirming we see the same here today, showing on all Windows endpoints.

The “proof” is checking for a registry key that needs to be manually set, and is then causing the latest months MS patches to show as missing when they are actually installed.

1 Like

you need KB5065426 … AND:

1-reg add “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management” /v FeatureSettingsOverride /t REG_DWORD /d 0x00800000 /f

2-reg add “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management” /v FeatureSettingsOverrideMask /t REG_DWORD /d 0x00000003 /f

Do you have a Rapid7 Support case open for this? If so, would you mind sharing the number please?

This is the way - We went with a different mask - Here’s a PS script for it.

# Remediation: Enable speculative execution mitigations incl. BHI on Windows
# Per MS KB (combined): FeatureSettingsOverride = 0x00802048, Mask = 0x00000003
# Hive: HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
# Exit 0 on success; 1 on any failure.

$ErrorActionPreference = 'Stop'

# --- Config (override here if needed) ---
$RegPath        = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management'
$DesiredOverride = 0x00802048  # BHI (0x00800000) + additional mitigations (0x00002048)
$DesiredMask     = 0x00000003

# --- Logging ---
$LogDir  = 'C:\tools'
$LogFile = Join-Path $LogDir 'Remediate_SpecExecMitigations.log'
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
function Log {
    param([string]$Message)
    $ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    $line = "$ts  $Message"
    $line | Out-File -FilePath $LogFile -Append -Encoding utf8
    Write-Output $line
}

try {
    Log "Starting remediation for speculative execution mitigations (BHI included)."
    Log "Target key: $RegPath"
    Log ("Desired FeatureSettingsOverride: 0x{0:X8} ({1})" -f $DesiredOverride, [int]$DesiredOverride)
    Log ("Desired FeatureSettingsOverrideMask: 0x{0:X8} ({1})" -f $DesiredMask, [int]$DesiredMask)

    # Ensure key exists
    if (-not (Test-Path $RegPath)) {
        Log "Key missing; creating: $RegPath"
        New-Item -Path $RegPath -Force | Out-Null
    } else {
        Log "Key exists."
    }

    # Set Override
    if (-not (Get-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverride' -ErrorAction SilentlyContinue)) {
        Log ("Creating FeatureSettingsOverride as DWORD = 0x{0:X8}" -f $DesiredOverride)
        New-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverride' -PropertyType DWord -Value ([int]$DesiredOverride) -Force | Out-Null
    } else {
        Log ("Setting FeatureSettingsOverride = 0x{0:X8}" -f $DesiredOverride)
        Set-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverride' -Value ([int]$DesiredOverride)
    }

    # Set Mask
    if (-not (Get-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverrideMask' -ErrorAction SilentlyContinue)) {
        Log ("Creating FeatureSettingsOverrideMask as DWORD = 0x{0:X8}" -f $DesiredMask)
        New-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverrideMask' -PropertyType DWord -Value ([int]$DesiredMask) -Force | Out-Null
    } else {
        Log ("Setting FeatureSettingsOverrideMask = 0x{0:X8}" -f $DesiredMask)
        Set-ItemProperty -Path $RegPath -Name 'FeatureSettingsOverrideMask' -Value ([int]$DesiredMask)
    }

    # Verify
    $actualOverride = [int](Get-ItemPropertyValue -Path $RegPath -Name 'FeatureSettingsOverride')
    $actualMask     = [int](Get-ItemPropertyValue -Path $RegPath -Name 'FeatureSettingsOverrideMask')

    $ok = $true
    if ($actualOverride -ne [int]$DesiredOverride) {
        Log ("VERIFICATION FAILED: FeatureSettingsOverride expected 0x{0:X8} but read 0x{1:X8}" -f $DesiredOverride, $actualOverride)
        $ok = $false
    } else {
        Log ("OK: FeatureSettingsOverride = 0x{0:X8}" -f $actualOverride)
    }
    if ($actualMask -ne [int]$DesiredMask) {
        Log ("VERIFICATION FAILED: FeatureSettingsOverrideMask expected 0x{0:X8} but read 0x{1:X8}" -f $DesiredMask, $actualMask)
        $ok = $false
    } else {
        Log ("OK: FeatureSettingsOverrideMask = 0x{0:X8}" -f $actualMask)
    }

    if ($ok) {
        Log "Remediation successful. (Note: some mitigations may require a reboot to fully take effect.)"
        exit 0
    } else {
        Log "Remediation completed but verification failed."
        exit 1
    }
}
catch {
    Log ("ERROR: {0}" -f $_.Exception.Message)
    exit 1
}
1 Like

Thank you for sharing.

It’s likely that different environments will need different values as you suggest. I’ve always wondered why Microsoft went with a pair of bitmaps to control this many feature flags, when they could instead have used individual registry values, which might have been easier to understand at a glance.

Since the script already creates a log file, is it worth also logging the existing registry value/data, if any? I admit this isn’t likely to be needed, but I’ve never regretted having the capability to revert a change.

Heads up, your script uses the value 0x00802048. This is the value for a machine with HyperThreading disabled.

The value in your script is HEAVILY implied by the Microsoft support page to be the right value. If you look very, very closely, the value actually needs to be 0x00800048. The section outlining all mitigations combined with HT on is (decimal) 72, which converts to 48 in hex, whereas the example they give is (decimal) 8264, which converts to 2048 in hex. So your script works for the registry detection in Rapid7, but if the goal is actual enhanced security, then 0x00800048 (or as a reddit post quoting a CrowdStrike article locked behind login states, “8388680” in decimal) is correct.

….assuming you want Hyper Threading on, which maybe I’m a big ol’ security n00b, but that seems like a pretty essential part of modern computing.