Class: Msf::Modules::Loader::Executable
- Defined in:
- lib/msf/core/modules/loader/executable.rb
Overview
Concerns loading executables from a directory as modules
Constant Summary
Constants inherited from Base
Base::DIRECTORY_BY_TYPE, Base::MODULE_EXTENSION, Base::MODULE_SEPARATOR, Base::NAMESPACE_MODULE_CONTENT, Base::NAMESPACE_MODULE_LINE, Base::NAMESPACE_MODULE_NAMES, Base::TYPE_BY_DIRECTORY, Base::UNIT_TEST_REGEX
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#each_module_reference_name(path, opts = {}) {|parent_path, type, module_reference_name| ... } ⇒ void
protected
Yields the module_reference_name for each module file found under the directory path.
-
#loadable?(path) ⇒ true, false
Returns true if the path is a directory.
-
#loadable_module?(parent_path, type, module_reference_name, cached_metadata: nil) ⇒ Boolean
True this loader can load the module, false otherwise.
-
#module_path(parent_path, type, module_reference_name) ⇒ String
protected
Returns the full path to the module file on disk.
-
#read_module_content(parent_path, type, module_reference_name) ⇒ String
protected
Loads the module content from the on disk file.
-
#read_module_content_from_path(full_path) ⇒ String
protected
Loads the module content from the on disk file.
- #read_script_env_runtime(full_path) ⇒ Object protected
-
#script_runtime_available?(full_path) ⇒ Boolean
protected
True if the script’s required runtime is available on the host, false otherwise.
Methods inherited from Base
#create_namespace_module, #current_module, #initialize, #load_error, #load_module, #load_modules, #load_warning, #module_path?, #module_reference_name_from_path, #namespace_module_name, #namespace_module_names, #namespace_module_transaction, #reload_module, #restore_namespace_module, reverse_relative_name, #script_path?, typed_path, #typed_path
Constructor Details
This class inherits a constructor from Msf::Modules::Loader::Base
Instance Method Details
#each_module_reference_name(path, opts = {}) {|parent_path, type, module_reference_name| ... } ⇒ void (protected)
This method returns an undefined value.
Yields the module_reference_name for each module file found under the directory path.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/msf/core/modules/loader/executable.rb', line 56 def each_module_reference_name(path, opts={}) whitelist = opts[:whitelist] || [] ::Dir.foreach(path) do |entry| full_entry_path = ::File.join(path, entry) type = entry.singularize unless ::File.directory?(full_entry_path) && module_manager.type_enabled?(type) next end full_entry_pathname = Pathname.new(full_entry_path) # Try to load modules from all the files in the supplied path Rex::Find.find(full_entry_path) do |entry_descendant_path| # Assume that all modules are scripts for now, workaround # filesystems where all files are labeled as executable. if script_path?(entry_descendant_path) entry_descendant_pathname = Pathname.new(entry_descendant_path) relative_entry_descendant_pathname = entry_descendant_pathname.relative_path_from(full_entry_pathname) relative_entry_descendant_path = relative_entry_descendant_pathname.to_s next if File::basename(relative_entry_descendant_path).start_with?('example') # The module_reference_name doesn't have a file extension module_reference_name = File.join(File.dirname(relative_entry_descendant_path), File.basename(relative_entry_descendant_path, '.*')) yield path, type, module_reference_name end end end end |
#loadable?(path) ⇒ true, false
Returns true if the path is a directory
10 11 12 |
# File 'lib/msf/core/modules/loader/executable.rb', line 10 def loadable?(path) File.directory?(path) end |
#loadable_module?(parent_path, type, module_reference_name, cached_metadata: nil) ⇒ Boolean
Returns True this loader can load the module, false otherwise.
19 20 21 22 |
# File 'lib/msf/core/modules/loader/executable.rb', line 19 def loadable_module?(parent_path, type, module_reference_name, cached_metadata: nil) full_path = &.path || module_path(parent_path, type, module_reference_name) script_path?(full_path) end |
#module_path(parent_path, type, module_reference_name) ⇒ String (protected)
Returns the full path to the module file on disk.
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/msf/core/modules/loader/executable.rb', line 90 def module_path(parent_path, type, module_reference_name) # The extension is lost on loading, hit the disk to recover :( partial_path = File.join(DIRECTORY_BY_TYPE[type], module_reference_name) full_path = File.join(parent_path, partial_path) Rex::Find.find(File.dirname(full_path)) do |mod| if File.basename(full_path, '.*') == File.basename(mod, '.*') return File.join(File.dirname(full_path), File.basename(mod)) end end '' end |
#read_module_content(parent_path, type, module_reference_name) ⇒ String (protected)
Loads the module content from the on disk file.
108 109 110 111 112 |
# File 'lib/msf/core/modules/loader/executable.rb', line 108 def read_module_content(parent_path, type, module_reference_name) full_path = module_path(parent_path, type, module_reference_name) read_module_content_from_path(full_path) end |
#read_module_content_from_path(full_path) ⇒ String (protected)
Loads the module content from the on disk file.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/msf/core/modules/loader/executable.rb', line 118 def read_module_content_from_path(full_path) unless script_path?(full_path) load_error(full_path, Errno::ENOENT.new) return '' end unless script_runtime_available?(full_path) load_error(full_path, RuntimeError.new("Unable to load module as the following runtime was not found on the path: #{read_script_env_runtime(full_path)}")) return '' end begin content = Msf::Modules::External::Shim.generate(full_path, @module_manager.framework) if content return content else elog "Unable to load module #{full_path}, unknown module type" return '' end rescue LoadError => e load_error(full_path, e) return '' rescue ::Exception => e elog("Unable to load module #{full_path}", error: e) # XXX migrate this to a full load_error when we can tell the user why the # module did not load and/or how to resolve it. # load_error(full_path, e) '' end end |
#read_script_env_runtime(full_path) ⇒ Object (protected)
26 27 28 29 30 31 32 |
# File 'lib/msf/core/modules/loader/executable.rb', line 26 def read_script_env_runtime(full_path) # Extract the runtime from the first line of the script, i.e. # #!/usr/bin/env python # //usr/bin/env go run "$0" "$@"; exit "$?" first_line = File.open(full_path, 'rb') { |f| f.gets } first_line.to_s[%r{\A(?:#!|/)/usr/bin/env\s+(\w+)}, 1] end |
#script_runtime_available?(full_path) ⇒ Boolean (protected)
Returns True if the script’s required runtime is available on the host, false otherwise.
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/msf/core/modules/loader/executable.rb', line 36 def script_runtime_available?(full_path) return false unless script_path?(full_path) # Modules currently use /usr/bin/env - in the future absolute paths may need to be supported script_runtime = read_script_env_runtime(full_path) return !!Rex::FileUtils.find_full_path(script_runtime) if script_runtime # If the script runtime isn't known, we assume the script is executable true end |