Share via


Verifying Spectre / Meltdown protections remotely

In this post we will take a look at the SpeculationControl PowerShell module that was recently released by the Microsoft Security Response Center to help with verifying Spectre / Meltdown protections.

SpeculationControl can be found on the PowerShell Gallery at the following link: https://www.powershellgallery.com/packages/SpeculationControl

Installing this module onto a system adds a new function called Get-SpeculationControlSettings and this function can be run on a system to provide details on whether Spectre / Meltdown protections have been enabled.

What if you wanted to run this remotely against multiple systems?

To run the Get-SpeculationControlSettings function against multiple systems, see the example code below:
(Credit goes to Keith Hitchcock for his help on this)

This example only requires that you have the SpeculationControl PowerShell module installed on the system that you execute this code from. Because of the way the Get-SpeculationControlSettings function is structured, we can simply load the function remotely as part of the call to Invoke-Command.

In order to run this sample code in an environment, the only update required is the list of machines that follow -ComputerName. If you prefer to pass in a list of systems in a text file, the sample code can easily be modified to take in an input text file by utilizing the Get-Content cmdlet.

Sample output

While this is nice, we can take things a step further by outputting the results to CSV which will make things easier to consume, especially as we start adding more systems to the list.

Example code below:

Sample output

This is now easier to digest, and we can sort and apply filters as needed.

At this point, we have taken the SpeculationControl PowerShell module and run it through a few examples that take it beyond local execution and help us review remote systems in an environment.

Next, we will take a look at using the SpeculationControl PowerShell module along with another PowerShell module called DSCEA. DSCEA provides configuration testing and reporting capabilities for Windows based systems, and we will take a look at how we can use it to gain some intelligence from the data that we are able to gather remotely.

For example, let’s say your management team is looking for numbers, specifically how many machines exist in your environment that have not yet been patched for the CVE-2017-5754 rogue data cache load (Meltdown) vulnerability.

While we could ask someone to look through the CSV file and compare systems across multiple columns, I’d rather have a computer provide me with this information.

There are a few points to make though before we go down the DSCEA path. DSCEA requires a minimum PowerShell version of 5.0, with 5.1 being recommended. Also, DSCEA would require that the SpeculationControl PowerShell module be installed on all endpoints that are being scanned. While there are some easy ways to handle this which include pushing out a DSC configuration that utilizes the DSC File resource, or just a file copy script, for this example I am including the entire Get-SpeculationControlSettings function as a part of my custom DSC configuration. This just makes this a whole lot easier to demonstrate, but it does require code updates if there are updates to the SpeculationControl PowerShell module in the future.

This section will assume you have downloaded DSCEA and have some knowledge of its usage. If you don’t, click here to learn more.

I have copied the DSC configuration at the end of this post that will be used to verify if systems have been patched for Meltdown. You will use this configuration to build a MOF file that you will use with DSCEA to scan systems to see if they have the proper updates and configurations enabled.

The configuration comes with the following logic defined to determine if a system has been properly configured in regards to Meltdown:

DSCEA HTML Report Example
In this case, all 3 systems are non-compliant, meaning they need to be reviewed to get the proper updates and settings applied.

DSC Configuration

Comments

  • Anonymous
    January 06, 2018
    The comment has been removed
    • Anonymous
      January 07, 2018
      Thank you Rob! It looks like my code samples ran into issues once the module was updated with a signature block. I have integrated your suggestion into the code and everything seems to be working properly now. For those with comments below that relate to this issue, please grab the new code snippets and try again. I have updated both the PowerShell and DSC code.
  • Anonymous
    January 06, 2018
    The comment has been removed
  • Anonymous
    January 06, 2018
    I seem to be having trouble running the scriptblock (I am running this on 5.1). I get a "Executable script code found in signature block".Also, the DSC Configuration seems to have errors.
  • Anonymous
    January 07, 2018
    Great Job!!!!, Thank u!!
  • Anonymous
    January 07, 2018
    I think one of the best practicies to overcome meltdown is using this website first :https://meltdownattack.com/by the way, your post was quite interesting, thank you!
  • Anonymous
    January 07, 2018
    Hi Ralph great if you use DSC, but I am looking for SCCM compliance settings , any idea if your colleagues in SCCM land are looking to do something similar to assist an enterprise looking to manage this path release?
    • Anonymous
      January 07, 2018
      Hi BritV8, please review the following sample that Ken Wygant, Microsoft Sr PFE - Configuration Manager has shared out:https://twitter.com/pfeken/status/949395268696530945
  • Anonymous
    January 07, 2018
    The comment has been removed
  • Anonymous
    January 08, 2018
    I wrote a little wrapper script for this, hope you find it useful. function Get-SpectreMeltdownStatus{ [CmdletBinding()] Param ( # Computername [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [string[]]$ComputerName, #The Full FileName of the export file. [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [string[]]$ExportFileName ) Begin { if (-not(Get-Module -name SpeculationControl)){ Try{ Import-Module Import-Module SpeculationControl } Catch{ Write-Warning "PowerShell Module SpeculationControl is not installed on this client" Write-Warning "Install module first: https://www.powershellgallery.com/packages/SpeculationControl/1.0.2" Throw } } } Process { $OutPut = @() ForEach ($RemoteComp in $ComputerName) { Write-Verbose "Processing: $RemoteComp" $scriptstring = Get-Content -Path (Get-Module SpeculationControl).Path | % { if (-not ($_ -match “^# “)) { $_ }} | Out-String $scriptstring += function Write-Host {} $scriptstring += "Get-SpeculationControlSettings" $script=[scriptblock]::create($scriptstring) $results = Invoke-Command -ComputerName $RemoteComp -ScriptBlock $script $compliance = $false if ($results.KVAShadowRequired -eq $False) { $compliance = $True } elseif ($results.KVAShadowRequired -eq $True -and $results.KVAShadowWindowsSupportPresent -eq $True -and $results.KVAShadowWindowsSupportEnabled -eq $True -and ` $results.KVAShadowPcidEnabled -eq $True) { $compliance = $True } Write-Verbose "Compliance: $($compliance)" $results | Add-Member -MemberType NoteProperty -Name "Compliant" -Value $compliance $OutPut = $OutPut + $results } } End { Write-Verbose "Exporting Results to $ExportFileName" If (Test-Path $ExportFileName) { Write-Warning "File $ExportFileName already exists, delete the file manually or specify another file name" } Else { $OutPut | Export-Csv -Path "$ExportFileName" -NoTypeInformation -NoClobber } }}
  • Anonymous
    January 09, 2018
    Thanks guys! To mitigate this completely you'd have to install a patch right? (Windows patch and Vendor patch)I can see the vendor patch could be a challenge for you to control, but ideally the script should check for installed Microsoft patches. I'm struggling a little to find which hotfix to check for. What to you recommend to check for? - KB 4056888-4056892 or 4054022?Secondly - The script returns $compliance = true if the KVAShadowRequired is disabled - regardsless of any of the remaining "KVA..." settings? And if KVAShadowRequired is enabled - all 4 "KVA.." settings has to be true to be compliant.I'm asking since there are already a bunch of alternative checks available and I see some conflicting messages.Can you provide any input to make the check even more effecient?
    • Anonymous
      January 09, 2018
      The comment has been removed
  • Anonymous
    January 09, 2018
    Running this against various lists of servers, I receive repeated instances of the following error:Unsupported processor manufacturer: + CategoryInfo : OperationStopped: (Unsupported processor manufacturer: :String) [], RuntimeException + FullyQualifiedErrorId : Unsupported processor manufacturer: + PSComputerName :
  • Anonymous
    January 09, 2018
    I can't get these scripts to work. They run until they hit the first error and then stop operating. The error is:Unsupported processor manufacturer: At script.ps1:22 char:1+ $results = Invoke-Command -ComputerName $Server -ScriptBlock $script -ErrorActio ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Unsupported processor manufacturer: :String) [], RuntimeException + FullyQualifiedErrorId : Unsupported processor manufacturer:
    • Anonymous
      January 09, 2018
      The comment has been removed
      • Anonymous
        January 10, 2018
        In some cases I have this, it appears to be the Model number that is not matching, yet am sure the CPU is on the affected hardware list.One example I have gives this on the WMI query:Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHzIntel64 Family 6 Model 63 Stepping 2 63 = 0x3F in Hex and is not in the script. Is this an unaffected CPU?if ($result.Success) { $family = [System.UInt32]$result.Groups[1].Value $model = [System.UInt32]$result.Groups[2].Value $stepping = [System.UInt32]$result.Groups[3].Value if (($family -eq 0x6) -and (($model -eq 0x1c) -or ($model -eq 0x26) -or ($model -eq 0x27) -or ($model -eq 0x36) -or ($model -eq 0x35))) { $kvaShadowRequired = $false }
        • Anonymous
          January 10, 2018
          The code above for verifying the CPU manufacturer does not support multiple CPUs.
  • Anonymous
    January 17, 2018
    Script looks great, how would I run this against all computers in ADUC instead of exporting into text file?
    • Anonymous
      January 29, 2018
      Import-Module -Name SpeculationControlInvoke-Command -ComputerName (Get-Content d:\temp\ServerList.txt) ${function:Get-SpeculationControlSettings} | export-csv D:\temp\check_29012018.csv -NoTypeInformation
  • Anonymous
    February 01, 2018
    Hello Ralph,I'm facing an issue when trying to run the codeThe codeImport-Module SpeculationControl$scriptstring = Get-Content -Path (Get-Module SpeculationControl).Path | % { if (-not ($_ -match “^# “)) { $_ }} | Out-String$scriptstring += 'function Write-Host {}'$scriptstring += 'Get-SpeculationControlSettings'$script=[scriptblock]::create($scriptstring)$InputFile = "C:\computers.txt"$RemoteComputers = Get-Content $InputFile$results = Invoke-Command -ComputerName $RemoteComputers -ScriptBlock $script$results | Export-Csv .\SpeculationControlSettings.csv -NoTypeInformationThe Error**************************************************************************************************************************************[172.28.0.58] Connecting to remote server 172.28.0.58 failed with the following error message : The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You can get more information about that by running the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic. + CategoryInfo : OpenError: (172.28.0.58:String) [], PSRemotingTransportException + FullyQualifiedErrorId : ServerNotTrusted,PSSessionStateBroken**************************************************************************************************************************************Need your help Thank you in advance