From 42767814aea2bc198f1420555eb7ddd52a4d683a Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Wed, 19 Aug 2020 12:32:02 +0100 Subject: [PATCH 1/3] Improve boot time --- Gemfile | 1 + Gemfile.lock | 2 + lib/metasploit/framework.rb | 2 +- lib/metasploit/framework/command/base.rb | 33 +++++----- .../framework/thread_factory_provider.rb | 6 +- lib/msf/core/db_manager/connection.rb | 17 ++--- lib/msf/core/framework.rb | 2 +- lib/msf/ui/console/command_dispatcher/core.rb | 2 +- lib/msf/ui/console/driver.rb | 62 +++++++++---------- msfconsole | 8 ++- 10 files changed, 73 insertions(+), 62 deletions(-) diff --git a/Gemfile b/Gemfile index a1e202d18c8f3..a34498a8b3c71 100755 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,7 @@ group :development do # Metasploit::Aggregator external session proxy # disabled during 2.5 transition until aggregator is available #gem 'metasploit-aggregator' + gem 'stackprof' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 73314797b2089..c35cac2479f2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -409,6 +409,7 @@ GEM tilt (~> 2.0) sqlite3 (1.3.13) sshkey (2.0.0) + stackprof (0.2.15) swagger-blocks (3.0.0) thin (1.7.2) daemons (~> 1.0, >= 1.0.9) @@ -457,6 +458,7 @@ DEPENDENCIES ruby-prof simplecov (= 0.18.2) sqlite3 (~> 1.3.0) + stackprof swagger-blocks timecop yard diff --git a/lib/metasploit/framework.rb b/lib/metasploit/framework.rb index b872a0a153ee5..dc675e98b8ea4 100644 --- a/lib/metasploit/framework.rb +++ b/lib/metasploit/framework.rb @@ -8,7 +8,7 @@ require 'active_support' require 'bcrypt' require 'json' -require 'msgpack' +# require 'msgpack' require 'metasploit/credential' require 'nokogiri' require 'packetfu' diff --git a/lib/metasploit/framework/command/base.rb b/lib/metasploit/framework/command/base.rb index 62b3515a2a5fb..974666b06722c 100644 --- a/lib/metasploit/framework/command/base.rb +++ b/lib/metasploit/framework/command/base.rb @@ -46,21 +46,21 @@ class Metasploit::Framework::Command::Base def self.require_environment! parsed_options = self.parsed_options # RAILS_ENV must be set before requiring 'config/application.rb' - parsed_options.environment! - ARGV.replace(parsed_options.positional) - - # allow other Rails::Applications to use this command - if !defined?(Rails) || Rails.application.nil? - # @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/commands.rb#L39-L40 - require Pathname.new(__FILE__).parent.parent.parent.parent.parent.join('config', 'application') - end - - # have to configure before requiring environment because - # config/environment.rb calls initialize! and the initializers will use - # the configuration from the parsed options. - parsed_options.configure(Rails.application) - - Rails.application.require_environment! + # parsed_options.environment! + # ARGV.replace(parsed_options.positional) + # + # # allow other Rails::Applications to use this command + # if !defined?(Rails) || Rails.application.nil? + # # @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/commands.rb#L39-L40 + # require Pathname.new(__FILE__).parent.parent.parent.parent.parent.join('config', 'application') + # end + # + # # have to configure before requiring environment because + # # config/environment.rb calls initialize! and the initializers will use + # # the configuration from the parsed options. + # parsed_options.configure(Rails.application) + # + # Rails.application.require_environment! parsed_options end @@ -79,7 +79,8 @@ def self.parsed_options_class_name def self.start parsed_options = require_environment! - new(application: Rails.application, parsed_options: parsed_options).start + # new(application: Rails.application, parsed_options: parsed_options).start + new(application: nil, parsed_options: parsed_options).start end # diff --git a/lib/metasploit/framework/thread_factory_provider.rb b/lib/metasploit/framework/thread_factory_provider.rb index 82709047e687e..a520927660976 100644 --- a/lib/metasploit/framework/thread_factory_provider.rb +++ b/lib/metasploit/framework/thread_factory_provider.rb @@ -6,11 +6,15 @@ # # framework.threads created here # Rex::ThreadFactory.spawn("name", false) { ... } # -class Metasploit::Framework::ThreadFactoryProvider < Metasploit::Model::Base +class Metasploit::Framework::ThreadFactoryProvider # WTF??? < Metasploit::Model::Base # # Attributes # + def initialize(framework:) + self.framework = framework + end + # @!attribute framework # The framework managing the spawned threads. # diff --git a/lib/msf/core/db_manager/connection.rb b/lib/msf/core/db_manager/connection.rb index db8ff4b18a284..b2c0e8240d54d 100644 --- a/lib/msf/core/db_manager/connection.rb +++ b/lib/msf/core/db_manager/connection.rb @@ -113,14 +113,15 @@ def create_db(opts) # @return [true] if an active connection can be made to the database using the current config. # @return [false] if an active connection cannot be made to the database. def connection_established? - begin - # use with_connection so the connection doesn't stay pinned to the thread. - ApplicationRecord.connection_pool.with_connection { - ApplicationRecord.connection.active? - } - rescue ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad => error - false - end + # begin + # # use with_connection so the connection doesn't stay pinned to the thread. + # ApplicationRecord.connection_pool.with_connection { + # ApplicationRecord.connection.active? + # } + # rescue ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad => error + # false + # end + false end # diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index be62b37e22d3d..ad3c538257052 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -288,7 +288,7 @@ def search(match, logger: nil) private def get_db - unless options['DisableDatabase'] + unless options['DisableDatabase'] || true db_manager = Msf::DBManager.new(self) options[:db_manager] = db_manager unless options['SkipDatabaseInit'] diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index 4526079839437..c1087256ce7de 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -21,7 +21,7 @@ require 'msf/ui/console/command_dispatcher/resource' require 'msf/ui/console/command_dispatcher/modules' require 'msf/ui/console/command_dispatcher/developer' -require 'msf/util/document_generator' +# require 'msf/util/document_generator' require 'optparse' diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index 5fa47bfd7d872..6f415e9beccb6 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -4,7 +4,7 @@ require 'msf/ui' require 'msf/ui/console/framework_event_manager' require 'msf/ui/console/command_dispatcher' -require 'msf/ui/console/command_dispatcher/db' +# require 'msf/ui/console/command_dispatcher/db' require 'msf/ui/console/command_dispatcher/creds' require 'msf/ui/console/table' require 'find' @@ -36,7 +36,7 @@ class Driver < Msf::Ui::Driver CommandDispatcher::Modules, CommandDispatcher::Jobs, CommandDispatcher::Resource, - CommandDispatcher::Db, + # CommandDispatcher::Db, CommandDispatcher::Creds, CommandDispatcher::Developer ] @@ -232,35 +232,35 @@ def load_preconfig end def load_db_config(path=nil) - begin - conf = Msf::Config.load(path) - rescue - wlog("Failed to load configuration: #{$!}") - return - end - - if conf.group?(DbConfigGroup) - conf[DbConfigGroup].each_pair do |k, v| - if k.downcase == 'default_db' - ilog "Default data service found. Attempting to connect..." - default_db_config_path = "#{DbConfigGroup}/#{v}" - default_db = conf[default_db_config_path] - if default_db - connect_string = "db_connect #{v}" - - if framework.db.active && default_db['url'] !~ /http/ - ilog "Existing local data connection found. Disconnecting first." - run_single("db_disconnect") - end - - run_single(connect_string) - else - elog "Config entry for '#{default_db_config_path}' could not be found. Config file might be corrupt." - return - end - end - end - end + # begin + # conf = Msf::Config.load(path) + # rescue + # wlog("Failed to load configuration: #{$!}") + # return + # end + # + # if conf.group?(DbConfigGroup) + # conf[DbConfigGroup].each_pair do |k, v| + # if k.downcase == 'default_db' + # ilog "Default data service found. Attempting to connect..." + # default_db_config_path = "#{DbConfigGroup}/#{v}" + # default_db = conf[default_db_config_path] + # if default_db + # connect_string = "db_connect #{v}" + # + # if framework.db.active && default_db['url'] !~ /http/ + # ilog "Existing local data connection found. Disconnecting first." + # run_single("db_disconnect") + # end + # + # run_single(connect_string) + # else + # elog "Config entry for '#{default_db_config_path}' could not be found. Config file might be corrupt." + # return + # end + # end + # end + # end end # diff --git a/msfconsole b/msfconsole index 62294a4e31f68..c50f9ac9f582b 100755 --- a/msfconsole +++ b/msfconsole @@ -6,7 +6,7 @@ # require 'pathname' - +require 'stackprof' begin # Silences warnings as they only serve to confuse end users @@ -19,8 +19,10 @@ begin require 'metasploit/framework/profiler' require 'metasploit/framework/command/console' require 'msf/core/payload_generator' - Metasploit::Framework::Profiler.start - Metasploit::Framework::Command::Console.start + # Metasploit::Framework::Profiler.start + # StackProf.run(mode: :wall, out: 'test_prof_wall_time.dump', raw: true, ignore_gc: true) do + Metasploit::Framework::Command::Console.start + # end rescue Interrupt puts "\nAborting..." exit(1) From 97b2478ea5d9e36a3a234a1c66f9ec4a0313de98 Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Fri, 21 Aug 2020 13:07:58 +0100 Subject: [PATCH 2/3] Only require things that are actually required --- lib/msf/base/logging.rb | 2 +- lib/msf/base/simple.rb | 16 ++++----- lib/msf/base/simple/buffer.rb | 2 +- lib/msf/base/simple/framework.rb | 35 +++++++++++-------- .../ui/console/command_dispatcher/payload.rb | 1 + lib/msf/ui/console/driver.rb | 7 ++-- 6 files changed, 35 insertions(+), 28 deletions(-) diff --git a/lib/msf/base/logging.rb b/lib/msf/base/logging.rb index 893d97031a321..17390ef31d0fd 100644 --- a/lib/msf/base/logging.rb +++ b/lib/msf/base/logging.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- require 'rex' -require 'msf/base' +# require 'msf/base' module Msf diff --git a/lib/msf/base/simple.rb b/lib/msf/base/simple.rb index f460f450b98ad..7fcd12caa5921 100644 --- a/lib/msf/base/simple.rb +++ b/lib/msf/base/simple.rb @@ -4,14 +4,14 @@ require 'msf/base/simple/statistics' # Simplified module interfaces -require 'msf/base/simple/module' -require 'msf/base/simple/encoder' -require 'msf/base/simple/exploit' -require 'msf/base/simple/nop' -require 'msf/base/simple/payload' -require 'msf/base/simple/auxiliary' -require 'msf/base/simple/post' -require 'msf/base/simple/evasion' +# require 'msf/base/simple/module' +# require 'msf/base/simple/encoder' +# require 'msf/base/simple/exploit' +# require 'msf/base/simple/nop' +# require 'msf/base/simple/payload' +# require 'msf/base/simple/auxiliary' +# require 'msf/base/simple/post' +# require 'msf/base/simple/evasion' # Simplified framework interface require 'msf/base/simple/framework' diff --git a/lib/msf/base/simple/buffer.rb b/lib/msf/base/simple/buffer.rb index 1daaa8bdd4b44..a993b778fd8ff 100644 --- a/lib/msf/base/simple/buffer.rb +++ b/lib/msf/base/simple/buffer.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- -require 'msf/base' +# require 'msf/base' module Msf module Simple diff --git a/lib/msf/base/simple/framework.rb b/lib/msf/base/simple/framework.rb index 498ae2c3fe57e..469ab3b984810 100644 --- a/lib/msf/base/simple/framework.rb +++ b/lib/msf/base/simple/framework.rb @@ -1,7 +1,10 @@ # -*- coding: binary -*- -require 'msf/base/simple' +# require 'msf/base/simple' require 'msf/base/simple/framework/module_paths' require 'msf/base/simple/noop_job_listener' +require 'msf/base/simple/statistics' +require 'msf/base/logging' + module Msf module Simple @@ -50,18 +53,19 @@ def load(path, opts = {}) # Simplifies module instances when they're created. # def on_module_created(instance) - Msf::Simple::Framework.simplify_module(instance) + # Msf::Simple::Framework.simplify_module(instance) + instance end ModuleSimplifiers = { - Msf::MODULE_ENCODER => Msf::Simple::Encoder, - Msf::MODULE_EXPLOIT => Msf::Simple::Exploit, - Msf::MODULE_NOP => Msf::Simple::Nop, - Msf::MODULE_PAYLOAD => Msf::Simple::Payload, - Msf::MODULE_AUX => Msf::Simple::Auxiliary, - Msf::MODULE_POST => Msf::Simple::Post, - Msf::MODULE_EVASION => Msf::Simple::Evasion + # Msf::MODULE_ENCODER => Msf::Simple::Encoder, + # Msf::MODULE_EXPLOIT => Msf::Simple::Exploit, + # Msf::MODULE_NOP => Msf::Simple::Nop, + # Msf::MODULE_PAYLOAD => Msf::Simple::Payload, + # Msf::MODULE_AUX => Msf::Simple::Auxiliary, + # Msf::MODULE_POST => Msf::Simple::Post, + # Msf::MODULE_EVASION => Msf::Simple::Evasion } # Create a simplified instance of the framework. This routine takes a hash @@ -131,12 +135,13 @@ def self.simplify(framework, opts) # with the simplified module interface. # def self.simplify_module(instance, load_saved_config = true) - if ((ModuleSimplifiers[instance.type]) and - (instance.class.include?(ModuleSimplifiers[instance.type]) == false)) - instance.extend(ModuleSimplifiers[instance.type]) - - instance.init_simplified(load_saved_config) - end + # if ((ModuleSimplifiers[instance.type]) and + # (instance.class.include?(ModuleSimplifiers[instance.type]) == false)) + # instance.extend(ModuleSimplifiers[instance.type]) + # + # instance.init_simplified(load_saved_config) + # end + instance end diff --git a/lib/msf/ui/console/command_dispatcher/payload.rb b/lib/msf/ui/console/command_dispatcher/payload.rb index f219cc5095371..e4df1af4bd0d3 100644 --- a/lib/msf/ui/console/command_dispatcher/payload.rb +++ b/lib/msf/ui/console/command_dispatcher/payload.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'rex/parser/arguments' +require 'msf/base/simple/buffer.rb' module Msf module Ui diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index 6f415e9beccb6..fb07a1d20d9d7 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -1,11 +1,12 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/base' +# require 'msf/base' +require 'msf/base/simple/framework' require 'msf/ui' require 'msf/ui/console/framework_event_manager' require 'msf/ui/console/command_dispatcher' # require 'msf/ui/console/command_dispatcher/db' -require 'msf/ui/console/command_dispatcher/creds' +# require 'msf/ui/console/command_dispatcher/creds' require 'msf/ui/console/table' require 'find' require 'erb' @@ -37,7 +38,7 @@ class Driver < Msf::Ui::Driver CommandDispatcher::Jobs, CommandDispatcher::Resource, # CommandDispatcher::Db, - CommandDispatcher::Creds, + # CommandDispatcher::Creds, CommandDispatcher::Developer ] From c4e4eb91e86a48aa61fc43391f4bef38f93a1087 Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Fri, 21 Aug 2020 18:46:39 +0100 Subject: [PATCH 3/3] Only require things that are actually required --- lib/metasploit/framework/command/console.rb | 2 +- lib/msf/ui/console/driver.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/metasploit/framework/command/console.rb b/lib/metasploit/framework/command/console.rb index 61ebe9dc30e78..df51843096246 100644 --- a/lib/metasploit/framework/command/console.rb +++ b/lib/metasploit/framework/command/console.rb @@ -57,7 +57,7 @@ def start def driver unless @driver # require here so minimum loading is done before {start} is called. - require 'msf/ui' + require 'msf/ui/console/driver' @driver = Msf::Ui::Console::Driver.new( Msf::Ui::Console::Driver::DefaultPrompt, diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index fb07a1d20d9d7..9ef1f06fac44e 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -2,7 +2,8 @@ require 'msf/core' # require 'msf/base' require 'msf/base/simple/framework' -require 'msf/ui' +# require 'msf/ui' +require 'msf/ui/driver' require 'msf/ui/console/framework_event_manager' require 'msf/ui/console/command_dispatcher' # require 'msf/ui/console/command_dispatcher/db'