Class: Metasploit::Credential::Migrator

Inherits:
Object
  • Object
show all
Includes:
Creation
Defined in:
lib/metasploit/credential/migrator.rb

Overview

This class provides migration behavior for converting ‘Mdm::Cred` objects to their appropriate counterparts in the Metasploit::Credential namespace.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Creation

#active_db?, #create_cracked_credential, #create_credential, #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

Constructor Details

#initialize(workspace = nil) ⇒ void

Sets up a migrator object with either a single workspace or all workspaces

Parameters:

  • the (Mdm::Workspace)

    workspace to act on



26
27
28
29
30
31
32
33
34
# File 'lib/metasploit/credential/migrator.rb', line 26

def initialize(workspace=nil)
  @origin = Metasploit::Credential::Origin::Import.new(filename: 'MIGRATION')

  if workspace.present?
    @workspaces = [workspace]
  else
    @workspaces = Mdm::Workspace.all
  end
end

Instance Attribute Details

#originMetasploit::Credential::Origin::Import

An origin for tracking how these credentials made it into the system. Treating this as an Import since there is no migration origin.



13
14
15
# File 'lib/metasploit/credential/migrator.rb', line 13

def origin
  @origin
end

#workspacesArray<Mdm::Workspace>

Where the migrated creds will originate

Returns:

  • (Array<Mdm::Workspace>)


20
21
22
# File 'lib/metasploit/credential/migrator.rb', line 20

def workspaces
  @workspaces
end

Instance Method Details

#convert_creds_in_workspace(workspace) ⇒ void

This method returns an undefined value.

Converts the ‘Mdm::Cred` objects in a single `Mdm::Workspace`

Parameters:

  • the (Mdm::Workspace)

    workspace to act on



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
85
86
87
# File 'lib/metasploit/credential/migrator.rb', line 58

def convert_creds_in_workspace(workspace)
  workspace.creds.each do |cred|
    service = cred.service
    begin
      core = create_credential(
        origin: origin,
        private_data: private_data_from_cred(cred),
        private_type: cred_type_to_credential_class(cred.ptype),
        username: cred.user,
        workspace_id: workspace.id
      )
    rescue ActiveRecord::RecordInvalid => e
      logger = Metasploit::Credential::Core.logger

      logger.error("#{__method__} - Failed to migrate: #{cred.user}, Mdm::Cred id #{cred.id}")
      logger.error("#{__method__} -    validation errors: #{e}")
      logger.error("#{__method__} -    failing record: #{e.record.inspect}")
    else
      (
        address: service.host.address,
        core: core,
        port: service.port,
        protocol: service.proto,
        service_name: service.name,
        status: Metasploit::Model::Login::Status::UNTRIED,
        workspace_id: workspace.id
      )
    end
  end
end

#cred_type_to_credential_class(cred_type) ⇒ Object

Converts types in the legacy credentials model to a type in the new one. Assumes that anything that isn’t ‘smb_hash’ but contains ‘hash’ will be a NonreplaybleHash. @return

Parameters:

  • cred_type (String)

    the value from the ptype field of ‘Mdm::Cred`



95
96
97
98
99
100
# File 'lib/metasploit/credential/migrator.rb', line 95

def cred_type_to_credential_class(cred_type)
  return :ntlm_hash if cred_type == "smb_hash"
  return :ssh_key if cred_type == "ssh_key"
  return :nonreplayable_hash if cred_type.include? "hash"
  return :password
end

#creds_exist?Boolean

Returns true if #workspaces contains ‘Mdm::Cred` objects

Returns:

  • (Boolean)


38
39
40
# File 'lib/metasploit/credential/migrator.rb', line 38

def creds_exist?
  workspaces.map(&:creds).flatten.present?
end

#key_data_from_file(path) ⇒ String

Returns the text of the SSH key as read from the file

Parameters:

  • path (String)

    Path to an SSH key file on disk

Returns:

  • (String)


105
106
107
108
109
110
111
112
113
# File 'lib/metasploit/credential/migrator.rb', line 105

def key_data_from_file(path)
  # Sometimes we will set the :pass attribute to a file path containing the key
  if File.exists?(path)
    File.read(path)
  # In other cases we store the entire SSH key directly in the :pass attribute
  elsif Metasploit::Credential::SSHKey.new(data: path).private?
    path
  end
end

#migrate!void

This method returns an undefined value.

Perform the migration



44
45
46
47
48
49
50
51
52
53
# File 'lib/metasploit/credential/migrator.rb', line 44

def migrate!
  if creds_exist?
    Metasploit::Credential::Core.transaction do
      origin.save # we are going to use the one we instantiated earlier, since there is work to be done
      workspaces.each do |workspace|
        convert_creds_in_workspace(workspace)
      end
    end
  end
end

#private_data_from_cred(cred) ⇒ Object

Returns private data given an ‘Mdm::Cred` @return

Parameters:

  • cred (Mdm::Cred)


118
119
120
121
122
123
124
125
# File 'lib/metasploit/credential/migrator.rb', line 118

def private_data_from_cred(cred)
  case cred.ptype
  when 'ssh_key'
    key_data_from_file(cred.pass)
  else
    cred.pass
  end
end