Class: Metasploit::Credential::Importer::Core
- Inherits:
-
Object
- Object
- Metasploit::Credential::Importer::Core
- Defined in:
- lib/metasploit/credential/importer/core.rb
Overview
Creates Core objects and their associated Public, Private, and Realm objects from a CSV file.
Successful import will also create a Origin::Import
Constant Summary collapse
- BLANK_TOKEN =
This token represents an explict Blank entry. An empty field instead indicates that we do not know what this value is
"<BLANK>"
- VALID_LONG_CSV_HEADERS =
[:username, :private_type, :private_data, :realm_key, :realm_value, :host_address, :service_port, :service_name, :service_protocol, :status, :access_level, :last_attempted_at ]
- VALID_SHORT_CSV_HEADERS =
[:username, :private_data]
Constants included from Base
Base::LONG_FORM_ALLOWED_PRIVATE_TYPE_NAMES, Base::SHORT_FORM_ALLOWED_PRIVATE_TYPE_NAMES
Instance Attribute Summary collapse
-
#csv_object ⇒ CSV
An instance of ‘CSV` from whence cometh the sweet sweet credential input.
-
#private_credential_type ⇒ String
The name of one of the subclasses of Private.
Instance Method Summary collapse
-
#import! ⇒ void
If no #private_credential_type is set, assumes that the CSV contains a mixture of private types and realms.
-
#import_long_form ⇒ void
Performs an import of a “long” CSV - one that that contains realms and heterogenous private types Performs a pretty naive import from the data in #csv_object, allowing the import to have different private types per row, and attempting to reduce database lookups by storing found or created Realm objects in a lookup Hash that gets updated with every new Realm found, and then consulted in analysis of subsequent rows.
- #import_short_form ⇒ Boolean
-
#key_data_from_file(key_file_name) ⇒ String
The key data inside the file at
key_file_name
.
Methods included from Creation
#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_core, #create_credential_login, #create_credential_origin, #create_credential_origin_cracked_password, #create_credential_origin_import, #create_credential_origin_manual, #create_credential_origin_service, #create_credential_origin_session, #create_credential_private, #create_credential_public, #create_credential_realm, #create_credential_service, #invalidate_login
Methods included from Base
Instance Attribute Details
#csv_object ⇒ CSV
An instance of ‘CSV` from whence cometh the sweet sweet credential input
41 42 43 |
# File 'lib/metasploit/credential/importer/core.rb', line 41 def csv_object @csv_object end |
Instance Method Details
#import! ⇒ void
This method returns an undefined value.
If no #private_credential_type is set, assumes that the CSV contains a mixture of private types and realms. Otherwise, assume that this is a short form import and process accordingly.
84 85 86 87 88 89 90 91 |
# File 'lib/metasploit/credential/importer/core.rb', line 84 def import! if csv_object.first.headers.include? 'private_type' result = import_long_form else result = import_short_form end return result end |
#import_long_form ⇒ void
This method returns an undefined value.
Performs an import of a “long” CSV - one that that contains realms and heterogenous private types Performs a pretty naive import from the data in #csv_object, allowing the import to have different private types per row, and attempting to reduce database lookups by storing found or created Realm objects in a lookup Hash that gets updated with every new Realm found, and then consulted in analysis of subsequent rows.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/metasploit/credential/importer/core.rb', line 100 def import_long_form all_creds_valid = true realms = Hash.new Metasploit::Credential::Core.transaction do core_opts = [] rows = [] csv_object.each do |row| next if row.header_row? next unless row['username'].present? || row['private_data'].present? username = row['username'].present? ? row['username'] : '' realm_key = row['realm_key'] realm_value = row['realm_value'] # Use the name of the Realm as a lookup for getting the object private_class = row['private_type'].present? ? row['private_type'].constantize : '' private_data = row['private_data'].present? ? row['private_data'] : '' if realms[realm_value].nil? realms[realm_value] = Metasploit::Credential::Realm.where(key: realm_key, value: realm_value).first_or_create end realm_object_for_row = realms[realm_value] public_object = create_public_from_field(username) if private_class.present? && LONG_FORM_ALLOWED_PRIVATE_TYPE_NAMES.include?(private_class.name) if private_data.strip == BLANK_TOKEN private_object_for_row = Metasploit::Credential::BlankPassword.first_or_create elsif private_class == Metasploit::Credential::SSHKey private_object_for_row = Metasploit::Credential::SSHKey.where(data: key_data_from_file(private_data)).first_or_create else private_object_for_row = private_class.where(data: private_data).first_or_create end end all_creds_valid = all_creds_valid && public_object && private_object_for_row && (public_object.valid? && private_object_for_row.valid?) core_opts << {origin:origin, workspace_id: workspace.id, public: public_object, private: private_object_for_row, realm: realm_object_for_row} rows << row end if all_creds_valid core_opts.each_index do |index| row = rows[index] # Host and Service information for Logins host_address = row['host_address'] service_port = row['service_port'] service_protocol = row['service_protocol'] service_name = row['service_name'] # These were not initially included in the export, so handle # legacy cases: access_level = row['access_level'].present? ? row['access_level'] : '' last_attempted_at = row['last_attempted_at'].present? ? row['last_attempted_at'] : '' status = row['status'].present? ? row['status'] : '' if Metasploit::Credential::Core.where(core_opts[index]).blank? core = create_credential_core(core_opts[index]) else core = Metasploit::Credential::Core.where(core_opts[index]).first end if host_address.present? && service_port.present? && service_protocol.present? login_opts = { core: core, address: host_address, port: service_port, protocol: service_protocol, workspace_id: workspace.id, service_name: service_name.present? ? service_name : "" } login_opts[:last_attempted_at] = last_attempted_at unless status.blank? login_opts[:status] = status unless status.blank? login_opts[:access_level] = access_level unless access_level.blank? create_credential_login(login_opts) end end end end return all_creds_valid end |
#import_short_form ⇒ Boolean
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/metasploit/credential/importer/core.rb', line 197 def import_short_form core_opts = [] all_creds_valid = true Metasploit::Credential::Core.transaction do csv_object.each do |row| next if row.header_row? username = row['username'].present? ? row['username'] : '' private_data = row['private_data'].present? ? row['private_data'] : '' public_object = create_public_from_field(username) if private_data.strip == BLANK_TOKEN private_object_for_row = Metasploit::Credential::BlankPassword.first_or_create else private_object_for_row = @private_credential_type.constantize.where(data: private_data).first_or_create end # need to check private_object_for_row.valid? to raise a user facing message if any cred had invalid private all_creds_valid = all_creds_valid && (public_object.valid? && private_object_for_row.valid?) core_opts << {origin:origin, workspace_id: workspace.id, public: public_object, private: private_object_for_row} end if all_creds_valid core_opts.each do |item| if Metasploit::Credential::Core.where(origin: item[:origin], workspace_id: item[:workspace_id], public: item[:public], private: item[:private]).blank? create_credential_core(item) end end end end return all_creds_valid end |
#key_data_from_file(key_file_name) ⇒ String
The key data inside the file at key_file_name
76 77 78 79 |
# File 'lib/metasploit/credential/importer/core.rb', line 76 def key_data_from_file(key_file_name) full_key_file_path = File.join(File.dirname(input.path), Metasploit::Credential::Importer::Zip::KEYS_SUBDIRECTORY_NAME, key_file_name) File.open(full_key_file_path, 'r').read end |