This patch moves all database interaction into the metasploit core. Usage is about the same, except instead of loading a plugin, you call db_driver <driver_name>
git-svn-id: file:///home/svn/framework3/trunk@6417 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
8b32f139d3
commit
709362ff53
|
@ -23,6 +23,9 @@ class DBManager
|
|||
# Returns the list of usable database drivers
|
||||
attr_accessor :drivers
|
||||
|
||||
# Returns the active driver
|
||||
attr_accessor :driver
|
||||
|
||||
def initialize(framework)
|
||||
|
||||
self.framework = framework
|
||||
|
@ -60,7 +63,7 @@ class DBManager
|
|||
#
|
||||
def initialize_drivers
|
||||
self.drivers = []
|
||||
tdrivers = %W{ sqlite sqlite3 mysql postgresql }
|
||||
tdrivers = %W{ sqlite3 mysql postgresql }
|
||||
tdrivers.each do |driver|
|
||||
begin
|
||||
ActiveRecord::Base.establish_connection(:adapter => driver)
|
||||
|
@ -69,6 +72,10 @@ class DBManager
|
|||
rescue ::Exception
|
||||
end
|
||||
end
|
||||
|
||||
if(not self.drivers.empty?)
|
||||
self.driver = self.drivers[0]
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -77,6 +77,27 @@ module CommandDispatcher
|
|||
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_1)
|
||||
end
|
||||
|
||||
#
|
||||
# Provide command-specific tab completion
|
||||
#
|
||||
def tab_complete_helper(str, words)
|
||||
items = []
|
||||
|
||||
# Is the user trying to tab complete one of our commands?
|
||||
if (commands.include?(words[0]))
|
||||
if (self.respond_to?('cmd_'+words[0]+'_tabs'))
|
||||
res = self.send('cmd_'+words[0]+'_tabs', str, words)
|
||||
return nil if res.nil?
|
||||
items.concat(res)
|
||||
else
|
||||
# Avoid the default completion list for known commands
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
|
||||
#
|
||||
# The driver that this command dispatcher is associated with.
|
||||
#
|
||||
|
@ -111,4 +132,4 @@ end
|
|||
|
||||
end end end
|
||||
|
||||
require 'msf/ui/console/command_dispatcher/core'
|
||||
require 'msf/ui/console/command_dispatcher/core'
|
||||
|
|
|
@ -1456,27 +1456,6 @@ class Core
|
|||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Provide command-specific tab completion
|
||||
#
|
||||
def tab_complete_helper(str, words)
|
||||
items = []
|
||||
|
||||
# Is the user trying to tab complete one of our commands?
|
||||
if (commands.include?(words[0]))
|
||||
if (self.respond_to?('cmd_'+words[0]+'_tabs'))
|
||||
res = self.send('cmd_'+words[0]+'_tabs', str, words)
|
||||
return nil if res.nil?
|
||||
items.concat(res)
|
||||
else
|
||||
# Avoid the default completion list for known commands
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
|
||||
#
|
||||
# Provide tab completion for option values
|
||||
#
|
||||
|
|
|
@ -2,11 +2,13 @@ module Msf
|
|||
module Ui
|
||||
module Console
|
||||
module CommandDispatcher
|
||||
module Db
|
||||
class Db
|
||||
|
||||
require 'rexml/document'
|
||||
require 'tempfile'
|
||||
|
||||
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
|
@ -29,21 +31,31 @@ module Db
|
|||
# Returns the hash of commands supported by this dispatcher.
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"db_hosts" => "List all hosts in the database",
|
||||
"db_services" => "List all services in the database",
|
||||
"db_vulns" => "List all vulnerabilities in the database",
|
||||
"db_notes" => "List all notes in the database",
|
||||
"db_add_host" => "Add one or more hosts to the database",
|
||||
"db_add_port" => "Add a port to host",
|
||||
"db_add_note" => "Add a note to host",
|
||||
"db_del_host" => "Delete one or more hosts from the database",
|
||||
"db_autopwn" => "Automatically exploit everything",
|
||||
"db_import_amap_mlog" => "Import a THC-Amap scan results file (-o -m)",
|
||||
"db_import_nessus_nbe" => "Import a Nessus scan result file (NBE)",
|
||||
"db_import_nmap_xml" => "Import a Nmap scan results file (-oX)",
|
||||
"db_nmap" => "Executes nmap and records the output automatically",
|
||||
base = {
|
||||
"db_driver" => "Specify a database driver",
|
||||
"db_connect" => "Connect to an existing database",
|
||||
"db_disconnect" => "Disconnect from the current database instance",
|
||||
"db_create" => "Create a brand new database",
|
||||
"db_destroy" => "Drop an existing database",
|
||||
}
|
||||
|
||||
more = {
|
||||
"db_hosts" => "List all hosts in the database",
|
||||
"db_services" => "List all services in the database",
|
||||
"db_vulns" => "List all vulnerabilities in the database",
|
||||
"db_notes" => "List all notes in the database",
|
||||
"db_add_host" => "Add one or more hosts to the database",
|
||||
"db_add_port" => "Add a port to host",
|
||||
"db_add_note" => "Add a note to host",
|
||||
"db_del_host" => "Delete one or more hosts from the database",
|
||||
"db_autopwn" => "Automatically exploit everything",
|
||||
"db_import_amap_mlog" => "Import a THC-Amap scan results file (-o -m)",
|
||||
"db_import_nessus_nbe" => "Import a Nessus scan result file (NBE)",
|
||||
"db_import_nmap_xml" => "Import a Nmap scan results file (-oX)",
|
||||
"db_nmap" => "Executes nmap and records the output automatically",
|
||||
}
|
||||
|
||||
framework.db.active ? base.merge(more) : base
|
||||
end
|
||||
|
||||
def cmd_db_hosts(*args)
|
||||
|
@ -594,6 +606,558 @@ module Db
|
|||
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Database management
|
||||
#
|
||||
|
||||
def db_check_driver
|
||||
if(not framework.db.driver)
|
||||
print_error("No database driver has been specified")
|
||||
return false
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def cmd_db_driver(*args)
|
||||
|
||||
if(args[0])
|
||||
if(args[0] == "-h")
|
||||
print_status("Usage: db_driver [driver-name]")
|
||||
return
|
||||
end
|
||||
|
||||
if(framework.db.drivers.include?(args[0]))
|
||||
framework.db.driver = args[0]
|
||||
print_status("Using database driver #{args[0]}")
|
||||
else
|
||||
print_error("Invalid driver specified")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if(framework.db.driver)
|
||||
print_status(" Active Driver: #{framework.db.driver}")
|
||||
else
|
||||
print_status("No Active Driver")
|
||||
end
|
||||
print_status(" Available: #{framework.db.drivers.join(", ")}")
|
||||
end
|
||||
|
||||
def cmd_db_driver_tabs(str, words)
|
||||
return framework.db.drivers
|
||||
end
|
||||
|
||||
def cmd_db_create(*args)
|
||||
return if not db_check_driver
|
||||
meth = "db_create_#{framework.db.driver}"
|
||||
if(self.respond_to?(meth))
|
||||
self.send(meth, *args)
|
||||
else
|
||||
print_error("This database driver is not currently supported")
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_db_destroy(*args)
|
||||
return if not db_check_driver
|
||||
meth = "db_destroy_#{framework.db.driver}"
|
||||
if(self.respond_to?(meth))
|
||||
self.send(meth, *args)
|
||||
else
|
||||
print_error("This database driver is not currently supported")
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_db_connect(*args)
|
||||
return if not db_check_driver
|
||||
meth = "db_connect_#{framework.db.driver}"
|
||||
if(self.respond_to?(meth))
|
||||
self.send(meth, *args)
|
||||
else
|
||||
print_error("This database driver is not currently supported")
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_db_disconnect(*args)
|
||||
return if not db_check_driver
|
||||
meth = "db_disconnect_#{framework.db.driver}"
|
||||
if(self.respond_to?(meth))
|
||||
self.send(meth, *args)
|
||||
else
|
||||
print_error("This database driver is not currently supported")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Database management: SQLite
|
||||
#
|
||||
|
||||
#
|
||||
# Disconnect from the current SQLite instance
|
||||
#
|
||||
def db_disconnect_sqlite(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing SQLite database
|
||||
#
|
||||
def db_connect_sqlite(*args)
|
||||
|
||||
info = db_parse_db_uri_sqlite(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
if (not File.exists?(opts['dbfile']))
|
||||
print_status("The specified database does not exist")
|
||||
return
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new SQLite database instance
|
||||
#
|
||||
def db_create_sqlite(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_sqlite(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
sql = ::File.join(Msf::Config.install_root, "data", "sql", "sqlite.sql")
|
||||
|
||||
if (::File.exists?(opts['dbfile']))
|
||||
print_status("The specified database already exists, connecting")
|
||||
else
|
||||
|
||||
print_status("Creating a new database instance...")
|
||||
|
||||
db = ::SQLite3::Database.new(opts['dbfile'])
|
||||
::File.read(sql).split(";").each do |line|
|
||||
begin
|
||||
db.execute(line.strip)
|
||||
rescue ::SQLite3::SQLException, ::SQLite3::MisuseException
|
||||
end
|
||||
end
|
||||
db.close
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def db_destroy_sqlite(*args)
|
||||
cmd_db_disconnect()
|
||||
info = db_parse_db_uri_sqlite(args[0])
|
||||
File.unlink(info[:path])
|
||||
end
|
||||
|
||||
def db_parse_db_uri_sqlite(path)
|
||||
res = {}
|
||||
res[:path] = path || File.join(Msf::Config.config_directory, 'sqlite3.db')
|
||||
res
|
||||
end
|
||||
|
||||
#
|
||||
# Database management: SQLite3
|
||||
#
|
||||
|
||||
#
|
||||
# Disconnect from the current SQLite instance
|
||||
#
|
||||
def db_disconnect_sqlite3(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing SQLite database
|
||||
#
|
||||
def db_connect_sqlite3(*args)
|
||||
|
||||
info = db_parse_db_uri_sqlite3(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
if (not File.exists?(opts['dbfile']))
|
||||
print_status("The specified database does not exist")
|
||||
return
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new SQLite database instance
|
||||
#
|
||||
def db_create_sqlite3(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_sqlite3(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
sql = ::File.join(Msf::Config.install_root, "data", "sql", "sqlite.sql")
|
||||
|
||||
if (::File.exists?(opts['dbfile']))
|
||||
print_status("The specified database already exists, connecting")
|
||||
else
|
||||
|
||||
print_status("Creating a new database instance...")
|
||||
|
||||
db = ::SQLite3::Database.new(opts['dbfile'])
|
||||
::File.read(sql).split(";").each do |line|
|
||||
begin
|
||||
db.execute(line.strip)
|
||||
rescue ::SQLite3::SQLException, ::SQLite3::MisuseException
|
||||
end
|
||||
end
|
||||
db.close
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def db_destroy_sqlite3(*args)
|
||||
cmd_db_disconnect()
|
||||
info = db_parse_db_uri_sqlite3(args[0])
|
||||
File.unlink(info[:path])
|
||||
end
|
||||
|
||||
def db_parse_db_uri_sqlite3(path)
|
||||
res = {}
|
||||
res[:path] = path || ::File.join(Msf::Config.config_directory, 'sqlite3.db')
|
||||
res
|
||||
end
|
||||
|
||||
#
|
||||
# Database management: MySQL
|
||||
#
|
||||
|
||||
#
|
||||
# Disconnect from the current MySQL instance
|
||||
#
|
||||
def db_disconnect_mysql(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing MySQL database
|
||||
#
|
||||
def db_connect_mysql(*args)
|
||||
info = db_parse_db_uri_mysql(args[0])
|
||||
opts = { 'adapter' => 'mysql' }
|
||||
|
||||
opts['username'] = info[:user] if (info[:user])
|
||||
opts['password'] = info[:pass] if (info[:pass])
|
||||
opts['database'] = info[:name]
|
||||
opts['host'] = info[:host] if (info[:host])
|
||||
opts['port'] = info[:port] if (info[:port])
|
||||
|
||||
# This is an ugly hack for a broken MySQL adapter:
|
||||
# http://dev.rubyonrails.org/ticket/3338
|
||||
if (opts['host'].strip.downcase == 'localhost')
|
||||
opts['host'] = Socket.gethostbyname("localhost")[3].unpack("C*").join(".")
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new MySQL database instance
|
||||
#
|
||||
def db_create_mysql(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_mysql(args[0])
|
||||
opts = { 'adapter' => 'mysql' }
|
||||
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
opts['username'] = info[:user]
|
||||
argv.push('-u')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
argv.push('--password=' + info[:pass])
|
||||
opts['password'] = info[:pass]
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
opts['host'] = info[:host]
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
opts['port'] = info[:port]
|
||||
argv.push('-P')
|
||||
argv.push(info[:port])
|
||||
|
||||
# This is an ugly hack for a broken MySQL adapter:
|
||||
# http://dev.rubyonrails.org/ticket/3338
|
||||
if (opts['host'].strip.downcase == 'localhost')
|
||||
opts['host'] = Socket.gethostbyname("localhost")[3].unpack("C*").join(".")
|
||||
end
|
||||
end
|
||||
|
||||
argv.push('-f')
|
||||
|
||||
opts['database'] = info[:name]
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "mysql.sql")
|
||||
fd = File.open(sql, 'r')
|
||||
|
||||
system("mysqladmin #{cargs} drop #{info[:name]} >/dev/null 2>&1")
|
||||
system("mysqladmin #{cargs} create #{info[:name]}")
|
||||
|
||||
psql = File.popen("mysql #{cargs} #{info[:name]}", "w")
|
||||
psql.write(fd.read)
|
||||
psql.close
|
||||
fd.close
|
||||
|
||||
print_status("Database creation complete (check for errors)")
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def db_destroy_mysql(*args)
|
||||
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_mysql(args[0])
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
argv.push('-u')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
argv.push('--password=' + info[:pass])
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
argv.push('-P')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
argv.push("-f")
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
system("mysqladmin -f #{cargs} drop #{info[:name]}")
|
||||
end
|
||||
|
||||
def db_parse_db_uri_mysql(path)
|
||||
res = {}
|
||||
if (path)
|
||||
auth, dest = path.split('@')
|
||||
(dest = auth and auth = nil) if not dest
|
||||
res[:user],res[:pass] = auth.split(':') if auth
|
||||
targ,name = dest.split('/')
|
||||
(name = targ and targ = nil) if not name
|
||||
res[:host],res[:port] = targ.split(':') if targ
|
||||
end
|
||||
res[:name] = name || 'metasploit3'
|
||||
res
|
||||
end
|
||||
|
||||
#
|
||||
# Database management: Postgres
|
||||
#
|
||||
#
|
||||
# Disconnect from the current Postgres instance
|
||||
#
|
||||
def db_disconnect_postgres(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing Postgres database
|
||||
#
|
||||
def db_connect_postgres(*args)
|
||||
info = db_parse_db_uri_postgres(args[0])
|
||||
opts = { 'adapter' => 'postgresql' }
|
||||
|
||||
opts['username'] = info[:user] if (info[:user])
|
||||
opts['password'] = info[:pass] if (info[:pass])
|
||||
opts['database'] = info[:name]
|
||||
opts['host'] = info[:host] if (info[:host])
|
||||
opts['port'] = info[:port] if (info[:port])
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new Postgres database instance
|
||||
#
|
||||
def db_create_postgres(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_postgres(args[0])
|
||||
opts = { 'adapter' => 'postgresql' }
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
opts['username'] = info[:user]
|
||||
argv.push('-U')
|
||||
argv.push(info[:user])
|
||||
else
|
||||
opts['username'] = 'postgres'
|
||||
argv.push('-U')
|
||||
argv.push('postgres')
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
print()
|
||||
print_status("Warning: You will need to enter the password at the prompts below")
|
||||
print()
|
||||
argv.push('-W')
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
opts['host'] = info[:host]
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
opts['port'] = info[:port]
|
||||
argv.push('-p')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
opts['database'] = info[:name]
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "postgres.sql")
|
||||
fd = File.open(sql, 'r')
|
||||
|
||||
system("dropdb #{cargs} #{info[:name]} >/dev/null 2>&1")
|
||||
system("createdb #{cargs} #{info[:name]}")
|
||||
|
||||
psql = File.popen("psql -q " + cargs + info[:name], "w")
|
||||
psql.write(fd.read)
|
||||
psql.close
|
||||
fd.close
|
||||
|
||||
print_status("Database creation complete (check for errors)")
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise RuntimeError.new("Failed to connect to the database")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def db_destroy_postgres(*args)
|
||||
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = db_parse_db_uri_postgres(args[0])
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
argv.push('-U')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
print()
|
||||
print_status("Warning: You will need to enter the password at the prompts below")
|
||||
print()
|
||||
argv.push('-W')
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
argv.push('-p')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
system("dropdb #{cargs} #{info[:name]}")
|
||||
end
|
||||
|
||||
def db_parse_db_uri_postgres(path)
|
||||
res = {}
|
||||
if (path)
|
||||
auth, dest = path.split('@')
|
||||
(dest = auth and auth = nil) if not dest
|
||||
res[:user],res[:pass] = auth.split(':') if auth
|
||||
targ,name = dest.split('/')
|
||||
(name = targ and targ = nil) if not name
|
||||
res[:host],res[:port] = targ.split(':') if targ
|
||||
end
|
||||
res[:name] = name || 'metasploit3'
|
||||
res
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,6 +77,12 @@ class Driver < Msf::Ui::Driver
|
|||
# Add the core command dispatcher as the root of the dispatcher
|
||||
# stack
|
||||
enstack_dispatcher(CommandDispatcher::Core)
|
||||
|
||||
# Add the database dispatcher if it is usable
|
||||
if(framework.db.usable)
|
||||
require 'msf/ui/console/command_dispatcher/db'
|
||||
enstack_dispatcher(CommandDispatcher::Db)
|
||||
end
|
||||
|
||||
# Register event handlers
|
||||
register_event_handlers
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
require 'fileutils'
|
||||
require 'msf/ui/console/command_dispatcher/db'
|
||||
require "socket"
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# This class intializes the database db with a shiny new
|
||||
# MySQL database instance.
|
||||
#
|
||||
###
|
||||
|
||||
class Plugin::DBMySQL < Msf::Plugin
|
||||
|
||||
|
||||
#
|
||||
# Command dispatcher for configuring Mysql
|
||||
#
|
||||
class MysqlCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# The dispatcher's name.
|
||||
#
|
||||
def name
|
||||
"MySQL Database"
|
||||
end
|
||||
|
||||
#
|
||||
# The initial command set
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"db_connect" => "Connect to an existing database ( user:pass@host:port/db )",
|
||||
"db_disconnect" => "Disconnect from the current database instance",
|
||||
"db_create" => "Create a brand new database ( user:pass@host:port/db )",
|
||||
"db_destroy" => "Drop an existing database ( user:pass@host:port/db )"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Disconnect from the current MySQL instance
|
||||
#
|
||||
def cmd_db_disconnect(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
driver.remove_dispatcher('Database Backend')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing MySQL database
|
||||
#
|
||||
def cmd_db_connect(*args)
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'mysql' }
|
||||
|
||||
opts['username'] = info[:user] if (info[:user])
|
||||
opts['password'] = info[:pass] if (info[:pass])
|
||||
opts['database'] = info[:name]
|
||||
opts['host'] = info[:host] if (info[:host])
|
||||
opts['port'] = info[:port] if (info[:port])
|
||||
|
||||
# This is an ugly hack for a broken MySQL adapter:
|
||||
# http://dev.rubyonrails.org/ticket/3338
|
||||
if (opts['host'].strip.downcase == 'localhost')
|
||||
opts['host'] = Socket.gethostbyname("localhost")[3].unpack("C*").join(".")
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new MySQL database instance
|
||||
#
|
||||
def cmd_db_create(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'mysql' }
|
||||
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
opts['username'] = info[:user]
|
||||
argv.push('-u')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
argv.push('--password=' + info[:pass])
|
||||
opts['password'] = info[:pass]
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
opts['host'] = info[:host]
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
opts['port'] = info[:port]
|
||||
argv.push('-P')
|
||||
argv.push(info[:port])
|
||||
|
||||
# This is an ugly hack for a broken MySQL adapter:
|
||||
# http://dev.rubyonrails.org/ticket/3338
|
||||
if (opts['host'].strip.downcase == 'localhost')
|
||||
opts['host'] = Socket.gethostbyname("localhost")[3].unpack("C*").join(".")
|
||||
end
|
||||
end
|
||||
|
||||
argv.push('-f')
|
||||
|
||||
opts['database'] = info[:name]
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "mysql.sql")
|
||||
fd = File.open(sql, 'r')
|
||||
|
||||
system("mysqladmin #{cargs} drop #{info[:name]} >/dev/null 2>&1")
|
||||
system("mysqladmin #{cargs} create #{info[:name]}")
|
||||
|
||||
psql = File.popen("mysql #{cargs} #{info[:name]}", "w")
|
||||
psql.write(fd.read)
|
||||
psql.close
|
||||
fd.close
|
||||
|
||||
print_status("Database creation complete (check for errors)")
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def cmd_db_destroy(*args)
|
||||
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
argv.push('-u')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
argv.push('--password=' + info[:pass])
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
argv.push('-P')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
argv.push("-f")
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
system("mysqladmin -f #{cargs} drop #{info[:name]}")
|
||||
end
|
||||
|
||||
def parse_db_uri(path)
|
||||
res = {}
|
||||
if (path)
|
||||
auth, dest = path.split('@')
|
||||
(dest = auth and auth = nil) if not dest
|
||||
res[:user],res[:pass] = auth.split(':') if auth
|
||||
targ,name = dest.split('/')
|
||||
(name = targ and targ = nil) if not name
|
||||
res[:host],res[:port] = targ.split(':') if targ
|
||||
end
|
||||
res[:name] = name || 'metasploit3'
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper class for the database command dispatcher
|
||||
#
|
||||
class DatabaseCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher::Db
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Database specific initialization goes here
|
||||
#
|
||||
###
|
||||
|
||||
def initialize(framework, opts)
|
||||
super
|
||||
add_console_dispatcher(MysqlCommandDispatcher)
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
remove_console_dispatcher('MySQL Database')
|
||||
remove_console_dispatcher('Database Backend')
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a short, friendly name for the plugin.
|
||||
#
|
||||
def name
|
||||
"db_mysql"
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a brief description of the plugin. It should be no
|
||||
# more than 60 characters, but there are no hard limits.
|
||||
#
|
||||
def desc
|
||||
"Loads a new mysql database backend"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
end
|
||||
end
|
|
@ -1,229 +0,0 @@
|
|||
require 'fileutils'
|
||||
require 'msf/ui/console/command_dispatcher/db'
|
||||
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# This class intializes the database db with a shiny new
|
||||
# Postgres database instance.
|
||||
#
|
||||
###
|
||||
|
||||
class Plugin::DBPostgres < Msf::Plugin
|
||||
|
||||
|
||||
#
|
||||
# Command dispatcher for configuring Postgres
|
||||
#
|
||||
class PostgresCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# The dispatcher's name.
|
||||
#
|
||||
def name
|
||||
"Postgres Database"
|
||||
end
|
||||
|
||||
#
|
||||
# The initial command set
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"db_connect" => "Connect to an existing database ( user:pass@host:port/db )",
|
||||
"db_disconnect" => "Disconnect from the current database instance",
|
||||
"db_create" => "Create a brand new database ( user:pass@host:port/db )",
|
||||
"db_destroy" => "Drop an existing database ( user:pass@host:port/db )"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Disconnect from the current Postgres instance
|
||||
#
|
||||
def cmd_db_disconnect(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
driver.remove_dispatcher('Database Backend')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing Postgres database
|
||||
#
|
||||
def cmd_db_connect(*args)
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'postgresql' }
|
||||
|
||||
opts['username'] = info[:user] if (info[:user])
|
||||
opts['password'] = info[:pass] if (info[:pass])
|
||||
opts['database'] = info[:name]
|
||||
opts['host'] = info[:host] if (info[:host])
|
||||
opts['port'] = info[:port] if (info[:port])
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new Postgres database instance
|
||||
#
|
||||
def cmd_db_create(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'postgresql' }
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
opts['username'] = info[:user]
|
||||
argv.push('-U')
|
||||
argv.push(info[:user])
|
||||
else
|
||||
opts['username'] = 'postgres'
|
||||
argv.push('-U')
|
||||
argv.push('postgres')
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
print()
|
||||
print_status("Warning: You will need to enter the password at the prompts below")
|
||||
print()
|
||||
argv.push('-W')
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
opts['host'] = info[:host]
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
opts['port'] = info[:port]
|
||||
argv.push('-p')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
opts['database'] = info[:name]
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "postgres.sql")
|
||||
fd = File.open(sql, 'r')
|
||||
|
||||
system("dropdb #{cargs} #{info[:name]} >/dev/null 2>&1")
|
||||
system("createdb #{cargs} #{info[:name]}")
|
||||
|
||||
psql = File.popen("psql -q " + cargs + info[:name], "w")
|
||||
psql.write(fd.read)
|
||||
psql.close
|
||||
fd.close
|
||||
|
||||
print_status("Database creation complete (check for errors)")
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def cmd_db_destroy(*args)
|
||||
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
argv = []
|
||||
|
||||
if (info[:user])
|
||||
argv.push('-U')
|
||||
argv.push(info[:user])
|
||||
end
|
||||
|
||||
if (info[:pass])
|
||||
print()
|
||||
print_status("Warning: You will need to enter the password at the prompts below")
|
||||
print()
|
||||
argv.push('-W')
|
||||
end
|
||||
|
||||
if (info[:host])
|
||||
argv.push('-h')
|
||||
argv.push(info[:host])
|
||||
end
|
||||
|
||||
if (info[:port])
|
||||
argv.push('-p')
|
||||
argv.push(info[:port])
|
||||
end
|
||||
|
||||
cargs = argv.map{|c| "'#{c}' "}.join
|
||||
system("dropdb #{cargs} #{info[:name]}")
|
||||
end
|
||||
|
||||
def parse_db_uri(path)
|
||||
res = {}
|
||||
if (path)
|
||||
auth, dest = path.split('@')
|
||||
(dest = auth and auth = nil) if not dest
|
||||
res[:user],res[:pass] = auth.split(':') if auth
|
||||
targ,name = dest.split('/')
|
||||
(name = targ and targ = nil) if not name
|
||||
res[:host],res[:port] = targ.split(':') if targ
|
||||
end
|
||||
res[:name] = name || 'metasploit3'
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper class for the database command dispatcher
|
||||
#
|
||||
class DatabaseCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher::Db
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Database specific initialization goes here
|
||||
#
|
||||
###
|
||||
|
||||
def initialize(framework, opts)
|
||||
super
|
||||
add_console_dispatcher(PostgresCommandDispatcher)
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
remove_console_dispatcher('PostgreSQL Database')
|
||||
remove_console_dispatcher('Database Backend')
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a short, friendly name for the plugin.
|
||||
#
|
||||
def name
|
||||
"db_postgres"
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a brief description of the plugin. It should be no
|
||||
# more than 60 characters, but there are no hard limits.
|
||||
#
|
||||
def desc
|
||||
"Loads a new postgres database backend"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
end
|
||||
end
|
|
@ -1,172 +0,0 @@
|
|||
require 'fileutils'
|
||||
require 'msf/ui/console/command_dispatcher/db'
|
||||
require "rubygems"
|
||||
require "sqlite"
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# This class intializes the database db with a shiny new
|
||||
# SQLite2 database instance.
|
||||
#
|
||||
###
|
||||
|
||||
class Plugin::DBSQLite2 < Msf::Plugin
|
||||
|
||||
#
|
||||
# Command dispatcher for configuring SQLite
|
||||
#
|
||||
class SQLiteCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# The dispatcher's name.
|
||||
#
|
||||
def name
|
||||
"SQLite2 Database"
|
||||
end
|
||||
|
||||
#
|
||||
# The initial command set
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"db_connect" => "Connect to an existing database ( /path/to/db )",
|
||||
"db_disconnect" => "Disconnect from the current database instance",
|
||||
"db_create" => "Create a brand new database ( /path/to/db )",
|
||||
"db_destroy" => "Drop an existing database ( /path/to/db )"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Disconnect from the current SQLite instance
|
||||
#
|
||||
def cmd_db_disconnect(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
driver.remove_dispatcher('Database Backend')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing SQLite database
|
||||
#
|
||||
def cmd_db_connect(*args)
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'sqlite' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
if (not File.exists?(opts['dbfile']))
|
||||
print_status("The specified database does not exist")
|
||||
return
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new SQLite database instance
|
||||
#
|
||||
def cmd_db_create(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'sqlite' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "sqlite.sql")
|
||||
if (File.exists?(opts['dbfile']))
|
||||
print_status("The specified database already exists, connecting")
|
||||
else
|
||||
|
||||
print_status("Creating a new database instance...")
|
||||
|
||||
db = SQLite::Database.new(opts['dbfile'])
|
||||
File.read(sql).split(";").each do |line|
|
||||
begin
|
||||
db.execute(line.strip)
|
||||
rescue ::SQLite::Exceptions::SQLException, ::NoMethodError
|
||||
end
|
||||
end
|
||||
db.close
|
||||
end
|
||||
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def cmd_db_destroy(*args)
|
||||
cmd_db_disconnect()
|
||||
info = parse_db_uri(args[0])
|
||||
File.unlink(info[:path])
|
||||
end
|
||||
|
||||
def parse_db_uri(path)
|
||||
res = {}
|
||||
res[:path] = path || File.join(Msf::Config.config_directory, 'sqlite2.db')
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper class for the database command dispatcher
|
||||
#
|
||||
class DatabaseCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher::Db
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Database specific initialization goes here
|
||||
#
|
||||
###
|
||||
|
||||
def initialize(framework, opts)
|
||||
super
|
||||
add_console_dispatcher(SQLiteCommandDispatcher)
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
remove_console_dispatcher('SQLite2 Database')
|
||||
remove_console_dispatcher('Database Backend')
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a short, friendly name for the plugin.
|
||||
#
|
||||
def name
|
||||
"db_sqlite2"
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a brief description of the plugin. It should be no
|
||||
# more than 60 characters, but there are no hard limits.
|
||||
#
|
||||
def desc
|
||||
"Loads a new sqlite2 database backend"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
end
|
||||
end
|
|
@ -1,178 +0,0 @@
|
|||
require 'fileutils'
|
||||
require 'msf/ui/console/command_dispatcher/db'
|
||||
|
||||
require 'rubygems'
|
||||
require 'sqlite3'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# This class intializes the database db with a shiny new
|
||||
# SQLite3 database instance.
|
||||
#
|
||||
###
|
||||
|
||||
class Plugin::DBSQLite3 < Msf::Plugin
|
||||
|
||||
#
|
||||
# Command dispatcher for configuring SQLite
|
||||
#
|
||||
class SQLiteCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
#
|
||||
# The dispatcher's name.
|
||||
#
|
||||
def name
|
||||
"SQLite3 Database"
|
||||
end
|
||||
|
||||
#
|
||||
# The initial command set
|
||||
#
|
||||
def commands
|
||||
{
|
||||
"db_connect" => "Connect to an existing database ( /path/to/db )",
|
||||
"db_disconnect" => "Disconnect from the current database instance",
|
||||
"db_create" => "Create a brand new database ( /path/to/db )",
|
||||
"db_destroy" => "Drop an existing database ( /path/to/db )"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Disconnect from the current SQLite instance
|
||||
#
|
||||
def cmd_db_disconnect(*args)
|
||||
if (framework.db)
|
||||
framework.db.disconnect()
|
||||
driver.remove_dispatcher('Database Backend')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to an existing SQLite database
|
||||
#
|
||||
def cmd_db_connect(*args)
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
if (not File.exists?(opts['dbfile']))
|
||||
print_status("The specified database does not exist")
|
||||
return
|
||||
end
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Create a new SQLite database instance
|
||||
#
|
||||
def cmd_db_create(*args)
|
||||
cmd_db_disconnect()
|
||||
|
||||
info = parse_db_uri(args[0])
|
||||
opts = { 'adapter' => 'sqlite3' }
|
||||
|
||||
opts['dbfile'] = info[:path]
|
||||
|
||||
sql = File.join(Msf::Config.install_root, "data", "sql", "sqlite.sql")
|
||||
|
||||
if (File.exists?(opts['dbfile']))
|
||||
print_status("The specified database already exists, connecting")
|
||||
else
|
||||
|
||||
print_status("Creating a new database instance...")
|
||||
|
||||
db = SQLite3::Database.new(opts['dbfile'])
|
||||
File.read(sql).split(";").each do |line|
|
||||
begin
|
||||
db.execute(line.strip)
|
||||
rescue ::SQLite3::SQLException, ::SQLite3::MisuseException
|
||||
end
|
||||
end
|
||||
db.close
|
||||
end
|
||||
|
||||
|
||||
if (not framework.db.connect(opts))
|
||||
raise PluginLoadError.new("Failed to connect to the database")
|
||||
end
|
||||
|
||||
driver.append_dispatcher(DatabaseCommandDispatcher)
|
||||
|
||||
print_status("Successfully connected to the database")
|
||||
print_status("File: #{opts['dbfile']}")
|
||||
end
|
||||
|
||||
#
|
||||
# Drop an existing database
|
||||
#
|
||||
def cmd_db_destroy(*args)
|
||||
cmd_db_disconnect()
|
||||
info = parse_db_uri(args[0])
|
||||
File.unlink(info[:path])
|
||||
end
|
||||
|
||||
def parse_db_uri(path)
|
||||
res = {}
|
||||
res[:path] = path || File.join(Msf::Config.config_directory, 'sqlite3.db')
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper class for the database command dispatcher
|
||||
#
|
||||
class DatabaseCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher::Db
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Database specific initialization goes here
|
||||
#
|
||||
###
|
||||
|
||||
def initialize(framework, opts)
|
||||
super
|
||||
add_console_dispatcher(SQLiteCommandDispatcher)
|
||||
end
|
||||
|
||||
|
||||
def cleanup
|
||||
remove_console_dispatcher('SQLite3 Database')
|
||||
remove_console_dispatcher('Database Backend')
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a short, friendly name for the plugin.
|
||||
#
|
||||
def name
|
||||
"db_sqlite3"
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a brief description of the plugin. It should be no
|
||||
# more than 60 characters, but there are no hard limits.
|
||||
#
|
||||
def desc
|
||||
"Loads a new sqlite3 database backend"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue