Synopsis
The Plex Media Server plugin framework contains a flaw that allows a remote attacker (authenticated with admin privileges) to execute arbitrary Python code within the context of the current OS user. Specifically, when a "Dict" file is loaded for a given plugin, the contents are unpickled without validation. The Dict file can be delivered remotely via the camera upload feature.
Let's first take a look at the unpickling piece.
This logic can be observed in C:\Program Files (x86)\Plex\Plex Media Server\Resources\Plug-ins-513b381af\Framework.bundle\Contents\Resources\Versions\1\Python\PMS\Dict.py:
def __load():
global __dict
path = "%s/Dict" % Data.__dataPath
if os.path.exists(path):
try:
__dict = Data.__unpickle(path)
PMS.Log("(Framework) Loaded the dictionary file")
except:
PMS.Log("(Framework) The dictionary file is corrupt & couldn't be loaded")
__loadDefaults()
else:
__loadDefaults()
And if we observe the definition of Data.__unpickle in C:\Program Files (x86)\Plex\Plex Media Server\Resources\Plug-ins-513b381af\Framework.bundle\Contents\Resources\Versions\1\Python\PMS\Data.py:
def __unpickle(path): f = open(path, "r") obj = pickle.load(f) f.close() return obj
It's clear that the pickle.loads() function is used to deserialize the contents of Dict. An attacker can craft a malicious Dict file such that when it is loaded, a payload of the attacker's choosing will be executed.
The delivery and trigger mechanisms require a few steps, but this can be automated. Here is the general flow:
Create a photo library at C:\Users\Public (can be different).
POST /library/sections?name=EvilLib&type=photo&agent=com.plexapp.agents.none&scanner=Plex%20Photo%20Scanner&language=en&importFromiTunes=&enableAutoPhotoTags=&location=C:\Users\Public
Using location ID from response, upload Dict file in this library. The directory structure will be created.
POST /library/metadata?createdAt=1171387901&filename=myfolder/Plex+Media+Server/Plug-in+Support/Data/com.plexapp.system/Dict&overwrite=true&locationID=8§ionID=3&type=13
Modify local app data path to point to this location
PUT /:/prefs?LocalAppDataPath=C:\Users\Public\myfolder
Restart com.plexapp.system
GET /:/plugins/com.plexapp.system/restart
Proof of Concept
auth_dict_unpickle_rce_exploit_tra_2020_32.pySolution
Upgrade to Plex Media Server 1.19.3.Disclosure Timeline
All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.
Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.
For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.
If you have questions or corrections about this advisory, please email [email protected]