VirtualBox TFTP server vulnerabilities

In my previous blog post I wrote about VirtualBox DHCP bugs which can be triggered from an unprivileged guest user, in the default configuration and without Guest Additions installed. TFTP server for PXE boot is another attack surface which can be reached from the same configuration. VirtualBox in NAT mode (default configuration) runs a read only TFTP server in the IP address to support PXE boot.

CVE-2019-2553 - Directory traversal vulnerability

The source code of the TFTP server is at src/VBox/Devices/Network/slirp/tftp.c and it is based on the TFTP server used in QEMU. The below comment can be found in the source:
 * This code is based on:
* tftp.c - a simple, read-only tftp server for qemu
The guest provided file path is validated using the function tftpSecurityFilenameCheck() as below:
* This function evaluate file name.
* @param pu8Payload
* @param cbPayload
* @param cbFileName
* @return VINF_SUCCESS -
DECLINLINE(int) tftpSecurityFilenameCheck(PNATState pData, PCTFTPSESSION pcTftpSession)
size_t cbSessionFilename = 0;
int rc = VINF_SUCCESS;
AssertPtrReturn(pcTftpSession, VERR_INVALID_PARAMETER);
cbSessionFilename = RTStrNLen((const char *)pcTftpSession->pszFilename, TFTP_FILENAME_MAX);
if ( !RTStrNCmp((const char*)pcTftpSession->pszFilename, "../", 3)
|| (pcTftpSession->pszFilename[cbSessionFilename - 1] == '/')
|| RTStrStr((const char *)pcTftpSession->pszFilename, "/../"))

/* only allow exported prefixes */
if ( RT_SUCCESS(rc)
&& !tftp_prefix)
return rc;
This code again is based on the validation done in QEMU (slirp/tftp.c)
  /* do sanity checks on the filename */
if (!strncmp(req_fname, "../", 3) ||
req_fname[strlen(req_fname) - 1] == '/' ||
strstr(req_fname, "/../")) {
tftp_send_error(spt, 2, "Access violation", tp);
Interesting observation here is, above validation done in QEMU is specific to Linux hosts. However, VirtualBox relies on the same validation for Windows hosts too. Since backslash can be used as directory separator in Windows, validations done in tftpSecurityFilenameCheck() can be bypassed to read host files accessible under the privileges of the VirtualBox process. The default path to TFTP root folder is C:\Users\\.VirtualBox\TFTP. Payload to read other files from the host needs to be crafted accordingly. Below is the demo: