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