Fist of Tech

VMware CVE-2020-4004 workaround using PowerCLI

Photo by Markus Spiske on Pexels.com

This post is about a recent vulnerability published by VMware, allowing hackers to run code on the virtual machines host system. The following PowerCLI functions will help you to set up the workaround faster.

Official statement of VMware: https://www.vmware.com/security/advisories/VMSA-2020-0026.html

Description by VMware

VMware ESXi, Workstation, and Fusion contain a use-after-free vulnerability in the XHCI USB controller. VMware has evaluated the severity of this issue to be in the Critical severity range with a maximum CVSSv3 base score of 9.3.

Known Attack Vectors by VMware

A malicious actor with local administrative privileges on a virtual machine may exploit this issue to execute code as the virtual machine’s VMX process running on the host.

Workaround

The suggested workaround for this issue is to remove the XHCI controllers from your virtual machines. But if you are working in a big environment you need to apply this workaround to a couple of hundred machines. Add the following two functions to your PowerShell/PowerCLI script to get the adapters and in the next step to remove the adapters. Please note this is not a full script, it is a function that does not exist in PowerCLI 6.5. Since I do not want to be the one responsible for crashing your environment, I decided to share the functions instead of a full script. Remove all the USB-Devices first!

This is inspired by a script that appeared in 2013 in the VMware community, sadly I don’t remember who wrote it. (If you know please send me a message)

Edit: 23.11.2020 – Changed the functions for better output and added a function to add the controlers again, after the patching is done.

Function Remove-USB3Controller {
    Param (
    [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
    $VM
    )
    Process {
        $VMConf = New-Object VMware.Vim.VirtualMachineConfigSpec
        $VMConf.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMConf.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMConf.deviceChange[0].operation = “remove”
        $Device = $VM.ExtensionData.Config.Hardware.Device | ForEach-Object {
            $_ | Where-Object {$_.gettype().Name -like "*xHCI*"}
        }
        $VMConf.deviceChange[0].device = $Device
        $VM.ExtensionData.ReconfigVM_Task($VMConf)
    }
}

Function Add-USB3Controller {
    Param (
    [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
    $VM
    )
    Process {
        $VMConf = New-Object VMware.Vim.VirtualMachineConfigSpec
        $VMConf.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMConf.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMConf.deviceChange[0].operation = “add”
        $VMConf.DeviceChange[0].Device = New-Object VMware.Vim.VirtualUSBXHCIController
        $VM.ExtensionData.ReconfigVM_Task($VMConf)
    }
}

Function Get-USB3Controller {
    Param (
    [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
    $VM
    )
    Process {
        Foreach ($VMachine in $VM) {
            Foreach ($Device in $VMachine.ExtensionData.Config.Hardware.Device) {
                If ($Device.gettype().Name -like "*xHCI*"){
                    $Details = New-Object PsObject
                    $Details | Add-Member Noteproperty VM -Value $VMachine
                    $Details | Add-Member Noteproperty USB3Controller -Value True
                    return $Details
                }
            }
        }
        $Details = New-Object PsObject
        $Details | Add-Member Noteproperty VM -Value $VMachine
        $Details | Add-Member Noteproperty USB3Controller -Value False
        return $Details
                
    }
}

To test this use the following lines:

$TestVM = Get-VM -Name "TestVM"
$TestVM | Get-USB3Controller
Remove-USB3Controller -VM $TestVM
$TestVM | Add-USB3Controller

Yes, you can run this against your whole environment, but please make sure you remove all the USB Devices first. This can be done by using the Remove-USB device cmdlet or by removing the devices manually.

Exit mobile version