PowerCLI to check for Python Exploit in VMware

About a week ago, I read about a python exploit that was targeting ESXi servers. I looked up the 2 CVE that were related to the exploit, CVE-2019-5544 and CVE-2020-3992. I then wanted to see if these CVE had been patched by VMware, and they have via the VMSA-2019-0022 and VMSA-2020-0023.3. Which I’ve already patched for, but I was still curious as to the contents of the file ‘/etc/rc.local.d/local.sh’. So I took to my PowerShell ISE to see what I could find.

I took the bones from another script that I have to uses Plink.exe to programmatically run commands against my ESXi hosts, and runs a simple command.

$Cluster = "Cluster1"
$VMhosts = Get-Cluster $Cluster | Get-VMhost | Sort
$Plink = "C:\scripts\applications\plink\plink.exe"
$User = "username"
$Pswd = "password"
$plinkoptions = " -v -batch -pw $Pswd"
$Logfile = "C:\scripts\logs\VMware_CVE-2020-3992.txt"

So the above starts the script and gathers the VMhosts that i want to check. I ran this script against my clusters one at a time. I then created an alias for the Plink executable so I don’t have to type out the entire directory path to it. Created variables for the username and password to be used in the script. Lastly, I have a logfile to save all of the results of the script after it finishes for the host.

foreach ($VMhost in $VMhosts){
    SSHService $VMhost on
    
    # command to run
    $cmd = "cat /etc/rc.local.d/local.sh"
    
    $remoteCommand = '"' + $cmd + '"'
    $command = $plink + " " + $plinkoptions + " " + $User + "@" + $VMhost + " " + $remoteCommand
    $msg = Invoke-Expression -command $command 
    $VMhost.name | out-file $Logfile -Append
    $msg | out-file $Logfile -Append
    "" | Out-file $Logfile -Append

    SSHService $VMhost Off
}

This section of the script loops through the VMhosts that are in the cluster that was targeted in the first section of the script. I use a custom function (See below) to turn on the SSH service, if you leave SSH on, you can remove this line. I create a variable with the Linux command that I want to run. Then I format the Plink command to run. Invoke-Expression is used to run the command and its saved to the variable $msg which is then written to the logfile that was defined in the open lines of the script. I also include the hostname before the output and a blank line after to not crowd the logfile.

The output of the logfile should look like the following given that you haven’t be exploited.

ESXi.hostname
#!/bin/sh ++group=host/vim/vmvisor/boot

# local configuration options

# Note: modify at your own risk!  If you do/use anything in this
# script that is not part of a stable API (relying on files to be in
# specific places, specific tools, specific output, etc) there is a
# possibility you will end up with a broken system after patching or
# upgrading.  Changes are not supported unless under direction of
# VMware support.

# Note: This script will not be run when UEFI secure boot is enabled.

exit 0

SSHService – My custom function

This was a function that i wrote a long time ago as I alway keep SSH turned off on my ESXi hosts.

function SSHService
{
    [CmdletBinding()]
Param(
  [Parameter(Mandatory=$True)]
   [string]$VMhost,
	
   [Parameter(Mandatory=$True)]
   [ValidateSet("On","Off")]$State
)
If ($State -eq "On"){Get-vmhost $VMhost | Get-VMHostService | WHere KEY -EQ "TSM-SSH" | Start-VMHostService}
If ($State -eq "Off"){Get-vmhost $VMhost | Get-VMHostService | WHere KEY -EQ "TSM-SSH" | Stop-VMHostService -Confirm:$false}
}

#End SSHService Function

I have this in my profile, so its ready to be used in any PowerShell session that I have running.

-Stuart

2 thoughts on “PowerCLI to check for Python Exploit in VMware”

  1. Hey man, nice script! I found that if I had not previously logged into a host with PuTTy, and accepted the SSH keys, scripted plink sessions would fail. To resolve this potential security limitation I run this…

    foreach ($VMhost in $VMhosts){
    C:\temp\putty.exe $VMhost
    }

    This will open up a PuTTy session for each host, and all that’s needed is to push “accept” on any SSH key acceptance dialogs created. Then the PuTTy windows can be closed, as login is not required.

    1. Tim,
      Great catch with needing to save the SSH keys. I have the keys saved from when I do the host upgrades that I forgot about the acceptance needed to make it automated.

      -Stuart

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.