ActiveBreach

CVE-2024-21111 – Local Privilege Escalation in Oracle VirtualBox

VirtualBox is a popular open source, cross-platform, virtualization software developed by Oracle Corporation. Earlier this year we identified an arbitrary file move vulnerability in the VirtualBox system service service that could facilitate privilege escalation; here we’ll outline the steps used to discover and exploit this issue.

This vulnerability was also discovered by Naor Hodorov who is also credited in the Oracle Patch Advisory.

Vulnerability Discovery

After installing VirtualBox for Windows, a single user-land service is installed (VirtualBox system service) which runs as SYSTEM and is configured to start on-demand:

PS C:\\tools> sc.exe qc VboxSDS
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: VboxSDS
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 3   DEMAND_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\\Program Files\\Oracle\\VirtualBox\\VBoxSDS.exe"
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : VirtualBox system service
        DEPENDENCIES       : RPCSS
        SERVICE_START_NAME : LocalSystem

This service will create the directory C:\\ProgramData\\VirtualBox\\ for logging purposes.

This directory is created without specifying explicit ACLs and as such inherits permissions from the parent directory (C:\\ProgramData) which allows users to create new files/folders:

PS C:\\tools> cacls.exe C:\\ProgramData\\VirtualBox
C:\\ProgramData\\VirtualBox NT AUTHORITY\\SYSTEM:(OI)(CI)(ID)F
                          BUILTIN\\Administrators:(OI)(CI)(ID)F
                          CREATOR OWNER:(OI)(CI)(IO)(ID)F
                          BUILTIN\\Users:(OI)(CI)(ID)R
                          BUILTIN\\Users:(CI)(ID)(special access:)
                                                FILE_WRITE_DATA
                                                FILE_APPEND_DATA
                                                FILE_WRITE_EA
                                                FILE_WRITE_ATTRIBUTES

PS C:\\tools>

When the service is started, this folder will be populated with log files, these log files will inherit the directory permissions which will prevent low privileged users from modifying/removing them and as a consequence limits abuse of directory junctions, a popular primitive used when exploiting logic access bugs:

PS C:\\tools> ls C:\\ProgramData\\VirtualBox\\

    Directory: C:\\ProgramData\\VirtualBox

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/22/2024   9:44 AM              0 VBoxSDS.log
-a----         4/22/2024   9:43 AM           1924 VBoxSDS.log.1
-a----         4/12/2024   1:49 AM           1924 VBoxSDS.log.10
-a----         4/19/2024   5:32 PM           1924 VBoxSDS.log.2
-a----         4/18/2024  10:41 AM           1281 VBoxSDS.log.3
-a----         4/17/2024  11:27 PM           1924 VBoxSDS.log.4
-a----         4/17/2024  10:20 PM            665 VBoxSDS.log.5
-a----         4/17/2024  10:20 PM           1431 VBoxSDS.log.6
-a----         4/15/2024  11:04 PM           1925 VBoxSDS.log.7
-a----         4/15/2024   1:30 PM            665 VBoxSDS.log.8
-a----         4/15/2024   1:30 PM           1431 VBoxSDS.log.9

PS C:\\tools> cacls.exe C:\\ProgramData\\VirtualBox\\VBoxSDS.log
C:\\ProgramData\\VirtualBox\\VBoxSDS.log NT AUTHORITY\\SYSTEM:(ID)F
                                      BUILTIN\\Administrators:(ID)F
                                      BUILTIN\\Users:(ID)R
PS C:\\tools>

Analysing the service during startup shows an interesting behaviour where by the VboxSDS service will perform file rename/move operation recursively inside the C:\\ProgramData\\VirtualBox directory.

VboxSDS.log will become VboxSDS.log.1

VboxSDS.log.1 will become VboxSDS.log.2

If the only file inside directory is VboxSDS.log.10, it will be deleted:

This can be abused to both delete files in the directory and perform an arbitrary file move.

In order to clear the directory, we need to be able to start the service as a low privileged user and also the ability to stop/crash the service, as in most cases the directory will contain multiple log files.

Starting the service as a low privileged user can be achieved through COM. The VboxSDS service registers a COM server and whenever this COM class is initiated the service is started:

PS C:\\tools> sc.exe queryex VboxSDS

SERVICE_NAME: VboxSDS
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :
PS C:\\tools> [Activator]::CreateInstance([type]::GetTypeFromCLSID("74AB5FFE-8726-4435-AA7E-876D705BCBA5"))
System.__ComObject
PS C:\\tools> sc.exe queryex VboxSDS

SERVICE_NAME: VboxSDS
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 11364
        FLAGS              :
PS C:\\tools>

The easiest way we discovered to crash the service was to prevent it from creating the VboxSDS.log file.

This can be done in few different ways, however we believe the easiest is to create a directory named VboxSDS.log, meaning the subsequent call to CreateFile API will fail as it expects a file:

In order to win the race between moving and creating the VboxSDS.log file, an opportunistic lock is created on VboxSDS.log.11. This file does not normally exist but the service will try to delete it just before creating the VboxSDS.log file:

Building an Exploit

With abilities to both clear the directory and start/crash the VBoxSDS service we can start building an exploit:

  • First we create the VboxSDS.log.11 file and set oplock on it,
  • We use the exposed COM server to start the service,
  • When oplock is triggered on the VboxSDS.log.11 file we create the VboxSDS.log directory which will cause the service to crash,
  • We keep starting the service until the directory is empty,
  • Once the directory is empty, a VboxSDS.log.9 file is created and an opportunistic lock is placed,
  • We start the service again and when oplock is triggered the VboxSDS.log.9 file is deleted and the directory is turned into a junction point to the NT Object Manager directory (\\RPC Control),
  • In the Object Manager directory two symbolic links are created:
    • VboxSDS.log.9 which points to our payload dll,
    • VboxSDS.log.10 which points to a non-existent dll in the system32 directory (in this case wow64log.dll),
  • Once wow64log.dll is created, the Microsoft Edge Update Service is started and our dll is loaded in to a SYSTEM process 🙂

This blog post was written by Filip Dragovic.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2024 MDSec