Better handle of module cache when db_connect is run manually
parent
a7d1a61af2
commit
430351fe79
|
@ -36,15 +36,15 @@ class DBManager
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Only include Mdm if we're not using Metasploit commercial versions
|
# Only include Mdm if we're not using Metasploit commercial versions
|
||||||
# If Mdm::Host is defined, the dynamically created classes
|
# If Mdm::Host is defined, the dynamically created classes
|
||||||
# are already in the object space
|
# are already in the object space
|
||||||
begin
|
begin
|
||||||
include MetasploitDataModels unless defined? Mdm::Host
|
include MetasploitDataModels unless defined? Mdm::Host
|
||||||
rescue NameError => e
|
rescue NameError => e
|
||||||
warn_about_rubies
|
warn_about_rubies
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
|
|
||||||
# Provides :framework and other accessors
|
# Provides :framework and other accessors
|
||||||
include Framework::Offspring
|
include Framework::Offspring
|
||||||
|
@ -77,11 +77,19 @@ class DBManager
|
||||||
# Array of additional migration paths
|
# Array of additional migration paths
|
||||||
attr_accessor :migration_paths
|
attr_accessor :migration_paths
|
||||||
|
|
||||||
|
# Flag to indicate that modules are cached
|
||||||
|
attr_accessor :modules_cached
|
||||||
|
|
||||||
|
# Flag to indicate that the module cacher is running
|
||||||
|
attr_accessor :modules_caching
|
||||||
|
|
||||||
def initialize(framework, opts = {})
|
def initialize(framework, opts = {})
|
||||||
|
|
||||||
self.framework = framework
|
self.framework = framework
|
||||||
self.migrated = false
|
self.migrated = false
|
||||||
self.migration_paths = [ ::File.join(Msf::Config.install_root, "data", "sql", "migrate") ]
|
self.migration_paths = [ ::File.join(Msf::Config.install_root, "data", "sql", "migrate") ]
|
||||||
|
self.modules_cached = false
|
||||||
|
self.modules_caching = false
|
||||||
|
|
||||||
@usable = false
|
@usable = false
|
||||||
|
|
||||||
|
@ -316,8 +324,24 @@ class DBManager
|
||||||
framework.db.find_workspace(@workspace_name)
|
framework.db.find_workspace(@workspace_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def purge_all_module_details
|
||||||
|
return if not self.migrated
|
||||||
|
return if self.modules_caching
|
||||||
|
|
||||||
|
::ActiveRecord::Base.connection_pool.with_connection do
|
||||||
|
Mdm::ModuleDetail.destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def update_all_module_details
|
def update_all_module_details
|
||||||
return if not self.migrated
|
return if not self.migrated
|
||||||
|
return if self.modules_caching
|
||||||
|
|
||||||
|
self.modules_cached = false
|
||||||
|
self.modules_caching = true
|
||||||
|
|
||||||
::ActiveRecord::Base.connection_pool.with_connection {
|
::ActiveRecord::Base.connection_pool.with_connection {
|
||||||
|
|
||||||
|
@ -368,6 +392,9 @@ class DBManager
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.modules_cached = true
|
||||||
|
self.modules_caching = false
|
||||||
|
|
||||||
nil
|
nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1334,11 +1334,11 @@ class Core
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
if framework.db and framework.db.migrated
|
if framework.db and framework.db.migrated and framework.db.modules_cached
|
||||||
return search_modules_sql(match)
|
return search_modules_sql(match)
|
||||||
end
|
end
|
||||||
|
|
||||||
print_error("Warning: no database connected, falling back to slow search")
|
print_error("Warning: database not connected or cache not built, falling back to slow search")
|
||||||
|
|
||||||
tbl = generate_module_table("Matching Modules")
|
tbl = generate_module_table("Matching Modules")
|
||||||
[
|
[
|
||||||
|
|
|
@ -45,6 +45,7 @@ class Db
|
||||||
"db_import" => "Import a scan result file (filetype will be auto-detected)",
|
"db_import" => "Import a scan result file (filetype will be auto-detected)",
|
||||||
"db_export" => "Export a file containing the contents of the database",
|
"db_export" => "Export a file containing the contents of the database",
|
||||||
"db_nmap" => "Executes nmap and records the output automatically",
|
"db_nmap" => "Executes nmap and records the output automatically",
|
||||||
|
"db_rebuild_cache" => "Rebuilds the database-stored module cache"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Always include commands that only make sense when connected.
|
# Always include commands that only make sense when connected.
|
||||||
|
@ -1424,12 +1425,26 @@ class Db
|
||||||
if (::File.exists? ::File.expand_path(file))
|
if (::File.exists? ::File.expand_path(file))
|
||||||
db = YAML.load(::File.read(file))['production']
|
db = YAML.load(::File.read(file))['production']
|
||||||
framework.db.connect(db)
|
framework.db.connect(db)
|
||||||
|
|
||||||
|
if framework.db.active and not framework.db.modules_cached
|
||||||
|
print_status("Rebuilding the module cache in the background...")
|
||||||
|
framework.threads.spawn("ModuleCacheRebuild", true) do
|
||||||
|
framework.db.update_all_module_details
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
meth = "db_connect_#{framework.db.driver}"
|
meth = "db_connect_#{framework.db.driver}"
|
||||||
if(self.respond_to?(meth))
|
if(self.respond_to?(meth))
|
||||||
self.send(meth, *args)
|
self.send(meth, *args)
|
||||||
|
if framework.db.active and not framework.db.modules_cached
|
||||||
|
print_status("Rebuilding the module cache in the background...")
|
||||||
|
framework.threads.spawn("ModuleCacheRebuild", true) do
|
||||||
|
framework.db.update_all_module_details
|
||||||
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
print_error("This database driver #{framework.db.driver} is not currently supported")
|
print_error("This database driver #{framework.db.driver} is not currently supported")
|
||||||
end
|
end
|
||||||
|
@ -1456,6 +1471,26 @@ class Db
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_db_rebuild_cache
|
||||||
|
unless framework.db.active
|
||||||
|
print_error("The database is not connected")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status("Purging and rebuilding the module cache in the background...")
|
||||||
|
framework.threads.spawn("ModuleCacheRebuild", true) do
|
||||||
|
framework.db.purge_all_module_details
|
||||||
|
framework.db.update_all_module_details
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cmd_db_rebuild_cache_help
|
||||||
|
print_line "Usage: db_rebuild_cache"
|
||||||
|
print_line
|
||||||
|
print_line "Purge and rebuild the SQL module cache."
|
||||||
|
print_line
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Set RHOSTS in the +active_module+'s (or global if none) datastore from an array of addresses
|
# Set RHOSTS in the +active_module+'s (or global if none) datastore from an array of addresses
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue