
ParaShells: Parallels Desktop Turns Appliance Install Into a Root Shell
JFrog researchers detail ParaShells, a local privilege escalation chain in Parallels Desktop 26.4.0 (build 57513) on Apple silicon that lets an unprivileged macOS user gain root. The chain combines a world-writable Unix socket for prl_disp_service, weak peer-credential-based authentication in PrlSrv_LoginLocal, and argument injection in the InstallAppliance extraction path where a crafted sVmParentPath breaks Qt's QProcess::splitCommand quoting to inject tar's --use-compress-program= flag, causing macOS tar to execute an attacker script as uid 0.
How it works
The attack chains three weaknesses that must all line up. The dispatcher's Unix socket /var/run/prl_disp_service.socket is mode 0777 (srwxrwxrwx), so any local process can connect. PrlSrv_LoginLocal then authenticates on kernel peer credentials (uid/gid, sometimes pid) with no Parallels Team ID check — an unsigned Python client logging in as a non-admin user succeeds when PrlUsrCfg_IsLocalAdministrator reports 0. The client then calls PrlSrv_InstallAppliance(hServer, hAppCfg, sVmParentPath, nFlags). The dispatcher builds its extract command as the single string tar -xf "%1" -C "%2", where %2 is the attacker-controlled sVmParentPath, then passes it through Qt's QProcess::splitCommand to build argv. A parent path containing an embedded quote closes the quoting early, so leftover text lands as a flag rather than a shell command — specifically --use-compress-program=/tmp/u505, which macOS tar honors and runs as root.
The lab payload parent path was:
/tmp/sprl_p_505" --use-compress-program=/tmp/u505 "The attacker must actually mkdir a directory with that exact name, because the dispatcher verifies sVmParentPath exists before extracting. PackageURL must parse as a URL (the download helper always passes -ui); file:///tmp/...tar works, a bare path does not.
Preconditions / Affected
- Parallels Desktop for Mac installed; lab-proven on 26.4.0 (build 57513), macOS arm64 (Apple silicon).
prl_disp_servicerunning with the socket present — the default on a stock install; a running VM is not required.- Any low-privileged local user (coworker account, CI agent, or already-resident malware). No admin group, no Parallels-signed binary needed.
JFrog did not regression-test older builds; treat any install exposing the same InstallAppliance template and world-writable socket as in scope. App Store Edition may start services differently but shares the same root-helper IPC risk class.
What to do
The post gives no patch — only detection. Confirm build and socket exposure:
# Product version (GUI About box, or):
defaults read "/Applications/Parallels Desktop.app/Contents/Info" CFBundleShortVersionString
defaults read "/Applications/Parallels Desktop.app/Contents/Info" CFBundleVersion
# Dispatcher socket world-writable?
ls -l /var/run/prl_disp_service.socket
# Expect something like: srwxrwxrwx ... prl_disp_service.socket
# Service state (if prlsrvctl is on PATH):
prlsrvctl info | headIf the socket mode is 0777 and Desktop is at or near 26.4.0 (57513), assume exposure until you confirm a patched build.
Caveats
This is argument injection, not shell injection: shell metacharacters (;, &&, backticks) do nothing here — the payload works only because macOS tar's --use-compress-program flag executes a program. The writeup does not claim a patched version exists or a CVE id, and older builds were not tested.
Organisations named here
- ParaShells
- prl_disp_service
- PrlSrv_InstallAppliance
- PrlSrv_LoginLocal
Technologies named here
- macOS
- defaults
- Parallels Desktop
- Parallels Desktop App Store Edition (may differ in how services start; same class of root helper IPC risk)
- Parallels Desktop for Mac 26.4.0 (build 57513), macOS arm64, lab-proven
- prl_disp_service, Parallels root helper daemon
- prlsrvctl
- Qt
- tar
Techniques named here
- Argument injection
Concepts named here
- Local privilege escalation
- Peer-credential authentication
- World-writable Unix socket
Threat actors named here
- ParaShells (JFrog's name for a local privilege escalation vulnerability in Parallels Desktop for Mac)
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
