From 59bc1a34d5de3a318ee29b415d3e647964a0a798 Mon Sep 17 00:00:00 2001 From: christopher lee Date: Thu, 1 Feb 2018 13:38:20 -0600 Subject: [PATCH 1/6] Remove 'puts' logging and cleanup AWS poc --- lib/metasploit/framework/data_service.rb | 22 +++- .../framework/data_service/proxy/core.rb | 62 +++++---- .../proxy/credential_data_proxy.rb | 5 +- .../data_service/proxy/event_data_proxy.rb | 2 +- .../data_service/proxy/exploit_data_proxy.rb | 6 +- .../data_service/proxy/host_data_proxy.rb | 14 +- .../data_service/proxy/loot_data_proxy.rb | 6 +- .../data_service/proxy/nmap_data_proxy.rb | 3 +- .../data_service/proxy/note_data_proxy.rb | 2 +- .../data_service/proxy/service_data_proxy.rb | 2 +- .../data_service/proxy/session_data_proxy.rb | 3 +- .../proxy/session_event_data_proxy.rb | 5 +- .../data_service/proxy/vuln_data_proxy.rb | 2 +- .../data_service/proxy/web_data_proxy.rb | 2 +- .../proxy/workspace_data_proxy.rb | 14 +- .../data_service/remote/http/core.rb | 54 ++------ .../remote/http/response_data_helper.rb | 8 +- .../remote/msf_red/job_handler.rb | 9 -- .../job_handlers/message_job_handler.rb | 23 ---- .../remote/msf_red/msf_red_service.rb | 122 ------------------ .../core/db_manager/http/aws/sns_handler.rb | 48 ------- .../core/db_manager/http/aws/sns_message.rb | 2 - .../http/http_db_manager_service.rb | 40 +++++- lib/msf/core/db_manager/http/job_processor.rb | 3 +- .../core/db_manager/http/servlet_helper.rb | 3 +- lib/msf/core/db_manager/http/sinatra_app.rb | 3 - lib/msf/ui/console/command_dispatcher/db.rb | 115 +++-------------- 27 files changed, 147 insertions(+), 433 deletions(-) delete mode 100644 lib/metasploit/framework/data_service/remote/msf_red/job_handler.rb delete mode 100644 lib/metasploit/framework/data_service/remote/msf_red/job_handlers/message_job_handler.rb delete mode 100644 lib/metasploit/framework/data_service/remote/msf_red/msf_red_service.rb delete mode 100644 lib/msf/core/db_manager/http/aws/sns_handler.rb delete mode 100644 lib/msf/core/db_manager/http/aws/sns_message.rb diff --git a/lib/metasploit/framework/data_service.rb b/lib/metasploit/framework/data_service.rb index 71307d875d..57717af775 100644 --- a/lib/metasploit/framework/data_service.rb +++ b/lib/metasploit/framework/data_service.rb @@ -33,6 +33,26 @@ module DataService def active raise 'DataLService#active is not implemented'; end -end + + class Metadata + attr_reader :id + attr_reader :name + attr_reader :active + + def initialize (id, name, active) + self.id = id + self.name = name + self.active = active + end + + private + attr_writer :id + attr_writer :name + attr_writer :active + + end + +end + end end diff --git a/lib/metasploit/framework/data_service/proxy/core.rb b/lib/metasploit/framework/data_service/proxy/core.rb index 44f69d6324..4e292faf7c 100644 --- a/lib/metasploit/framework/data_service/proxy/core.rb +++ b/lib/metasploit/framework/data_service/proxy/core.rb @@ -28,13 +28,13 @@ class DataProxy # def error return @error if (@error) - return @data_service.error if @data_service - return "none" + return @current_data_service.error if @current_data_service + return 'none' end def is_local? - if (@data_service) - return (@data_service.name == 'local_db_service') + if (@current_data_service) + return (@current_data_service.name == 'local_db_service') end return false @@ -44,8 +44,8 @@ class DataProxy # Determines if the data service is active # def active - if (@data_service) - return @data_service.active + if (@current_data_service) + return @current_data_service.active end return false @@ -57,8 +57,6 @@ class DataProxy # def register_data_service(data_service, online=false) validate(data_service) - - puts "Registering data service: #{data_service.name}" data_service_id = @data_service_id += 1 @data_services[data_service_id] = data_service set_data_service(data_service_id, online) @@ -70,45 +68,43 @@ class DataProxy def set_data_service(data_service_id, online=false) data_service = @data_services[data_service_id.to_i] if (data_service.nil?) - puts "Data service with id: #{data_service_id} does not exist" - return nil + raise "Data service with id: #{data_service_id} does not exist" end if (!online && !data_service.active) - puts "Data service not online: #{data_service.name}, not setting as active" - return nil + raise "Data service not online: #{data_service.name}, not setting as active" end - puts "Setting active data service: #{data_service.name}" - @data_service = data_service + @current_data_service = data_service end # - # Prints out a list of the current data services + # Retrieves metadata about the data services # - def print_data_services() + def get_services_metadata() + services_metadata = [] @data_services.each_key {|key| - out = "id: #{key}, description: #{@data_services[key].name}" - if (!@data_service.nil? && @data_services[key].name == @data_service.name) - out += " [active]" - end - puts out #hahaha + name = @data_services[key].name + active = !@current_data_service.nil? && name == @current_data_service.name + services_metadata << Metasploit::Framework::DataService::Metadata.new(key, name, active) } + + services_metadata end # # Used to bridge the local db # def method_missing(method, *args, &block) - #puts "Attempting to delegate method: #{method}" - unless @data_service.nil? - @data_service.send(method, *args, &block) + dlog ("Attempting to delegate method: #{method}") + unless @current_data_service.nil? + @current_data_service.send(method, *args, &block) end end def respond_to?(method_name, include_private=false) - unless @data_service.nil? - return @data_service.respond_to?(method_name, include_private) + unless @current_data_service.nil? + return @current_data_service.respond_to?(method_name, include_private) end false @@ -119,18 +115,18 @@ class DataProxy # def exit_called if @pid - puts 'Killing db process' + ilog 'Shutdown called, attempting to kill db process' begin - Process.kill("TERM", @pid) + Process.kill('TERM', @pid) rescue Exception => e - puts "Unable to kill db process: #{e.message}" + elog "Unable to kill db process: #{e.message}" end end end def get_data_service - raise 'No registered data_service' unless @data_service - return @data_service + raise 'No registered data_service' unless @current_data_service + return @current_data_service end ####### @@ -150,7 +146,7 @@ class DataProxy @error = 'disabled' end rescue Exception => e - puts "Unable to initialize a dataservice #{e.message}" + raise "Unable to initialize a dataservice #{e.message}" end end @@ -176,7 +172,7 @@ class DataProxy db_script = File.join( Msf::Config.install_root, "msfdb -ns") wait_t = Open3.pipeline_start(db_script) @pid = wait_t[0].pid - puts "Started process with pid #{@pid}" + dlog("Started data service process with pid #{@pid}") endpoint = URI.parse('http://localhost:8080') remote_host_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint) diff --git a/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb index 6e60ec0584..0c1171f132 100644 --- a/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb @@ -5,7 +5,7 @@ module CredentialDataProxy data_service = self.get_data_service() data_service.create_credential(opts) rescue Exception => e - puts "Call to #{data_service.class}#create_credential threw exception: #{e.message}" + elog "Call to #{data_service.class}#create_credential threw exception: #{e.message}" end end @@ -14,8 +14,7 @@ module CredentialDataProxy data_service = self.get_data_service data_service.creds(opts) rescue Exception => e - puts "Call to #{data_service.class}#credentials threw exception: #{e.message}" - e.backtrace.each { |line| puts "#{line}\n" } + elog "Call to #{data_service.class}#credentials threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb index 315e10f2c4..a8124e8b18 100644 --- a/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb @@ -5,7 +5,7 @@ module EventDataProxy data_service = self.get_data_service() data_service.report_event(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_event threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_event threw exception: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb index 3779790997..d704228710 100644 --- a/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb @@ -5,7 +5,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_attempt(host, opts) rescue Exception => e - puts"Call to #{data_service.class}#report_exploit_attempt threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_exploit_attempt threw exception: #{e.message}" end end @@ -14,7 +14,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_failure(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_exploit_failure threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_exploit_failure threw exception: #{e.message}" end end @@ -23,7 +23,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_success(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_exploit_success threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_exploit_success threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb index 247cf17940..d79617dc80 100644 --- a/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb @@ -9,14 +9,13 @@ module HostDataProxy opts[:addresses] = addresses data_service.hosts(opts) rescue Exception => e - puts "Call to #{data_service.class}#hosts threw exception: #{e.message}" + elog "Call to #{data_service.class}#hosts threw exception: #{e.message}" end end # TODO: Shouldn't this proxy to RemoteHostDataService#find_or_create_host ? # It's currently skipping the "find" part def find_or_create_host(opts) - puts 'Calling find host' report_host(opts) end @@ -27,8 +26,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.report_host(opts) rescue Exception => e - puts "Call to #{data_service.class}#report_host threw exception: #{e.message}" - opts.each { |k, v| puts "#{k} : #{v}" } + elog "Call to #{data_service.class}#report_host threw exception: #{e.message}" end end @@ -37,7 +35,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.report_hosts(hosts) rescue Exception => e - puts "Call to #{data_service.class}#report_hosts threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_hosts threw exception: #{e.message}" end end @@ -46,7 +44,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.delete_host(opts) rescue Exception => e - puts "Call to #{data_service.class}#delete_host threw exception: #{e.message}" + elog "Call to #{data_service.class}#delete_host threw exception: #{e.message}" end end @@ -54,13 +52,13 @@ module HostDataProxy def valid(opts) unless opts[:host] - puts 'Invalid host hash passed, :host is missing' + ilog 'Invalid host hash passed, :host is missing' return false end # Sometimes a host setup through a pivot will see the address as "Remote Pipe" if opts[:host].eql? "Remote Pipe" - puts "Invalid host hash passed, address was of type 'Remote Pipe'" + ilog "Invalid host hash passed, address was of type 'Remote Pipe'" return false end diff --git a/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb index e63c8b62f9..8a4bad5b6c 100644 --- a/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb @@ -8,7 +8,7 @@ module LootDataProxy end data_service.report_loot(opts) rescue Exception => e - puts "Call to #{data_service.class}#report_loot threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_loot threw exception: #{e.message}" end end @@ -18,9 +18,9 @@ module LootDataProxy opts[:wspace] = wspace data_service.loot(opts) rescue Exception => e - puts "Call to #{data_service.class}#loots threw exception: #{e.message}" - e.backtrace.each { |line| puts "#{line}\n" } + elog "Call to #{data_service.class}#loots threw exception: #{e.message}" end end + alias_method :loot, :loots end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb index 04b083122d..2182bdc822 100644 --- a/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb @@ -5,8 +5,7 @@ module NmapDataProxy data_service = self.get_data_service() data_service.import_nmap_xml_file(args) rescue Exception => e - puts "Call to #{data_service.class}#import_nmap_xml_file threw exception: #{e.message}" - e.backtrace { |line| puts "#{line}\n"} + elog "Call to #{data_service.class}#import_nmap_xml_file threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb index 591c26bd77..39d2f1c3e7 100644 --- a/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb @@ -4,7 +4,7 @@ module NoteDataProxy data_service = self.get_data_service() data_service.report_note(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_note threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_note threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb index 3f8564eb23..6bb0b8ab23 100644 --- a/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb @@ -5,7 +5,7 @@ module ServiceDataProxy data_service = self.get_data_service() data_service.report_service(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_service threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_service threw exception: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb index 4a7e33c131..1514b1199f 100644 --- a/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb @@ -4,8 +4,7 @@ module SessionDataProxy data_service = self.get_data_service() data_service.report_session(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_session threw exception: #{e.message}" - puts e.backtrace.each { |line| puts "#{line}\n" } + elog "Call to #{data_service.class}#report_session threw exception: #{e.message}" end end end diff --git a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb index 264cde47bf..ca4f9e4851 100644 --- a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb @@ -3,9 +3,8 @@ module SessionEventDataProxy def session_events begin data_service = self.get_data_service() - puts "In SessionEventDataProxy.session_events" rescue Exception => e - puts"Call to #{data_service.class}#session_events threw exception: #{e.message}" + elog "Call to #{data_service.class}#session_events threw exception: #{e.message}" end end @@ -14,7 +13,7 @@ module SessionEventDataProxy data_service = self.get_data_service() data_service.report_session_event(opts) rescue Exception => e - puts "Call to #{data_service.class}#report_session_event threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_session_event threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb index ea394ea087..18a4498b4b 100644 --- a/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb @@ -5,7 +5,7 @@ module VulnDataProxy data_service = self.get_data_service() data_service.report_vuln(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_vuln threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_vuln threw exception: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb index bea9e31265..dfa652de25 100644 --- a/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb @@ -4,7 +4,7 @@ module WebDataProxy data_service = self.get_data_service() data_service.report_web_site(opts) rescue Exception => e - puts"Call to #{data_service.class}#report_web_site threw exception: #{e.message}" + elog "Call to #{data_service.class}#report_web_site threw exception: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb index 2eb20a5ba3..141c24d3f0 100644 --- a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb @@ -5,7 +5,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.find_workspace(workspace_name) rescue Exception => e - puts"Call to #{data_service.class}#find_workspace threw exception: #{e.message}" + elog "Call to #{data_service.class}#find_workspace threw exception: #{e.message}" end end @@ -14,7 +14,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.add_workspace(workspace_name) rescue Exception => e - puts"Call to #{data_service.class}#add_workspace threw exception: #{e.message}" + elog "Call to #{data_service.class}#add_workspace threw exception: #{e.message}" end end @@ -23,7 +23,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.default_workspace rescue Exception => e - puts"Call to #{data_service.class}#default_workspace threw exception: #{e.message}" + elog "Call to #{data_service.class}#default_workspace threw exception: #{e.message}" end end @@ -32,7 +32,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace rescue Exception => e - puts"Call to #{data_service.class}#workspace threw exception: #{e.message}" + elog "Call to #{data_service.class}#workspace threw exception: #{e.message}" end end @@ -41,7 +41,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace = workspace rescue Exception => e - puts"Call to #{data_service.class}#find_workspace threw exception: #{e.message}" + elog "Call to #{data_service.class}#find_workspace threw exception: #{e.message}" end end @@ -50,7 +50,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspaces rescue Exception => e - puts"Call to #{data_service.class}#workspaces threw exception: #{e.message}" + elog "Call to #{data_service.class}#workspaces threw exception: #{e.message}" end end @@ -59,7 +59,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace_associations_counts() rescue Exception => e - puts"Call to #{data_service.class}#workspace_associations_counts threw exception: #{e.message}" + elog "Call to #{data_service.class}#workspace_associations_counts threw exception: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/remote/http/core.rb b/lib/metasploit/framework/data_service/remote/http/core.rb index 3e21256999..bd0ebd689c 100644 --- a/lib/metasploit/framework/data_service/remote/http/core.rb +++ b/lib/metasploit/framework/data_service/remote/http/core.rb @@ -110,7 +110,7 @@ class RemoteHTTPDataService begin query_str = (!query.nil? && !query.empty?) ? URI.encode_www_form(append_workspace(query)) : nil uri = URI::HTTP::build({path: path, query: query_str}) - puts "#{Time.now} - HTTP #{request_type} request to #{uri.request_uri} with #{data_hash ? data_hash : "nil"}" + dlog("HTTP #{request_type} request to #{uri.request_uri} with #{data_hash ? data_hash : "nil"}") client = @client_pool.pop() case request_type @@ -130,20 +130,17 @@ class RemoteHTTPDataService case response when Net::HTTPOK - # puts 'request sent successfully' return SuccessResponse.new(response) else - puts "HTTP #{request_type} request: #{uri.request_uri} failed with code: #{response.code} message: #{response.body}" + ilog "HTTP #{request_type} request: #{uri.request_uri} failed with code: #{response.code} message: #{response.body}" return FailedResponse.new(response) end rescue EOFError => e - puts "ERROR: No data was returned from the server." - puts "Backtrace: #{e.message}" - e.backtrace.each { |line| puts "#{line}\n"} - return FailedResponse.new("") + elog "No data was returned from the data service for request path : #{path}, message: #{e.message}" + return FailedResponse.new('') rescue Exception => e - puts "Problem with HTTP #{request_type} request: #{e.message}" - e.backtrace.each { |line| puts "#{line}\n" } + elog "Problem with HTTP request for path: #{path} message: #{e.message}" + return FailedResponse.new('') ensure @client_pool << client end @@ -156,32 +153,6 @@ class RemoteHTTPDataService return true end - # def do_nl_search(search) - # search_item = search.query.split(".")[0] - # case search_item - # when "host" - # do_host_search(search) - # end - # end - - # def active - # begin - # request_opts = {'method' => 'GET', 'uri' => ONLINE_TEST_URL} - # request = @client.request_raw(request_opts) - # response = @client._send_recv(request) - # if response.code == 200 - # try_sound_effect() - # return true - # else - # puts "request failed with code: #{response.code} message: #{response.message}" - # return false - # end - # rescue Exception => e - # puts "Unable to contact goliath service: #{e.message}" - # return false - # end - # end - def name "remote_data_service: (#{@endpoint})" end @@ -253,10 +224,10 @@ class RemoteHTTPDataService if !data_hash.nil? && !data_hash.empty? data_hash.each do |k,v| if v.is_a?(Msf::Session) - puts "#{Time.now} - DEBUG: Dropping Msf::Session object before converting to JSON." - puts "data_hash is #{data_hash}" - puts "Callstack:" - caller.each { |line| puts "#{line}\n"} + dlog('Dropping Msf::Session object before converting to JSON.') + dlog("data_hash is #{data_hash}") + dlog('Callstack:') + caller.each { |line| dlog("#{line}\n")} data_hash.delete(k) end end @@ -312,11 +283,6 @@ class RemoteHTTPDataService true end - def try_sound_effect() - sound_file = ::File.join(Msf::Config.data_directory, "sounds", "Goliath_Online_Sound_Effect.wav") - Rex::Compat.play_sound(sound_file) - end - end end end diff --git a/lib/metasploit/framework/data_service/remote/http/response_data_helper.rb b/lib/metasploit/framework/data_service/remote/http/response_data_helper.rb index cebb5ffd36..a299941497 100644 --- a/lib/metasploit/framework/data_service/remote/http/response_data_helper.rb +++ b/lib/metasploit/framework/data_service/remote/http/response_data_helper.rb @@ -17,7 +17,7 @@ module ResponseDataHelper return JSON.parse(body, object_class: OpenStruct) end rescue Exception => e - puts "open struct conversion failed #{e.message}" + elog "open struct conversion failed #{e.message}" end end @@ -44,8 +44,7 @@ module ResponseDataHelper return rv end rescue Exception => e - puts "Mdm Object conversion failed #{e.message}" - e.backtrace.each { |line| puts "#{line}\n" } + elog "Mdm Object conversion failed #{e.message}" end end @@ -67,8 +66,7 @@ module ResponseDataHelper File.open(save_path, 'w+') { |file| file.write(decoded_file) } end rescue Exception => e - puts "There was an error writing the file: #{e}" - e.backtrace.each { |line| puts "#{line}\n"} + elog "There was an error writing the file: #{e.message}" end save_path end diff --git a/lib/metasploit/framework/data_service/remote/msf_red/job_handler.rb b/lib/metasploit/framework/data_service/remote/msf_red/job_handler.rb deleted file mode 100644 index 00806c00e4..0000000000 --- a/lib/metasploit/framework/data_service/remote/msf_red/job_handler.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JobHandler - def handle(job_details) - raise 'JobHandler#handle is not implemented'; - end - - def job_type_handled - raise 'JobHandler#job_type_handled is not implemented'; - end -end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/remote/msf_red/job_handlers/message_job_handler.rb b/lib/metasploit/framework/data_service/remote/msf_red/job_handlers/message_job_handler.rb deleted file mode 100644 index 51d06ebccf..0000000000 --- a/lib/metasploit/framework/data_service/remote/msf_red/job_handlers/message_job_handler.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'metasploit/framework/data_service/remote/msf_red/job_handler' - -class MessageJobHandler - include JobHandler - - JOB_HANDLED = 'message' - - def handle(message_hash) - message = "User: #{message_hash['user_id']}, #{message_hash['message']}" - banner = "*" * message.size - puts "\n" - puts "\n" - puts banner - puts message - puts banner - puts "\n" - end - - def job_type_handled - JOB_HANDLED - end - -end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/remote/msf_red/msf_red_service.rb b/lib/metasploit/framework/data_service/remote/msf_red/msf_red_service.rb deleted file mode 100644 index fb912b94b8..0000000000 --- a/lib/metasploit/framework/data_service/remote/msf_red/msf_red_service.rb +++ /dev/null @@ -1,122 +0,0 @@ -require 'metasploit/framework/data_service' -require 'metasploit/framework/data_service/remote/http/core' - -class MSFRedService - JOB_CHECK_INTERVAL_SEC = 5 - LOGIN_TIMEOUT_SEC = 10 - SESSION_KEY_VALUE = 'msf-session-key' - LOGIN_ENDPOINT = '/login' - JOBS_ENDPOINT = '/jobs' - CONSOLE_SERVICE_HOST_NAME = 'console-service.metasploit.r7ops.com' - CONSOLE_SERVICE_PORT = 8080 - - def initialize - @client = Rex::Proto::Http::Client.new(CONSOLE_SERVICE_HOST_NAME, CONSOLE_SERVICE_PORT) - @job_handlers = Hash.new() - load_job_handlers - end - - # TODO: Obviously this is not secure - def launch(username, password) - if (do_login(username, password)) - inject_data_service - start_job_thread - end - - end - - ####### - private - ####### - - def load_job_handlers - job_handler_path = File.dirname(__FILE__) + '/job_handlers/*' - Dir.glob(job_handler_path).collect{|file_path| - job_handler_class = File.basename(file_path, '.rb').classify - require file_path - job_handler_class_constant = job_handler_class.constantize - job_handler = job_handler_class_constant.new - @job_handlers[job_handler.job_type_handled] = job_handler - } - end - - def inject_data_service - endpoint = URI.parse("http://#{CONSOLE_SERVICE_HOST_NAME}:#{CONSOLE_SERVICE_PORT}") - remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint) - remote_data_service.set_header(SESSION_KEY_VALUE, @session_key) - data_service_manager = Metasploit::Framework::DataService::DataProxy.instance - data_service_manager.register_data_service(remote_data_service) - end - - def do_login(username, password) - login_hash = {:username => username, :password => password} - begin - - request_opts = { 'method' => 'POST', 'ctype' => 'application/json', 'uri' => LOGIN_ENDPOINT, 'data' => login_hash.to_json } - request = @client.request_raw(request_opts) - response = @client._send_recv(request, LOGIN_TIMEOUT_SEC) - - if response.code == 200 - data = JSON.parse(response.body) - @session_key = data['session_key'] - puts "MSF Red console login successfull, session: #{@session_key}" - return true - else - puts "Login failed: failed with code: #{response.code} message: #{response.body}" - return false - end - rescue Exception => e - puts "Problem with POST request: #{e.message}" - return false - end - end - - - def start_job_thread - Thread.start { - loop { - sleep 5 - begin - job_hash = get_next_job - if (job_hash.nil? or job_hash.empty?) - next - end - - type = job_hash['job_type'] - job_handler = @job_handlers[type] - if (job_handler.nil?) - puts "No registered job handler for type: #{type}" - else - job_handler.handle(job_hash['job_details']) - end - rescue Exception => e - puts "Problem executing job: #{e.message}" - end - } - } - end - - def get_next_job - request_opts = { 'method' => 'GET', 'ctype' => 'application/json', 'uri' => JOBS_ENDPOINT, 'headers' => {SESSION_KEY_VALUE => @session_key} } - request = @client.request_raw(request_opts) - response = @client._send_recv(request) - - if response.code == 200 - if (response.body.nil? or response.body.empty?) - return nil - end - - begin - return JSON.parse(response.body) - rescue Exception => e - puts "Unable to parse: #{response.body}, reason: #{e.message}" - return nil - end - - else - puts "GET request: #{path} with body: #{json_body} failed with code: #{response.code} message: #{response.body}" - return nil - end - end - -end \ No newline at end of file diff --git a/lib/msf/core/db_manager/http/aws/sns_handler.rb b/lib/msf/core/db_manager/http/aws/sns_handler.rb deleted file mode 100644 index c1d53f0130..0000000000 --- a/lib/msf/core/db_manager/http/aws/sns_handler.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'net/http' -require 'msf/core/db_manager/http/servlet_helper' - -class SNSHandler - include ServletHelper - - def initialize(app) - @app = app - end - - def call(env) - request = Rack::Request.new(env) - # puts "Received #{env['REQUEST_METHOD']} for path #{env['REQUEST_PATH']}" - sns_message_type = env['HTTP_X_AMZ_SNS_MESSAGE_TYPE'] - if (request.post? and not sns_message_type.nil?) - case sns_message_type - when "Notification" - env['rack.input'] = get_message_io(request) - when "SubscriptionConfirmation" - do_confirm(request) - return [200, {}, ['']] - end - end - - @app.call(env) - end - - ####### - private - ####### - - # Confirms SNS subscription - def do_confirm(request) - opts = parse_json_request(request, true) - subscription_url = opts[:SubscribeURL] - begin - Net::HTTP.get(URI(subscription_url)) - rescue Exception => e - puts "Error on subscription: #{e.message}" - end - end - - def get_message_io(request) - opts = parse_json_request(request, true) - message = opts[:Message] - return StringIO.new(message) - end -end \ No newline at end of file diff --git a/lib/msf/core/db_manager/http/aws/sns_message.rb b/lib/msf/core/db_manager/http/aws/sns_message.rb deleted file mode 100644 index f415167ccc..0000000000 --- a/lib/msf/core/db_manager/http/aws/sns_message.rb +++ /dev/null @@ -1,2 +0,0 @@ -class SNSMessage -end \ No newline at end of file diff --git a/lib/msf/core/db_manager/http/http_db_manager_service.rb b/lib/msf/core/db_manager/http/http_db_manager_service.rb index 74a98066ab..93b0b45eca 100644 --- a/lib/msf/core/db_manager/http/http_db_manager_service.rb +++ b/lib/msf/core/db_manager/http/http_db_manager_service.rb @@ -1,13 +1,14 @@ require 'rack' require 'msf/core/db_manager/http/sinatra_app' require 'metasploit/framework/parsed_options/remote_db' +require 'rex/ui/text/output/stdio' class HttpDBManagerService def start(opts) parsed_options = Metasploit::Framework::ParsedOptions::RemoteDB.new if (parsed_options.options.database.no_signal) - puts 'removing trap' + print_warning 'Trap handling removed' opts[:signals] = false @shutdown_on_interupt = false else @@ -35,7 +36,7 @@ class HttpDBManagerService Rack::Handler::Thin.run(SinatraApp, opts) do |server| - # TODO: prevent accidental shutdown from msfconle eg: ctrl-c + # TODO: prevent accidental shutdown from msfconsole eg: ctrl-c [:INT, :TERM].each { |sig| trap(sig) { server.stop if (@shutdown_on_interupt || sig == :TERM) @@ -43,9 +44,11 @@ class HttpDBManagerService } if opts[:ssl] && opts[:ssl] = true - puts "Starting in HTTPS mode" + print_good "SSL Enabled" server.ssl = true server.ssl_options = opts[:ssl_opts] + else + print_warning 'SSL Disabled' end server.threaded = true end @@ -84,4 +87,33 @@ class HttpDBManagerService # } # end -end \ No newline at end of file + + +end + + +def print_line(msg) + $console_printer.print_line(msg) +end + +def print_warning(msg) + $console_printer.print_warning(msg) +end + +def print_good(msg) + $console_printer.print_good(msg) +end + +def print_error(msg, exception = nil) + unless exception.nil? + msg += "\n Call Stack:" + exception.backtrace.each {|line| + msg += "\n" + msg += "\t #{line}" + } + end + + $console_printer.print_error(msg) +end + +$console_printer = Rex::Ui::Text::Output::Stdio.new diff --git a/lib/msf/core/db_manager/http/job_processor.rb b/lib/msf/core/db_manager/http/job_processor.rb index 9341716d99..cf689145cd 100644 --- a/lib/msf/core/db_manager/http/job_processor.rb +++ b/lib/msf/core/db_manager/http/job_processor.rb @@ -21,8 +21,7 @@ class JobProcessor begin wrapper.job.call(wrapper.job_args) rescue Exception => e - puts "Error executing job #{e.message}" - e.backtrace.each { |line| puts "#{line}\n"} + print_error "Error executing job #{e.message}", e end end } diff --git a/lib/msf/core/db_manager/http/servlet_helper.rb b/lib/msf/core/db_manager/http/servlet_helper.rb index d3f6a605d6..22e8d97411 100644 --- a/lib/msf/core/db_manager/http/servlet_helper.rb +++ b/lib/msf/core/db_manager/http/servlet_helper.rb @@ -7,8 +7,7 @@ module ServletHelper include ResponseDataHelper def set_error_on_response(error) - puts "Error handling request: #{error.message}" - error.backtrace.each { |line| puts "#{line}\n" } + print_error "Error handling request: #{error.message}", error headers = {'Content-Type' => 'text/plain'} [500, headers, error.message] end diff --git a/lib/msf/core/db_manager/http/sinatra_app.rb b/lib/msf/core/db_manager/http/sinatra_app.rb index d17d7e9e16..1d706eeb21 100644 --- a/lib/msf/core/db_manager/http/sinatra_app.rb +++ b/lib/msf/core/db_manager/http/sinatra_app.rb @@ -1,6 +1,5 @@ require 'sinatra/base' require 'msf/core/db_manager/http/servlet_helper' -require 'msf/core/db_manager/http/aws/sns_handler' require 'msf/core/db_manager/http/servlet/host_servlet' require 'msf/core/db_manager/http/servlet/note_servlet' require 'msf/core/db_manager/http/servlet/vuln_servlet' @@ -18,8 +17,6 @@ require 'msf/core/db_manager/http/servlet/nmap_servlet' class SinatraApp < Sinatra::Base - use SNSHandler - helpers ServletHelper # Servlet registration diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 5b56d5b7c3..99d560ff47 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -47,13 +47,9 @@ module Msf "db_export" => "Export a file containing the contents of the database", "db_nmap" => "Executes nmap and records the output automatically", "db_rebuild_cache" => "Rebuilds the database-stored module cache", - "test_data_service_host" => "Blah", - "test_data_service_loot" => "Blah", - "perf_test_data_service_loot" => "REMOVEME - Run a performance test against the loot data service", - "add_data_service" => "Blah", - "list_data_services" => "Blah", - "set_data_service" => "Blah", - "nl_search" => "Blah" + "add_data_service" => "Adds a data service to metasploit", + "list_data_services" => "List data services added to metasploit", + "set_data_service" => "Sets the data service to use", } # Always include commands that only make sense when connected. @@ -93,7 +89,13 @@ module Msf end def cmd_list_data_services() - framework.db.print_data_services + framework.db.get_services_metadata.each {|metadata| + out = "id: #{metadata.id}, name: #{metadata.name}" + if metadata.active + out += " [active]" + end + print_line out + } end def cmd_add_data_service(*args) @@ -125,7 +127,12 @@ module Msf endpoint = "#{protocol}://#{host}:#{port}" remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint, https_opts) - framework.db.register_data_service(remote_data_service) + begin + framework.db.register_data_service(remote_data_service) + print_line "Registered data service: #{remote_data_service.name}" + rescue Exception => e + print_error "There was a problem registering the remote data service: #{e.message}" + end end def cmd_add_data_service_help @@ -140,96 +147,6 @@ module Msf print_line end - def cmd_test_data_service_host(*args) - host = {} - while (arg = args.shift) - case arg - when '-h' - host[:host] = args.shift - when '-n' - host[:name] = args.shift - when '-o' - host[:os_name] = args.shift - end - end - - puts 'Reporting test host to data service' - framework.db.report_host host - end - - def cmd_test_data_service_loot(*args) - loot = {} - while (arg = args.shift) - case arg - when '-h' - loot[:host] = args.shift - when '-n' - loot[:name] = args.shift - when '-s' - loot[:service] = args.shift - when '-t' - loot[:type] = args.shift - when '-i' - loot[:info] = args.shift - when '-p' - loot[:path] = args.shift - end - end - - puts 'Reporting test loot to data service' - framework.db.report_loot loot - end - - def cmd_perf_test_data_service_loot(*args) - host = "172.28.128.3" - name = SecureRandom.uuid - type = "file" - info = "file" - path = "/Users/jbarnett/.msf4/loot/20171005151912_default_172.28.128.3_linux.passwd_256904.txt" - data = File.read('/Users/jbarnett/rapid7/goliath/base64.txt') - - while (arg = args.shift) - case arg - when '-h' - host = args.shift - when '-n' - name = args.shift - when '-s' - service = args.shift - when '-t' - type = args.shift - when '-i' - info = args.shift - when '-p' - path = args.shift - when '-d' - data = args.shift - when '-c' - count = args.shift.to_i - end - end - - loots = [] - count.times do - loots << { :host => host, - :name => name, - :type => type, - :info => info, - :path => path, - :data => data - } - end - - puts 'Reporting test loot to data service' - start_time = Time.now - puts "#{start_time} - Staring loot perf test" - loots.each do |loot| - framework.db.report_loot loot - end - end_time = Time.now - puts "#{end_time} - Ending loot perf test. Duration was #{end_time - start_time}" - end - def cmd_workspace_help print_line "Usage:" print_line " workspace List workspaces" From 3bc0608579abf7ec82d31b7905d3e1d97062380b Mon Sep 17 00:00:00 2001 From: christopher lee Date: Thu, 1 Feb 2018 13:59:15 -0600 Subject: [PATCH 2/6] Finish POC cleanup --- lib/metasploit/framework/data_service.rb | 10 +++++++--- lib/msf/ui/console/command_dispatcher/core.rb | 16 ---------------- lib/msf/ui/console/command_dispatcher/db.rb | 6 +++++- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/lib/metasploit/framework/data_service.rb b/lib/metasploit/framework/data_service.rb index 57717af775..a5321dbec4 100644 --- a/lib/metasploit/framework/data_service.rb +++ b/lib/metasploit/framework/data_service.rb @@ -34,6 +34,9 @@ module DataService raise 'DataLService#active is not implemented'; end + # + # Hold metadata about a data service + # class Metadata attr_reader :id attr_reader :name @@ -45,14 +48,15 @@ module DataService self.active = active end + ####### private + ####### + attr_writer :id attr_writer :name attr_writer :active end - -end - +end end end diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index 001196ce30..66264bc56c 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -20,7 +20,6 @@ require 'msf/ui/console/command_dispatcher/jobs' require 'msf/ui/console/command_dispatcher/resource' require 'msf/ui/console/command_dispatcher/modules' require 'msf/util/document_generator' -require 'metasploit/framework/data_service/remote/msf_red/msf_red_service' module Msf module Ui @@ -108,7 +107,6 @@ class Core "?" => "Help menu", "banner" => "Display an awesome metasploit banner", "cd" => "Change the current working directory", - "msf_red_connect" => "Connect to MSF Platform", "connect" => "Communicate with a host", "color" => "Toggle color", "exit" => "Exit the console", @@ -263,20 +261,6 @@ class Core end - def cmd_msf_red_connect(*args) - while (arg = args.shift) - case arg - when '-u' - username = args.shift - when '-p' - password = args.shift - end - end - - msf_red_service = MSFRedService.new() - msf_red_service.launch(username, password) - end - def cmd_connect_help print_line "Usage: connect [options] " print_line diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 99d560ff47..55b42fd185 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -85,7 +85,11 @@ module Msf end def cmd_set_data_service(service_id) - framework.db.set_data_service(service_id) + begin + framework.db.set_data_service(service_id) + rescue Exception => e + print_error "Unable to set data service: #{e.message}" + end end def cmd_list_data_services() From 5a899d51266c9dd218d1dcd3cd42c4a97cc5a964 Mon Sep 17 00:00:00 2001 From: christopher lee Date: Thu, 1 Feb 2018 16:28:36 -0600 Subject: [PATCH 3/6] Renamed msfdb to avoid omnibus collision, removed inline data service startup code --- lib/metasploit/framework/command/console.rb | 1 - .../framework/data_service/proxy/core.rb | 32 +------------------ .../data_service/remote/http/core.rb | 12 +++++++ .../framework/parsed_options/base.rb | 4 --- .../framework/parsed_options/remote_db.rb | 2 ++ .../http/http_db_manager_service.rb | 15 --------- lib/msf/core/framework.rb | 2 +- lib/msf/ui/console/command_dispatcher/core.rb | 1 - msfdb => msfdb_ws | 2 +- 9 files changed, 17 insertions(+), 54 deletions(-) rename msfdb => msfdb_ws (96%) diff --git a/lib/metasploit/framework/command/console.rb b/lib/metasploit/framework/command/console.rb index 8a5d31208d..61ebe9dc30 100644 --- a/lib/metasploit/framework/command/console.rb +++ b/lib/metasploit/framework/command/console.rb @@ -79,7 +79,6 @@ class Metasploit::Framework::Command::Console < Metasploit::Framework::Command:: driver_options['DatabaseEnv'] = options.environment driver_options['DatabaseMigrationPaths'] = options.database.migrations_paths driver_options['DatabaseYAML'] = options.database.config - driver_options['DatabaseRemoteProcess'] = options.database.remote_process driver_options['DeferModuleLoads'] = options.modules.defer_loads driver_options['DisableBanner'] = options.console.quiet driver_options['DisableDatabase'] = options.database.disable diff --git a/lib/metasploit/framework/data_service/proxy/core.rb b/lib/metasploit/framework/data_service/proxy/core.rb index 4e292faf7c..2df4445878 100644 --- a/lib/metasploit/framework/data_service/proxy/core.rb +++ b/lib/metasploit/framework/data_service/proxy/core.rb @@ -110,20 +110,6 @@ class DataProxy false end - # - # Attempt to shutdown the local db process if it exists - # - def exit_called - if @pid - ilog 'Shutdown called, attempting to kill db process' - begin - Process.kill('TERM', @pid) - rescue Exception => e - elog "Unable to kill db process: #{e.message}" - end - end - end - def get_data_service raise 'No registered data_service' unless @current_data_service return @current_data_service @@ -139,14 +125,11 @@ class DataProxy if !db_manager.nil? register_data_service(db_manager, true) @usable = true - elsif opts['DatabaseRemoteProcess'] - run_remote_db_process(opts) - @usable = true else @error = 'disabled' end rescue Exception => e - raise "Unable to initialize a dataservice #{e.message}" + raise "Unable to initialize data service: #{e.message}" end end @@ -166,19 +149,6 @@ class DataProxy return false end - - def run_remote_db_process(opts) - # started with no signal to prevent ctrl-c from taking out db - db_script = File.join( Msf::Config.install_root, "msfdb -ns") - wait_t = Open3.pipeline_start(db_script) - @pid = wait_t[0].pid - dlog("Started data service process with pid #{@pid}") - - endpoint = URI.parse('http://localhost:8080') - remote_host_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint) - register_data_service(remote_host_data_service, true) - end - end end end diff --git a/lib/metasploit/framework/data_service/remote/http/core.rb b/lib/metasploit/framework/data_service/remote/http/core.rb index bd0ebd689c..ba54624ca9 100644 --- a/lib/metasploit/framework/data_service/remote/http/core.rb +++ b/lib/metasploit/framework/data_service/remote/http/core.rb @@ -31,6 +31,18 @@ class RemoteHTTPDataService build_client_pool(5) end + def connection_established? + true + end + + def after_establish_connection + + end + + def error + 'none' + end + # # POST data to the HTTP endpoint and don't wait for the endpoint to process the data before getting a response # diff --git a/lib/metasploit/framework/parsed_options/base.rb b/lib/metasploit/framework/parsed_options/base.rb index fc2bc6023d..4ccfceeb29 100644 --- a/lib/metasploit/framework/parsed_options/base.rb +++ b/lib/metasploit/framework/parsed_options/base.rb @@ -137,10 +137,6 @@ class Metasploit::Framework::ParsedOptions::Base options.database.config = path end - option_parser.on('-dbrp', 'Run database as a separate local process') do - options.database.remote_process = true - end - option_parser.separator '' option_parser.separator 'Framework options' diff --git a/lib/metasploit/framework/parsed_options/remote_db.rb b/lib/metasploit/framework/parsed_options/remote_db.rb index 9e557dc80a..49dd9c4666 100644 --- a/lib/metasploit/framework/parsed_options/remote_db.rb +++ b/lib/metasploit/framework/parsed_options/remote_db.rb @@ -22,7 +22,9 @@ class Metasploit::Framework::ParsedOptions::RemoteDB < Metasploit::Framework::Pa @options end + ####### private + ####### def option_parser unless @option_parser diff --git a/lib/msf/core/db_manager/http/http_db_manager_service.rb b/lib/msf/core/db_manager/http/http_db_manager_service.rb index 93b0b45eca..524bab606d 100644 --- a/lib/msf/core/db_manager/http/http_db_manager_service.rb +++ b/lib/msf/core/db_manager/http/http_db_manager_service.rb @@ -7,14 +7,6 @@ class HttpDBManagerService def start(opts) parsed_options = Metasploit::Framework::ParsedOptions::RemoteDB.new - if (parsed_options.options.database.no_signal) - print_warning 'Trap handling removed' - opts[:signals] = false - @shutdown_on_interupt = false - else - @shutdown_on_interupt = true - end - require_environment!(parsed_options) if opts[:ssl] @@ -36,13 +28,6 @@ class HttpDBManagerService Rack::Handler::Thin.run(SinatraApp, opts) do |server| - # TODO: prevent accidental shutdown from msfconsole eg: ctrl-c - [:INT, :TERM].each { |sig| - trap(sig) { - server.stop if (@shutdown_on_interupt || sig == :TERM) - } - } - if opts[:ssl] && opts[:ssl] = true print_good "SSL Enabled" server.ssl = true diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index 693862e329..47aa1d0e1e 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -272,7 +272,7 @@ protected private def get_db - if !options['DatabaseRemoteProcess'] && !options['DisableDatabase'] + if !options['DisableDatabase'] db_manager = Msf::DBManager.new(self) db_manager.init_db(options) options[:db_manager] = db_manager diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index 66264bc56c..3b8eb636f6 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -457,7 +457,6 @@ class Core forced = false forced = true if (args[0] and args[0] =~ /-y/i) - framework.db.exit_called if(framework.sessions.length > 0 and not forced) print_status("You have active sessions open, to exit anyway type \"exit -y\"") return diff --git a/msfdb b/msfdb_ws similarity index 96% rename from msfdb rename to msfdb_ws index ef29046ad5..87663d1973 100755 --- a/msfdb +++ b/msfdb_ws @@ -20,7 +20,7 @@ end def parse_args(args) opts = {} opt = OptionParser.new - banner = "msfdb - A remote database process for Metasploit Framework.\n" + banner = "msfdb_ws - Metasploit data store as a web service.\n" banner << "Usage: #{$0} [options] " opt.banner = banner opt.separator('') From 020a28f5c769a617420afcb23c9bbc6ad1e6814a Mon Sep 17 00:00:00 2001 From: christopher lee Date: Mon, 5 Feb 2018 13:28:17 -0600 Subject: [PATCH 4/6] Unify data service command --- lib/metasploit/framework/data_service.rb | 2 +- .../proxy/credential_data_proxy.rb | 4 +- .../data_service/proxy/event_data_proxy.rb | 2 +- .../data_service/proxy/exploit_data_proxy.rb | 6 +- .../data_service/proxy/host_data_proxy.rb | 8 +- .../data_service/proxy/loot_data_proxy.rb | 4 +- .../data_service/proxy/nmap_data_proxy.rb | 2 +- .../data_service/proxy/note_data_proxy.rb | 2 +- .../data_service/proxy/service_data_proxy.rb | 2 +- .../data_service/proxy/session_data_proxy.rb | 2 +- .../proxy/session_event_data_proxy.rb | 16 +- .../data_service/proxy/vuln_data_proxy.rb | 2 +- .../data_service/proxy/web_data_proxy.rb | 2 +- .../proxy/workspace_data_proxy.rb | 14 +- .../data_service/remote/http/core.rb | 4 +- lib/msf/ui/console/command_dispatcher/db.rb | 140 ++++++++++-------- 16 files changed, 116 insertions(+), 96 deletions(-) diff --git a/lib/metasploit/framework/data_service.rb b/lib/metasploit/framework/data_service.rb index a5321dbec4..043c8d5914 100644 --- a/lib/metasploit/framework/data_service.rb +++ b/lib/metasploit/framework/data_service.rb @@ -52,7 +52,7 @@ module DataService private ####### - attr_writer :id + attr_writer :id attr_writer :name attr_writer :active diff --git a/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb index 0c1171f132..c8ae9a1b4c 100644 --- a/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/credential_data_proxy.rb @@ -5,7 +5,7 @@ module CredentialDataProxy data_service = self.get_data_service() data_service.create_credential(opts) rescue Exception => e - elog "Call to #{data_service.class}#create_credential threw exception: #{e.message}" + elog "Problem creating credential: #{e.message}" end end @@ -14,7 +14,7 @@ module CredentialDataProxy data_service = self.get_data_service data_service.creds(opts) rescue Exception => e - elog "Call to #{data_service.class}#credentials threw exception: #{e.message}" + elog "Problem retrieving credentials: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb index a8124e8b18..403a752438 100644 --- a/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/event_data_proxy.rb @@ -5,7 +5,7 @@ module EventDataProxy data_service = self.get_data_service() data_service.report_event(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_event threw exception: #{e.message}" + elog "Problem reporting event: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb index d704228710..d211f4a5ae 100644 --- a/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/exploit_data_proxy.rb @@ -5,7 +5,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_attempt(host, opts) rescue Exception => e - elog "Call to #{data_service.class}#report_exploit_attempt threw exception: #{e.message}" + elog "Problem reporting exploit attempt: #{e.message}" end end @@ -14,7 +14,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_failure(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_exploit_failure threw exception: #{e.message}" + elog "Problem reporting exploit failure: #{e.message}" end end @@ -23,7 +23,7 @@ module ExploitDataProxy data_service = self.get_data_service() data_service.report_exploit_success(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_exploit_success threw exception: #{e.message}" + elog "Problem reporting exploit success: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb index d79617dc80..e7ef2414a5 100644 --- a/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/host_data_proxy.rb @@ -9,7 +9,7 @@ module HostDataProxy opts[:addresses] = addresses data_service.hosts(opts) rescue Exception => e - elog "Call to #{data_service.class}#hosts threw exception: #{e.message}" + elog "Problem retrieving hosts: #{e.message}" end end @@ -26,7 +26,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.report_host(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_host threw exception: #{e.message}" + elog "Problem reporting host: #{e.message}" end end @@ -35,7 +35,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.report_hosts(hosts) rescue Exception => e - elog "Call to #{data_service.class}#report_hosts threw exception: #{e.message}" + elog "Problem reporting hosts: #{e.message}" end end @@ -44,7 +44,7 @@ module HostDataProxy data_service = self.get_data_service() data_service.delete_host(opts) rescue Exception => e - elog "Call to #{data_service.class}#delete_host threw exception: #{e.message}" + elog "Problem removing host: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb index 8a4bad5b6c..00efdebf97 100644 --- a/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/loot_data_proxy.rb @@ -8,7 +8,7 @@ module LootDataProxy end data_service.report_loot(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_loot threw exception: #{e.message}" + elog "Problem reporting loot: #{e.message}" end end @@ -18,7 +18,7 @@ module LootDataProxy opts[:wspace] = wspace data_service.loot(opts) rescue Exception => e - elog "Call to #{data_service.class}#loots threw exception: #{e.message}" + elog "Problem retrieving loot: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb index 2182bdc822..3a4081bd02 100644 --- a/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/nmap_data_proxy.rb @@ -5,7 +5,7 @@ module NmapDataProxy data_service = self.get_data_service() data_service.import_nmap_xml_file(args) rescue Exception => e - elog "Call to #{data_service.class}#import_nmap_xml_file threw exception: #{e.message}" + elog "Problem importing NMAP XML: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb index 39d2f1c3e7..c3cc976a48 100644 --- a/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/note_data_proxy.rb @@ -4,7 +4,7 @@ module NoteDataProxy data_service = self.get_data_service() data_service.report_note(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_note threw exception: #{e.message}" + elog "Problem reporting note: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb index 6bb0b8ab23..c2954e9a34 100644 --- a/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/service_data_proxy.rb @@ -5,7 +5,7 @@ module ServiceDataProxy data_service = self.get_data_service() data_service.report_service(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_service threw exception: #{e.message}" + elog "Problem reporting service: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb index 1514b1199f..6f2eac47c5 100644 --- a/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/session_data_proxy.rb @@ -4,7 +4,7 @@ module SessionDataProxy data_service = self.get_data_service() data_service.report_session(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_session threw exception: #{e.message}" + elog "Problem reporting session: #{e.message}" end end end diff --git a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb index ca4f9e4851..f65268362f 100644 --- a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb @@ -1,19 +1,19 @@ module SessionEventDataProxy - def session_events - begin - data_service = self.get_data_service() - rescue Exception => e - elog "Call to #{data_service.class}#session_events threw exception: #{e.message}" - end - end + # def session_events + # begin + # data_service = self.get_data_service() + # rescue Exception => e + # elog "Problem retrieving session events: #{e.message}" + # end + # end def report_session_event(opts) begin data_service = self.get_data_service() data_service.report_session_event(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_session_event threw exception: #{e.message}" + elog "Problem reporting session event: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb index 18a4498b4b..3d96abe72c 100644 --- a/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/vuln_data_proxy.rb @@ -5,7 +5,7 @@ module VulnDataProxy data_service = self.get_data_service() data_service.report_vuln(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_vuln threw exception: #{e.message}" + elog "Problem reporting vulnerability: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb index dfa652de25..00a4df636c 100644 --- a/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/web_data_proxy.rb @@ -4,7 +4,7 @@ module WebDataProxy data_service = self.get_data_service() data_service.report_web_site(opts) rescue Exception => e - elog "Call to #{data_service.class}#report_web_site threw exception: #{e.message}" + elog "Problem reporting web site: #{e.message}" end end end \ No newline at end of file diff --git a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb index 141c24d3f0..a5cece9b85 100644 --- a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb @@ -5,7 +5,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.find_workspace(workspace_name) rescue Exception => e - elog "Call to #{data_service.class}#find_workspace threw exception: #{e.message}" + elog "Problem finding workspace: #{e.message}" end end @@ -14,7 +14,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.add_workspace(workspace_name) rescue Exception => e - elog "Call to #{data_service.class}#add_workspace threw exception: #{e.message}" + elog "Problem adding workspace: #{e.message}" end end @@ -23,7 +23,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.default_workspace rescue Exception => e - elog "Call to #{data_service.class}#default_workspace threw exception: #{e.message}" + elog "Problem getting the default workspace: #{e.message}" end end @@ -32,7 +32,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace rescue Exception => e - elog "Call to #{data_service.class}#workspace threw exception: #{e.message}" + elog "Problem retrieving workspace: #{e.message}" end end @@ -41,7 +41,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace = workspace rescue Exception => e - elog "Call to #{data_service.class}#find_workspace threw exception: #{e.message}" + elog "Problem setting workspace: #{e.message}" end end @@ -50,7 +50,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspaces rescue Exception => e - elog "Call to #{data_service.class}#workspaces threw exception: #{e.message}" + elog "Problem retrieving workspaces: #{e.message}" end end @@ -59,7 +59,7 @@ module WorkspaceDataProxy data_service = self.get_data_service() data_service.workspace_associations_counts() rescue Exception => e - elog "Call to #{data_service.class}#workspace_associations_counts threw exception: #{e.message}" + elog "Problem retrieving workspaces counts: #{e.message}" end end diff --git a/lib/metasploit/framework/data_service/remote/http/core.rb b/lib/metasploit/framework/data_service/remote/http/core.rb index ba54624ca9..c5a4209a0d 100644 --- a/lib/metasploit/framework/data_service/remote/http/core.rb +++ b/lib/metasploit/framework/data_service/remote/http/core.rb @@ -148,10 +148,10 @@ class RemoteHTTPDataService return FailedResponse.new(response) end rescue EOFError => e - elog "No data was returned from the data service for request path : #{path}, message: #{e.message}" + elog "No data was returned from the data service for request type/path : #{request_type}/#{path}, message: #{e.message}" return FailedResponse.new('') rescue Exception => e - elog "Problem with HTTP request for path: #{path} message: #{e.message}" + elog "Problem with HTTP request for type/path: #{request_type}/#{path} message: #{e.message}" return FailedResponse.new('') ensure @client_pool << client diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 55b42fd185..13e885c4b5 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -47,9 +47,7 @@ module Msf "db_export" => "Export a file containing the contents of the database", "db_nmap" => "Executes nmap and records the output automatically", "db_rebuild_cache" => "Rebuilds the database-stored module cache", - "add_data_service" => "Adds a data service to metasploit", - "list_data_services" => "List data services added to metasploit", - "set_data_service" => "Sets the data service to use", + "data_services" => "Command to add, list and set a data service", } # Always include commands that only make sense when connected. @@ -84,72 +82,24 @@ module Msf true end - def cmd_set_data_service(service_id) - begin - framework.db.set_data_service(service_id) - rescue Exception => e - print_error "Unable to set data service: #{e.message}" - end - end - - def cmd_list_data_services() - framework.db.get_services_metadata.each {|metadata| - out = "id: #{metadata.id}, name: #{metadata.name}" - if metadata.active - out += " [active]" - end - print_line out - } - end - - def cmd_add_data_service(*args) - protocol = "http" - port = 80 - https_opts = {} + def cmd_data_services(*args) while (arg = args.shift) case arg when '-h', '--help' - cmd_add_data_service_help + data_service_help + return + when '-a', '--add' + add_data_service(*args) + return + when '-s', '--set' + set_data_service(args.shift) return - when '-p' - port = args.shift - when '-s', '--ssl' - protocol = "https" - when '-c', '--cert' - https_opts[:cert] = args.shift - when '--skip-verify' - https_opts[:skip_verify] = true - else - host = arg end end - if host.nil? || port.nil? - print_error "Host and port are required." - return - end - - endpoint = "#{protocol}://#{host}:#{port}" - remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint, https_opts) - begin - framework.db.register_data_service(remote_data_service) - print_line "Registered data service: #{remote_data_service.name}" - rescue Exception => e - print_error "There was a problem registering the remote data service: #{e.message}" - end + list_data_services end - def cmd_add_data_service_help - print_line "Usage: add_data_service [ options ] [ Remote Address]" - print_line - print_line "OPTIONS:" - print_line " -h, --help Show this help information." - print_line " -p The port the data service is listening on. Default is 80." - print_line " -s, --ssl Enable SSL. Required for HTTPS data services." - print_line " -c, --cert Certificate file matching the server's certificate. Needed when using self-signed SSL cert." - print_line " --skip-verify Skip validating authenticity of server's certificate. NOT RECOMMENDED." - print_line - end def cmd_workspace_help print_line "Usage:" @@ -1938,7 +1888,77 @@ module Msf end end + ####### private + ####### + + def add_data_service(*args) + protocol = "http" + port = 80 + https_opts = {} + while (arg = args.shift) + case arg + when '-p' + port = args.shift + when '-s', '--ssl' + protocol = "https" + when '-c', '--cert' + https_opts[:cert] = args.shift + when '--skip-verify' + https_opts[:skip_verify] = true + else + host = arg + end + end + + if host.nil? || port.nil? + print_error "Host and port are required." + return + end + + endpoint = "#{protocol}://#{host}:#{port}" + remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint, https_opts) + begin + framework.db.register_data_service(remote_data_service) + print_line "Registered data service: #{remote_data_service.name}" + rescue Exception => e + print_error "There was a problem registering the remote data service: #{e.message}" + end + end + + def set_data_service(service_id) + begin + framework.db.set_data_service(service_id) + rescue Exception => e + print_error "Unable to set data service: #{e.message}" + end + end + + def list_data_services() + framework.db.get_services_metadata.each {|metadata| + out = "id: #{metadata.id}, name: #{metadata.name}" + if metadata.active + out += " [active]" + end + print_line out + } + end + + def data_service_help + print_line "Usage: data_services [ options ] - list data services by default" + print_line + print_line "OPTIONS:" + + print_line " -h, --help Show this help information." + print_line " -s, --set Set the data service by identifier." + print_line " -a, --add [ options ] host Adds data service" + print_line " Add Data Service Options:" + print_line " -p The port the data service is listening on. Default is 80." + print_line " -s, --ssl Enable SSL. Required for HTTPS data services." + print_line " -c, --cert Certificate file matching the server's certificate. Needed when using self-signed SSL cert." + print_line " --skip-verify Skip validating authenticity of server's certificate. NOT RECOMMENDED." + print_line + end def print_msgs(status_msg, error_msg) status_msg.each do |s| From 1759621b037d8b386118d78848339388989c3c1f Mon Sep 17 00:00:00 2001 From: christopher lee Date: Mon, 5 Feb 2018 15:01:03 -0600 Subject: [PATCH 5/6] Make 8080 default service port --- .../data_service/proxy/session_event_data_proxy.rb | 8 -------- lib/msf/ui/console/command_dispatcher/db.rb | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb index f65268362f..200816127c 100644 --- a/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/session_event_data_proxy.rb @@ -1,13 +1,5 @@ module SessionEventDataProxy - # def session_events - # begin - # data_service = self.get_data_service() - # rescue Exception => e - # elog "Problem retrieving session events: #{e.message}" - # end - # end - def report_session_event(opts) begin data_service = self.get_data_service() diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 13e885c4b5..5d759437c1 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -1894,7 +1894,7 @@ module Msf def add_data_service(*args) protocol = "http" - port = 80 + port = 8080 https_opts = {} while (arg = args.shift) case arg @@ -1953,7 +1953,7 @@ module Msf print_line " -s, --set Set the data service by identifier." print_line " -a, --add [ options ] host Adds data service" print_line " Add Data Service Options:" - print_line " -p The port the data service is listening on. Default is 80." + print_line " -p The port the data service is listening on. Default is 8080." print_line " -s, --ssl Enable SSL. Required for HTTPS data services." print_line " -c, --cert Certificate file matching the server's certificate. Needed when using self-signed SSL cert." print_line " --skip-verify Skip validating authenticity of server's certificate. NOT RECOMMENDED." From 272c5bc43e40dabb64652510dde23323a65f718a Mon Sep 17 00:00:00 2001 From: James Barnett Date: Mon, 5 Feb 2018 15:23:00 -0600 Subject: [PATCH 6/6] key file isnt always necessary, but cert is. --- msfdb_ws | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msfdb_ws b/msfdb_ws index 87663d1973..d44dfe1ada 100755 --- a/msfdb_ws +++ b/msfdb_ws @@ -70,7 +70,7 @@ end begin opts = parse_args(ARGV) - raise SwitchError.new("certificate file and key file must be specified when using -s") if opts[:ssl] && (opts[:ssl_key].nil? || opts[:ssl_cert].nil?) + raise SwitchError.new("certificate file must be specified when using -s") if opts[:ssl] && (opts[:ssl_cert].nil?) HttpDBManagerService.new.start(:Port => opts[:port], :Host => opts[:interface], :ssl => opts[:ssl],