Better handle of module cache when db_connect is run manually

unstable
HD Moore 2012-07-10 23:56:48 -05:00
parent a7d1a61af2
commit 430351fe79
4 changed files with 72 additions and 10 deletions

0
data/exploits/CVE-2012-1723.jar Normal file → Executable file
View File

View File

@ -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
} }

View File

@ -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")
[ [

View File

@ -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
# #