Local Privilege PlEXcalasion - CVE-2021-42835
Plex Media Server for Windows prior to version 18.104.22.16882, vulnerable to Time Of Check Time Of Use (TOCTOU) that allows low privilege users to gain SYSTEM privileges.
Tomer Peled, Netanel Cohen, and Amir Shen a Security Researchers from BugSec.
Plex for windows uses PlexUpdateService.exe to install new updates. The service is running in the SYSTEM context. When installing an update, the service first verifies file integrity and digital signature, only if the checks were successful the update will be installed.
At this process, After integrity and signature check, There was a design flow that handled the update file improperly. The file was closed and reopened later for installation.
This flaw allows an attacker to swap the update file with a malicious one as soon as the service is finished to verify the integrity and signature, resulting in code execution in the SYSTEM context.
This POC use tools developed by James Forshaw with slight modifications. The original can be found here - https://github.com/googleprojectzero/symboliclink-testing-tools
To achieve the above we used a Junction folder that will first point to a folder containing a valid update file and then will swap to a folder containing the malicious file.
We found that the file access order was as follow:
- Read the update file to check its digital signature
- Close the update file.
- Read CACERT.pem
- verify the signature.
- Read the update file again
- Execute the installation
We created a mount point on the junction folder to point to a folder that contains the valid update file. Set opLock on cacert.pem with a callback function, As soon as it acess we change the mount point to the malicious folder.
In addition, we have created an RPC client that will trigger the update.
- Clone the repository and open PlEXcalasion.sln in Visual Studio.
- Modify Paths:
PlexClient/PlexClient.cpp replace ROOTDIR with your path.
const wchar_t* pszString = L"<ROOTDIR>\\PlEXcalaison\\TOCTOU\\junction\\plex.exe"; // Path to the update file.
PlEXcalaison/BaitAndSwitch/BaitAndSwitch.cpp replace ROOTDIR with your path.
static LPCWSTR junction = L"<ROOTDIR>\\PlEXcalaison\\TOCTOU\\junction"; // Path to junction folder , MAKE SURE IT IS EMPTY ! static LPCWSTR target1 = L"<ROOTDIR>\\PlEXcalaison\\TOCTOU\\valid"; // Path to folder contains the valid update file. static LPCWSTR target2 = L"<ROOTDIR>\\PlEXcalaison\\TOCTOU\\malicious"; // Path to folder contains the malicious file - MUST BE THE SAME NAME AS THE UPDATE FILE. static LPCWSTR cacert = L"C:\\Program Files (x86)\\Plex\\Plex Media Server\\Resources\\cacert.pem"; // Path to cacert.pem - can be found in plex directory.
- Build the solution.
- Make sure a PlexClient.exe was created and can be found on Rleases dir.
- Put the desired executeable file you want to execute as system in the malicious folder and rename it to plex.exe (for the poc i used cmd.exe)
- Execute BiteAndSwitch.exe