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 56 57 |
# File 'lib/metasploit/credential/exporter/core.rb', line 55 def export_data @export_data end |
#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.
141 142 143 144 145 146 147 148 149 |
# File 'lib/metasploit/credential/exporter/core.rb', line 141 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.
127 128 129 130 131 132 133 134 135 |
# File 'lib/metasploit/credential/exporter/core.rb', line 127 def line_for_login(login) result = line_for_core(login.core) result.merge({ host_address: login.service.host.address, service_port: login.service.port, service_name: login.service.try(:name), service_protocol: login.service.proto }) end |
#output ⇒ IO
The IO object representing the manifest CSV that contains the exported data (other than SSH keys)
153 154 155 |
# File 'lib/metasploit/credential/exporter/core.rb', line 153 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
159 160 161 162 163 164 165 166 |
# File 'lib/metasploit/credential/exporter/core.rb', line 159 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
170 171 172 |
# File 'lib/metasploit/credential/exporter/core.rb', line 170 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
176 177 178 |
# File 'lib/metasploit/credential/exporter/core.rb', line 176 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.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/metasploit/credential/exporter/core.rb', line 183 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
205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/metasploit/credential/exporter/core.rb', line 205 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.
220 221 222 223 224 |
# File 'lib/metasploit/credential/exporter/core.rb', line 220 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
228 229 230 |
# File 'lib/metasploit/credential/exporter/core.rb', line 228 def zip_filename output_final_subdirectory_name + ".zip" end |