Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/base/config.rb
Views: 11780
# -*- coding: binary -*-12#3# Standard Library4#56require 'fileutils'78#9# Project10#1112require 'metasploit/framework/version'13require 'rex/compat'1415module Msf1617# This class wraps interaction with global configuration that can be used as a18# persistent storage point for configuration, logs, and other such fun things.19class Config < Hash2021# The installation's root directory for the distribution22InstallRoot = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))2324# Determines the base configuration directory. This method should be considered `private`.25#26# @return [String] the base configuration directory27def self.get_config_root2829# Use MSF_CFGROOT_CONFIG environment variable first.30val = Rex::Compat.getenv('MSF_CFGROOT_CONFIG')31if (val and File.directory?(val))32return val33end3435# XXX Update this when there is a need to break compatibility36config_dir_major = 437config_dir = ".msf#{config_dir_major}"3839# Windows-specific environment variables40['HOME', 'LOCALAPPDATA', 'APPDATA', 'USERPROFILE'].each do |dir|41val = Rex::Compat.getenv(dir)42if (val and File.directory?(val))43return File.join(val, config_dir)44end45end4647begin48# First we try $HOME/.msfx49File.expand_path("~#{FileSep}#{config_dir}")50rescue ::ArgumentError51# Give up and install root + ".msfx"52InstallRoot + config_dir53end54end5556#57# Default values58#5960# Default system file separator.61FileSep = File::SEPARATOR6263# Default configuration locations.64Defaults =65{66'ConfigDirectory' => get_config_root,67'ConfigFile' => "config",68'ModuleDirectory' => "modules",69'ScriptDirectory' => "scripts",70'LogDirectory' => "logs",71'LogosDirectory' => "logos",72'SessionLogDirectory' => "logs/sessions",73'PluginDirectory' => "plugins",74'DataDirectory' => "data",75'LootDirectory' => "loot",76'LocalDirectory' => "local",77'HistoriesDirectory' => "histories"78}7980##81#82# Class methods83#84##8586# Returns the framework installation root.87#88# @return [String] the framework installation root {InstallRoot}.89def self.install_root90InstallRoot91end9293# Returns the configuration directory default.94#95# @return [String] the root configuration directory.96def self.config_directory97self.new.config_directory98end99100# Returns the histories directory default.101#102# @return [String] the SQL session histories directory.103def self.histories_directory104self.new.histories_directory105end106107# Return the directory that logo files should be loaded from.108#109# @return [String] path to the logos directory.110def self.logos_directory111self.new.logos_directory112end113114# Returns the global module directory.115#116# @return [String] path to global module directory.117def self.module_directory118self.new.module_directory119end120121# Returns the path that scripts can be loaded from.122#123# @return [String] path to script directory.124def self.script_directory125self.new.script_directory126end127128# Returns the directory that log files should be stored in.129#130# @return [String] path to log directory.131def self.log_directory132self.new.log_directory133end134135# Returns the directory that plugins are stored in.136#137# @return [String] path to plugin directory.138def self.plugin_directory139self.new.plugin_directory140end141142# Returns the user-specific plugin base path143#144# @return [String] path to user-specific plugin directory.145def self.user_plugin_directory146self.new.user_plugin_directory147end148149# Returns the directory in which session log files are to reside.150#151# @return [String] path to session log directory.152def self.session_log_directory153self.new.session_log_directory154end155156# Returns the directory in which captured data will reside.157#158# @return [String] path to loot directory.159def self.loot_directory160self.new.loot_directory161end162163# Returns the directory in which locally-generated data will reside.164#165# @return [String] path to locally-generated data directory.166def self.local_directory167self.new.local_directory168end169170# Return the user-specific directory that logo files should be loaded from.171#172# @return [String] path to the logos directory.173def self.user_logos_directory174self.new.user_logos_directory175end176177# Returns the user-specific module base path178#179# @return [String] path to user-specific modules directory.180def self.user_module_directory181self.new.user_module_directory182end183184# Returns the user-specific script base path185#186# @return [String] path to user-specific script directory.187def self.user_script_directory188self.new.user_script_directory189end190191# @return [String] path to user-specific data directory.192def self.user_data_directory193self.new.user_data_directory194end195196# Returns the data directory197#198# @return [String] path to data directory.199def self.data_directory200self.new.data_directory201end202203# Returns the full path to the configuration file.204#205# @return [String] path to the configuration file.206def self.config_file207self.new.config_file208end209210# Returns the full path to the history file.211#212# @return [String] path to the history file.213def self.history_file214self.new.history_file215end216217# Returns the full path to the meterpreter history file.218#219# @return [String] path to the history file.220def self.meterpreter_history221self.new.meterpreter_history222end223224# Returns the full path to the smb session history file.225#226# @return [String] path to the history file.227def self.smb_session_history228self.new.smb_session_history229end230231# Returns the full path to the ldap session history file.232#233# @return [String] path to the history file.234def self.ldap_session_history235self.new.ldap_session_history236end237238# Returns the full path to the MySQL interactive query history file239#240# @return [String] path to the interactive query history file.241def self.history_file_for_session_type(opts)242self.new.history_file_for_session_type(opts)243end244245def self.pry_history246self.new.pry_history247end248# Returns the full path to the fav_modules file.249#250# @return [String] path to the fav_modules file.251def self.fav_modules_file252self.new.fav_modules_file253end254255# Returns the full path to the handler file.256#257# @return [String] path to the handler file.258def self.persist_file259self.new.persist_file260end261262# Initializes configuration, creating directories as necessary.263#264# @return [void]265def self.init266self.new.init267end268269# Loads configuration from the supplied file path, or the default one if270# none is specified.271#272# @param path [String] the path to the configuration file.273# @return [Rex::Parser::Ini] INI file parser.274def self.load(path = nil)275self.new.load(path)276end277278# Saves configuration to the path specified in the ConfigFile hash key or279# the default path if one isn't specified. The options should be group280# references that have named value pairs.281#282# @param opts [Hash] Hash containing configuration options.283# @option opts 'ConfigFile' [Hash] configuration file these options apply284# to.285# @return [void]286# @example Save 'Cat' => 'Foo' in group 'ExampleGroup'287# save(288# 'ExampleGroup' =>289# {290# 'Foo' => 'Cat'291# })292def self.save(opts)293self.new.save(opts)294end295296# Deletes the specified config group from the ini file297#298# @param group [String] The name of the group to remove299# @return [void]300def self.delete_group(group)301self.new.delete_group(group)302end303304# Updates the config class' self with the default hash.305#306# @return [Hash] the updated Hash.307def initialize308update(Defaults)309end310311# Returns the installation root directory312#313# @return [String] the installation root directory {InstallRoot}.314def install_root315InstallRoot316end317318# Return the directory that logo files should be loaded from.319#320# @return [String] path to the logos directory.321def logos_directory322data_directory + FileSep + self['LogosDirectory']323end324325# Returns the configuration directory default.326#327# @return [String] the root configuration directory.328def config_directory329self['ConfigDirectory']330end331332# Returns the histories directory default.333#334# @return [String] the SQL session histories directory.335def histories_directory336config_directory + FileSep + self['HistoriesDirectory']337end338339# Returns the full path to the configuration file.340#341# @return [String] path to the configuration file.342def config_file343config_directory + FileSep + self['ConfigFile']344end345346# Returns the full path to the history file.347#348# @return [String] path the history file.349def history_file350config_directory + FileSep + "history"351end352353def meterpreter_history354config_directory + FileSep + "meterpreter_history"355end356357def smb_session_history358config_directory + FileSep + "smb_session_history"359end360361def ldap_session_history362config_directory + FileSep + "ldap_session_history"363end364365def history_options_valid?(opts)366return false if (opts[:session_type].nil? || opts[:interactive].nil?)367368true369end370371def interactive_to_string_map(interactive)372# Check for true explicitly rather than just a value that is truthy.373interactive == true ? '_interactive' : ''374end375376def history_file_for_session_type(opts)377return nil unless history_options_valid?(opts)378379session_type_name = opts[:session_type]380interactive = interactive_to_string_map(opts[:interactive])381382histories_directory + FileSep + "#{session_type_name}_session#{interactive}_history"383end384385def pry_history386config_directory + FileSep + "pry_history"387end388389# Returns the full path to the fav_modules file.390#391# @return [String] path the fav_modules file.392def fav_modules_file393config_directory + FileSep + "fav_modules"394end395396# Returns the full path to the handler file.397#398# @return [String] path the handler file.399def persist_file400config_directory + FileSep + "persist"401end402403# Returns the global module directory.404#405# @return [String] path to global module directory.406def module_directory407install_root + FileSep + self['ModuleDirectory']408end409410# Returns the path that scripts can be loaded from.411#412# @return [String] path to script directory.413def script_directory414install_root + FileSep + self['ScriptDirectory']415end416417# Returns the directory that log files should be stored in.418#419# @return [String] path to log directory.420def log_directory421config_directory + FileSep + self['LogDirectory']422end423424# Returns the directory that plugins are stored in.425#426# @return [String] path to plugin directory.427def plugin_directory428install_root + FileSep + self['PluginDirectory']429end430431# Returns the directory in which session log files are to reside.432#433# @return [String] path to session log directory.434def session_log_directory435config_directory + FileSep + self['SessionLogDirectory']436end437438# Returns the directory in which captured data will reside.439#440# @return [String] path to loot directory.441def loot_directory442config_directory + FileSep + self['LootDirectory']443end444445# Returns the directory in which locally-generated data will reside.446#447# @return [String] path to locally-generated data directory.448def local_directory449config_directory + FileSep + self['LocalDirectory']450end451452# Return the user-specific directory that logo files should be loaded from.453#454# @return [String] path to the logos directory.455def user_logos_directory456config_directory + FileSep + self['LogosDirectory']457end458459# Returns the user-specific module base path460#461# @return [String] path to user-specific modules directory.462def user_module_directory463config_directory + FileSep + "modules"464end465466# Returns the user-specific plugin base path467#468# @return [String] path to user-specific plugin directory.469def user_plugin_directory470config_directory + FileSep + "plugins"471end472473# Returns the user-specific script base path474#475# @return [String] path to user-specific script directory.476def user_script_directory477config_directory + FileSep + "scripts"478end479480# @return [String] path to user-specific data directory.481def user_data_directory482config_directory + FileSep + self['DataDirectory']483end484485# Returns the data directory486#487# @return [String] path to data directory.488def data_directory489install_root + FileSep + self['DataDirectory']490end491492# Initializes configuration, creating directories as necessary.493#494# @return [void]495def init496FileUtils.mkdir_p(module_directory)497FileUtils.mkdir_p(config_directory)498FileUtils.mkdir_p(log_directory)499FileUtils.mkdir_p(session_log_directory)500FileUtils.mkdir_p(loot_directory)501FileUtils.mkdir_p(local_directory)502FileUtils.mkdir_p(user_logos_directory)503FileUtils.mkdir_p(user_module_directory)504FileUtils.mkdir_p(user_plugin_directory)505FileUtils.mkdir_p(user_data_directory)506FileUtils.mkdir_p(histories_directory)507end508509# Loads configuration from the supplied file path, or the default one if510# none is specified.511#512# @param path [String] the path to the configuration file.513# @return [Rex::Parser::Ini] INI file parser.514def load(path = nil)515path = config_file if (!path)516517return Rex::Parser::Ini.new(path)518end519520# Saves configuration to the path specified in the ConfigFile hash key or521# the default path if one isn't specified. The options should be group522# references that have named value pairs.523#524# @param opts [Hash] Hash containing configuration options.525# @option opts 'ConfigFile' [Hash] configuration file these options apply526# to.527# @return [void]528# @example Save 'Cat' => 'Foo' in group 'ExampleGroup'529# save(530# 'ExampleGroup' =>531# {532# 'Foo' => 'Cat'533# })534def save(opts)535ini = Rex::Parser::Ini.new(opts['ConfigFile'] || config_file)536537ini.update(opts)538539ini.to_file540end541542# Deletes the specified config group from the ini file543#544# @param group [String] The name of the group to remove545# @return [void]546def delete_group(group)547ini = Rex::Parser::Ini.new(config_file)548549ini.delete(group)550551ini.to_file552end553end554555end556557558