Skip to content

Back to the catalog

ParaShells: Parallels Desktop Turns Appliance Install Into a Root Shell
jfrog.comwriteup

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.

TL;DR A world-writable Unix socket and weak local auth in Parallels Desktop's root daemon let a low-privilege macOS user inject tar arguments during appliance install to get a root shell.
Document

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_service running 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 | head

If 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)