Module: MetasploitPayloads
- Defined in:
- lib/metasploit-payloads.rb,
lib/metasploit-payloads/error.rb,
lib/metasploit-payloads/crypto.rb,
lib/metasploit-payloads/version.rb
Overview
This module dispenses Metasploit payload binary files
Defined Under Namespace
Modules: Crypto Classes: Error, HashMismatchError, NotFoundError, NotReadableError
Constant Summary collapse
- EXTENSION_PREFIX =
'ext_server_'
- METERPRETER_SUBFOLDER =
'meterpreter'
- USER_DATA_SUBFOLDER =
'payloads'
- VERSION =
'2.0.189'
Class Method Summary collapse
-
.data_directory ⇒ Object
Full path to the local gem folder containing the base data.
-
.list_meterpreter_extension_suffixes(extension_name = nil) ⇒ Array<String>
List all the available suffixes, optionally filtered by the given extension name.
-
.list_meterpreter_extensions(binary_suffix = nil) ⇒ Array<String>
List all the available extensions, optionally filtered by the given suffix.
-
.local_meterpreter_dir ⇒ Object
Full path to the local gem folder which contains the meterpreter binaries.
-
.manifest_errors ⇒ Array<Hash<String, Symbol>>
An array of filenames with warnings.
-
.meterpreter_enum_ext(root_dir, binary_suffix = nil) ⇒ Array<String>
Enumerate extensions in the given root folder based on an optional suffix.
-
.meterpreter_enum_ext_suffixes(root_dir, extension_name = nil) ⇒ Array<String>
Enumerate binary suffixes in the given root folder based on an optional extension name.
-
.meterpreter_ext_path(ext_name, binary_suffix) ⇒ Object
Get the path to an extension based on its name (no prefix).
-
.meterpreter_path(name, binary_suffix, debug: false) ⇒ Object
Get the path to a meterpreter binary by full name.
-
.msf_meterpreter_dir ⇒ Object
Full path to the MSF data folder which contains the meterpreter binaries.
-
.path(*path_parts) ⇒ String?
Get the full path to any file packaged in this gem or other Metasploit Framework directories by local path and name.
-
.read(*path_parts) ⇒ Object
Get the contents of any file packaged in this gem by local path and name.
-
.readable_path(gem_path, *extra_paths) ⇒ String?
Get the path for the first readable path in the provided arguments.
-
.user_meterpreter_dir ⇒ Object
Full path to the user’s MSF data folder which contains the meterpreter binaries.
- .version ⇒ Object
Class Method Details
.data_directory ⇒ Object
Full path to the local gem folder containing the base data
184 185 186 |
# File 'lib/metasploit-payloads.rb', line 184 def self.data_directory ::File.realpath(::File.join(::File.dirname(__FILE__), '..', 'data')) end |
.list_meterpreter_extension_suffixes(extension_name = nil) ⇒ Array<String>
List all the available suffixes, optionally filtered by the given extension name. This is mostly useful for determining support for a specific extension.
177 178 179 |
# File 'lib/metasploit-payloads.rb', line 177 def self.list_meterpreter_extension_suffixes(extension_name=nil) list_meterpreter_dirs { |dir| meterpreter_enum_ext_suffixes(dir, extension_name) } end |
.list_meterpreter_extensions(binary_suffix = nil) ⇒ Array<String>
List all the available extensions, optionally filtered by the given suffix.
166 167 168 |
# File 'lib/metasploit-payloads.rb', line 166 def self.list_meterpreter_extensions(binary_suffix=nil) list_meterpreter_dirs { |dir| meterpreter_enum_ext(dir, binary_suffix) } end |
.local_meterpreter_dir ⇒ Object
Full path to the local gem folder which contains the meterpreter binaries.
205 206 207 |
# File 'lib/metasploit-payloads.rb', line 205 def self.local_meterpreter_dir ::File.join(data_directory, METERPRETER_SUBFOLDER) end |
.manifest_errors ⇒ Array<Hash<String, Symbol>>
Returns An array of filenames with warnings. Provides a file name and error. Empty if all needed Meterpreter files exist and have the correct hash.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/metasploit-payloads.rb', line 19 def self.manifest_errors manifest_errors = [] begin manifest_contents = ::File.binread(manifest_path) rescue => e return [{ path: manifest_path, error: e }] end begin manifest_uuid_contents = ::File.binread(manifest_uuid_path) rescue => e manifest_errors.append({ path: manifest_uuid_path, error: e }) end # Check if the hash of the manifest file is correct. if manifest_uuid_contents manifest_digest = ::OpenSSL::Digest.new('SHA3-256', manifest_contents) uuid_matches = (manifest_uuid_contents.chomp == manifest_digest.to_s) unless uuid_matches e = ::MetasploitPayloads::HashMismatchError.new(manifest_path) manifest_errors.append({ path: manifest_path, error: e }) end end manifest_contents.each_line do |line| filename, hash_type, hash = line.chomp.split(':') begin filename = filename.sub('./data/', '') # self.path prepends the gem data directory, which is already present in the manifest file. out_path = self.path(filename) # self.path can return a path to the gem data, or user's local data. bundled_file = out_path.start_with?(data_directory) if bundled_file file_hash_match = (::OpenSSL::Digest.new(hash_type, ::File.binread(out_path)).to_s == hash) unless file_hash_match e = ::MetasploitPayloads::HashMismatchError.new(out_path) manifest_errors.append({ path: e.path, error: e }) end end rescue ::MetasploitPayloads::NotFoundError, ::MetasploitPayloads::NotReadableError => e manifest_errors.append({ path: e.path, error: e }) end end manifest_errors end |
.meterpreter_enum_ext(root_dir, binary_suffix = nil) ⇒ Array<String>
Enumerate extensions in the given root folder based on an optional suffix.
216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/metasploit-payloads.rb', line 216 def self.meterpreter_enum_ext(root_dir, binary_suffix=nil) exts = [] binary_suffix ||= '.*' ::Dir.entries(root_dir).each do |f| if ::File.readable?(::File.join(root_dir, f)) && \ f =~ /#{EXTENSION_PREFIX}(\w+)\.#{binary_suffix}/ exts.push($1) end end exts end |
.meterpreter_enum_ext_suffixes(root_dir, extension_name = nil) ⇒ Array<String>
Enumerate binary suffixes in the given root folder based on an optional extension name.
235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/metasploit-payloads.rb', line 235 def self.meterpreter_enum_ext_suffixes(root_dir, extension_name=nil) suffixes = [] extension_name ||= '\w+' ::Dir.entries(root_dir).each do |f| if ::File.readable?(::File.join(root_dir, f)) && \ f =~ /#{EXTENSION_PREFIX}#{extension_name}\.(\w+(\.\w+)*)/ suffixes.push($1) end end suffixes end |
.meterpreter_ext_path(ext_name, binary_suffix) ⇒ Object
Get the path to an extension based on its name (no prefix).
70 71 72 |
# File 'lib/metasploit-payloads.rb', line 70 def self.meterpreter_ext_path(ext_name, binary_suffix) path(METERPRETER_SUBFOLDER, "#{EXTENSION_PREFIX}#{ext_name}.#{binary_suffix}") end |
.meterpreter_path(name, binary_suffix, debug: false) ⇒ Object
Get the path to a meterpreter binary by full name.
112 113 114 115 |
# File 'lib/metasploit-payloads.rb', line 112 def self.meterpreter_path(name, binary_suffix, debug: false) binary_suffix = binary_suffix&.gsub(/dll$/, 'debug.dll') if debug path(METERPRETER_SUBFOLDER, "#{name}.#{binary_suffix}".downcase) end |
.msf_meterpreter_dir ⇒ Object
Full path to the MSF data folder which contains the meterpreter binaries.
191 192 193 |
# File 'lib/metasploit-payloads.rb', line 191 def self.msf_meterpreter_dir ::File.join(Msf::Config.data_directory, METERPRETER_SUBFOLDER) end |
.path(*path_parts) ⇒ String?
Get the full path to any file packaged in this gem or other Metasploit Framework directories by local path and name.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/metasploit-payloads.rb', line 124 def self.path(*path_parts) gem_path = (data_directory, ::File.join(path_parts)) if user_path = (Msf::Config.config_directory, ::File.join(USER_DATA_SUBFOLDER, path_parts)) msf_path = (Msf::Config.data_directory, ::File.join(path_parts)) out_path = readable_path(gem_path, user_path, msf_path) else out_path = readable_path(gem_path) end return out_path unless out_path.nil? raise ::MetasploitPayloads::NotFoundError, ::File.join(gem_path), caller unless ::File.exist?(gem_path) nil end |
.read(*path_parts) ⇒ Object
Get the contents of any file packaged in this gem by local path and name. If the file is encrypted using ChaCha20, automatically decrypt it and return the file contents.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/metasploit-payloads.rb', line 144 def self.read(*path_parts) file_path = self.path(path_parts) begin file_contents = ::File.binread(file_path) rescue ::Errno::ENOENT => _e raise ::MetasploitPayloads::NotFoundError, file_path, caller rescue ::Errno::EACCES => _e raise ::MetasploitPayloads::NotReadableError, file_path, caller rescue ::StandardError => e raise e end Crypto.decrypt(ciphertext: file_contents) end |
.readable_path(gem_path, *extra_paths) ⇒ String?
Get the path for the first readable path in the provided arguments. Start with the provided ‘extra_paths` then fall back to the `gem_path`.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/metasploit-payloads.rb', line 82 def self.readable_path(gem_path, *extra_paths) # Try the MSF path first to see if the file exists, allowing the MSF data # folder to override what is in the gem. This is very helpful for # testing/development without having to move the binaries to the gem folder # each time. We only do this is MSF is installed. extra_paths.each do |extra_path| if ::File.readable? extra_path warn_local_path(extra_path) return extra_path else # Raise rather than falling back; # If there is a local file present, let's assume that the user wants to use it (e.g. local dev. changes) # rather than having MSF Console falling back to the files in the gem raise ::MetasploitPayloads::NotReadableError, extra_path, caller if ::File.exist?(extra_path) end end return gem_path if ::File.readable? gem_path raise ::MetasploitPayloads::NotReadableError, gem_path, caller if ::File.exist?(gem_path) nil end |
.user_meterpreter_dir ⇒ Object
Full path to the user’s MSF data folder which contains the meterpreter binaries.
198 199 200 |
# File 'lib/metasploit-payloads.rb', line 198 def self.user_meterpreter_dir ::File.join(Msf::Config.config_directory, USER_DATA_SUBFOLDER, METERPRETER_SUBFOLDER) end |
.version ⇒ Object
5 6 7 |
# File 'lib/metasploit-payloads/version.rb', line 5 def self.version VERSION end |