# -*- coding: binary -*- # # Gems # require 'rex/socket' # # Project # require 'metasploit/framework/require' require 'metasploit/framework/data_service' # The db module provides persistent storage and events. This class should be instantiated LAST # as the active_suppport library overrides Kernel.require, slowing down all future code loads. class Msf::DBManager extend Metasploit::Framework::Require # Default proto for making new `Mdm::Service`s. This should probably be a # const on `Mdm::Service` DEFAULT_SERVICE_PROTO = "tcp" autoload :Adapter, 'msf/core/db_manager/adapter' autoload :Client, 'msf/core/db_manager/client' autoload :Connection, 'msf/core/db_manager/connection' autoload :Cred, 'msf/core/db_manager/cred' autoload :DBExport, 'msf/core/db_manager/db_export' autoload :Event, 'msf/core/db_manager/event' autoload :ExploitAttempt, 'msf/core/db_manager/exploit_attempt' autoload :ExploitedHost, 'msf/core/db_manager/exploited_host' autoload :Host, 'msf/core/db_manager/host' autoload :HostDetail, 'msf/core/db_manager/host_detail' autoload :HostTag, 'msf/core/db_manager/host_tag' autoload :Import, 'msf/core/db_manager/import' autoload :ImportMsfXml, 'msf/core/db_manager/import_msf_xml' autoload :IPAddress, 'msf/core/db_manager/ip_address' autoload :Login, 'msf/core/db_manager/login' autoload :Loot, 'msf/core/db_manager/loot' autoload :Migration, 'msf/core/db_manager/migration' autoload :ModuleCache, 'msf/core/db_manager/module_cache' autoload :Note, 'msf/core/db_manager/note' autoload :Payload, 'msf/core/db_manager/payload' autoload :Ref, 'msf/core/db_manager/ref' autoload :Report, 'msf/core/db_manager/report' autoload :Route, 'msf/core/db_manager/route' autoload :Service, 'msf/core/db_manager/service' autoload :Session, 'msf/core/db_manager/session' autoload :SessionEvent, 'msf/core/db_manager/session_event' autoload :Task, 'msf/core/db_manager/task' autoload :User, 'msf/core/db_manager/user' autoload :Vuln, 'msf/core/db_manager/vuln' autoload :VulnAttempt, 'msf/core/db_manager/vuln_attempt' autoload :VulnDetail, 'msf/core/db_manager/vuln_detail' autoload :WMAP, 'msf/core/db_manager/wmap' autoload :Web, 'msf/core/db_manager/web' autoload :Workspace, 'msf/core/db_manager/workspace' optionally_include_metasploit_credential_creation # Interface must be included first include Metasploit::Framework::DataService include Msf::DBManager::Adapter include Msf::DBManager::Client include Msf::DBManager::Connection include Msf::DBManager::Cred include Msf::DBManager::DBExport include Msf::DBManager::Event include Msf::DBManager::ExploitAttempt include Msf::DBManager::ExploitedHost include Msf::DBManager::Host include Msf::DBManager::HostDetail include Msf::DBManager::HostTag include Msf::DBManager::Import include Msf::DBManager::IPAddress include Msf::DBManager::Login include Msf::DBManager::Loot include Msf::DBManager::Migration include Msf::DBManager::ModuleCache include Msf::DBManager::Note include Msf::DBManager::Payload include Msf::DBManager::Ref include Msf::DBManager::Report include Msf::DBManager::Route include Msf::DBManager::Service include Msf::DBManager::Session include Msf::DBManager::SessionEvent include Msf::DBManager::Task include Msf::DBManager::User include Msf::DBManager::Vuln include Msf::DBManager::VulnAttempt include Msf::DBManager::VulnDetail include Msf::DBManager::WMAP include Msf::DBManager::Web include Msf::DBManager::Workspace # Provides :framework and other accessors include Msf::Framework::Offspring def name 'local_db_service' end def is_local? true end # # Attributes # # Stores the error message for why the db was not loaded attr_accessor :error # Returns true if the prerequisites have been installed attr_accessor :usable # # initialize # def initialize(framework, opts = {}) self.framework = framework self.migrated = nil self.modules_cached = false self.modules_caching = false @usable = false # Don't load the database if the user said they didn't need it. if (opts['DisableDatabase']) self.error = "disabled" return end return initialize_database_support end # # Instance Methods # # # Determines if the database is functional # def check ::ApplicationRecord.connection_pool.with_connection { res = ::Mdm::Host.first } end # # Do what is necessary to load our database support # def initialize_database_support begin add_rails_engine_migration_paths @usable = true rescue ::Exception => e self.error = e elog('DB is not enabled due to load error', error: e) return false end # # Determine what drivers are available # initialize_adapter true end def init_db(opts) init_success = false # Append any migration paths necessary to bring the database online if opts['DatabaseMigrationPaths'] opts['DatabaseMigrationPaths'].each do |migrations_path| ActiveRecord::Migrator.migrations_paths << migrations_path end end configuration_pathname = Metasploit::Framework::Database.configurations_pathname(path: opts['DatabaseYAML']) if configuration_pathname.nil? self.error = "No database YAML file" else if configuration_pathname.readable? # parse specified database YAML file, using the same pattern as Rails https://github.com/rails/rails/pull/42249 dbinfo = begin YAML.load_file(configuration_pathname, aliases: true) || {} rescue ArgumentError YAML.load_file(configuration_pathname) || {} end dbenv = opts['DatabaseEnv'] || Rails.env db_opts = dbinfo[dbenv] else elog("Warning, #{configuration_pathname} is not readable. Try running as root or chmod.") end if db_opts init_success = connect(db_opts) else elog("No database definition for environment #{dbenv}") end end # framework.db.active will be true if after_establish_connection ran directly when connection_established? was # already true or if framework.db.connect called after_establish_connection. if !! error if error.to_s =~ /RubyGem version.*pg.*0\.11/i err_msg = <<~ERROR *** * * Metasploit now requires version 0.11 or higher of the 'pg' gem for database support * There are three ways to accomplish this upgrade: * 1. If you run Metasploit with your system ruby, simply upgrade the gem: * $ rvmsudo gem install pg * 2. Use the Community Edition web interface to apply a Software Update * 3. Uninstall, download the latest version, and reinstall Metasploit * *** ERROR elog(err_msg) end # +error+ is not an instance of +Exception+, it is, in fact, a +String+ elog("Failed to connect to the database: #{error}") end return init_success end end