Class: Metasploit::Credential::Exporter::Core
- Inherits:
-
Object
- Object
- Metasploit::Credential::Exporter::Core
- Includes:
- Base
- Defined in:
- lib/metasploit/credential/exporter/core.rb
Overview
This class is used to export Core information, optionally scoped to associated Login objects. In the case of exporting Login objects, the associated ‘Mdm::Host` and `Mdm::Server` information is exported as well. Exported data can be optionally scoped to include only a certain whitelist of database IDs.
The #export! method creates a zip file on disk containing a CSV with the data. If the ‘workspace` contains SSHKey objects on the exported Core objects, the keys are exported to files inside a subdirectory of the zip file.
Constant Summary collapse
- CORE_MODE =
The symbol representation of the mode for exporting Core objects
:core
- CREDS_DUMP_FILE_IDENTIFIER =
The pattern used to identify a creds dump zip or directory
"creds-dump"
- LOGIN_MODE =
The symbol representation of the mode for exporting Login objects
:login
- ALLOWED_MODES =
Valid modes
[LOGIN_MODE, CORE_MODE]
- DEFAULT_MODE =
The downcased and Symbolized name of the default object type to export
LOGIN_MODE
- TEMP_ZIP_PATH_PREFIX =
An argument to ‘Dir::mktmpdir`
"metasploit-exports"
Instance Attribute Summary collapse
- #export_data ⇒ ActiveRecord::Relation
-
#finalized_zip_file ⇒ Zip::File
The final output artifacts, zipped.
-
#mode ⇒ Symbol
One of ‘:login` or `:core`.
-
#whitelist_ids ⇒ Array<Fixnum>
A list of primary key IDs used to filter the objects in #export_data.
Instance Method Summary collapse
-
#data ⇒ Array
The munged data that will be iterated over for export.
-
#export! ⇒ void
Perform the export, creating the CSV and the zip file.
-
#initialize(args) ⇒ Core
constructor
A new instance of Core.
-
#line_for_core(core) ⇒ Hash
Returns a lookup for cores containing data from the given Core object’s component types in order that it can be used as a CSV row.
-
#line_for_login(login) ⇒ Hash
Take a login and return a [Hash] that will be used for a CSV row.
-
#output ⇒ IO
The IO object representing the manifest CSV that contains the exported data (other than SSH keys).
-
#output_final_directory_path ⇒ String
The platform-independent location of the export directory on disk, set in ‘Dir.tmpdir` by default.
-
#output_final_subdirectory_name ⇒ String
The final fragment of the #output_final_directory_path.
-
#output_zipfile_path ⇒ String
The path to the finished ‘Zip::File` on disk.
-
#path_for_key(datum) ⇒ String
Returns a platform-agnostic filesystem path where the key data will be saved as a file.
-
#render_manifest_output_and_keys ⇒ CSV
Iterate over the #export_data and write lines to the CSV at #output, returning the completed CSV file.
-
#render_zip ⇒ void
Creates a ‘Zip::File` by recursively zipping up the contents of #output_final_directory_path.
- #write_key_file(path, data) ⇒ void
-
#zip_filename ⇒ String
Returns the basename of the #output_final_directory_path.
Constructor Details
#initialize(args) ⇒ Core
Returns a new instance of Core.
105 106 107 108 109 |
# File 'lib/metasploit/credential/exporter/core.rb', line 105 def initialize(args) @mode = args[:mode].present? ? args.fetch(:mode) : DEFAULT_MODE fail "Invalid mode" unless ALLOWED_MODES.include?(mode) super args end |
Instance Attribute Details
#export_data ⇒ ActiveRecord::Relation
55 |
# File 'lib/metasploit/credential/exporter/core.rb', line 55 attr_writer :export_data |
#finalized_zip_file ⇒ Zip::File
The final output artifacts, zipped
60 61 62 |
# File 'lib/metasploit/credential/exporter/core.rb', line 60 def finalized_zip_file @finalized_zip_file end |
#mode ⇒ Symbol
One of ‘:login` or `:core`
65 66 67 |
# File 'lib/metasploit/credential/exporter/core.rb', line 65 def mode @mode end |
#whitelist_ids ⇒ Array<Fixnum>
A list of primary key IDs used to filter the objects in #export_data
70 71 72 |
# File 'lib/metasploit/credential/exporter/core.rb', line 70 def whitelist_ids @whitelist_ids end |
Instance Method Details
#data ⇒ Array
The munged data that will be iterated over for export
80 81 82 83 84 85 |
# File 'lib/metasploit/credential/exporter/core.rb', line 80 def data if whitelist_ids.present? export_data[:core] = export_data[:core].select{ |datum| whitelist_ids.include? datum.id } end export_data end |
#export! ⇒ void
This method returns an undefined value.
Perform the export, creating the CSV and the zip file
89 90 91 92 |
# File 'lib/metasploit/credential/exporter/core.rb', line 89 def export! render_manifest_output_and_keys render_zip end |
#line_for_core(core) ⇒ Hash
Returns a lookup for cores containing data from the given Core object’s component types in order that it can be used as a CSV row.
147 148 149 150 151 152 153 154 155 |
# File 'lib/metasploit/credential/exporter/core.rb', line 147 def line_for_core(core) { username: core.public.try(:username), private_type: core.private.try(:type), private_data: core.private.try(:data), realm_key: core.realm.try(:key), realm_value: core.realm.try(:value) } end |
#line_for_login(login) ⇒ Hash
Take a login and return a [Hash] that will be used for a CSV row. The hashes returned by this method will contain credentials for networked devices which may or may not successfully authenticate to those devices. Note that the order of columns here must match the order in Metasploit::Credential::Importer::Core::VALID_LONG_CSV_HEADERS or the headers and row values will be mismatched and break import.
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/metasploit/credential/exporter/core.rb', line 130 def line_for_login(login) result = line_for_core(login.core) result.merge({ host_address: login.service.host.address.to_s, service_port: login.service.port, service_name: login.service.try(:name), service_protocol: login.service.proto, status: login.status, access_level: login.access_level, last_attempted_at: login.last_attempted_at }) end |
#output ⇒ IO
The IO object representing the manifest CSV that contains the exported data (other than SSH keys)
159 160 161 |
# File 'lib/metasploit/credential/exporter/core.rb', line 159 def output @output ||= File.open(File.join(output_final_directory_path, Metasploit::Credential::Importer::Zip::MANIFEST_FILE_NAME), 'w') end |
#output_final_directory_path ⇒ String
The platform-independent location of the export directory on disk, set in ‘Dir.tmpdir` by default
165 166 167 168 169 170 171 172 |
# File 'lib/metasploit/credential/exporter/core.rb', line 165 def output_final_directory_path unless instance_variable_defined? :@output_final_directory_path tmp_path = Dir.mktmpdir(TEMP_ZIP_PATH_PREFIX) @output_final_directory_path = File.join(tmp_path, output_final_subdirectory_name) FileUtils.mkdir_p @output_final_directory_path end @output_final_directory_path end |
#output_final_subdirectory_name ⇒ String
The final fragment of the #output_final_directory_path
176 177 178 |
# File 'lib/metasploit/credential/exporter/core.rb', line 176 def output_final_subdirectory_name @output_final_subdiretory_name ||= "#{CREDS_DUMP_FILE_IDENTIFIER}-dump-#{workspace.id}-#{Time.now.to_i}" end |
#output_zipfile_path ⇒ String
The path to the finished ‘Zip::File` on disk
182 183 184 |
# File 'lib/metasploit/credential/exporter/core.rb', line 182 def output_zipfile_path Pathname.new(output_final_directory_path).dirname.to_s + '/' + zip_filename end |
#path_for_key(datum) ⇒ String
Returns a platform-agnostic filesystem path where the key data will be saved as a file
114 115 116 117 118 119 |
# File 'lib/metasploit/credential/exporter/core.rb', line 114 def path_for_key(datum) core = datum.is_a?(Metasploit::Credential::Core) ? datum : datum.core dir_path = File.join(output_final_directory_path, Metasploit::Credential::Importer::Zip::KEYS_SUBDIRECTORY_NAME) FileUtils.mkdir_p(dir_path) File.join(dir_path,"#{core.public.username}-#{core.private.id}") end |
#render_manifest_output_and_keys ⇒ CSV
Iterate over the #export_data and write lines to the CSV at #output, returning the completed CSV file.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/metasploit/credential/exporter/core.rb', line 189 def render_manifest_output_and_keys CSV.open(output, 'wb') do |csv| csv << Metasploit::Credential::Importer::Core::VALID_LONG_CSV_HEADERS data.each do |type_key, creds| creds.each do |datum| line = self.send("line_for_#{type_key}", datum) # Special-case any SSHKeys in the import if line[:private_type] == Metasploit::Credential::SSHKey.name key_path = path_for_key(datum) write_key_file(key_path, line[:private_data]) line[:private_data] = File.basename(key_path) end csv << line.values end end end end |
#render_zip ⇒ void
This method returns an undefined value.
Creates a ‘Zip::File` by recursively zipping up the contents of #output_final_directory_path
211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/metasploit/credential/exporter/core.rb', line 211 def render_zip zip_dir_path = Pathname.new(output_final_directory_path) Zip::File.open(output_zipfile_path, Zip::File::CREATE) do |zipfile| Dir[File.join(output_final_directory_path, '**', '**')].each do |file| file_path = Pathname.new(file) path_in_zip = file_path.relative_path_from(zip_dir_path) zipfile.add(path_in_zip, file) end end end |
#write_key_file(path, data) ⇒ void
This method returns an undefined value.
226 227 228 229 230 |
# File 'lib/metasploit/credential/exporter/core.rb', line 226 def write_key_file(path, data) File.open(path, 'w') do |file| file << data end end |
#zip_filename ⇒ String
Returns the basename of the #output_final_directory_path
234 235 236 |
# File 'lib/metasploit/credential/exporter/core.rb', line 234 def zip_filename output_final_subdirectory_name + ".zip" end |