Class: Mdm::Host

Inherits:
ApplicationRecord
  • Object
show all
Extended by:
ActiveSupport::Autoload
Includes:
OperatingSystemNormalization, Metasploit::Model::Search
Defined in:
app/models/mdm/host.rb

Overview

A system with an IP address on the network that has been discovered in some way.

Defined Under Namespace

Modules: OperatingSystemNormalization

Constant Summary collapse

UNKNOWN_ARCHITECTURE =

Special #arch value to indicate we should look at #detected_arch instead

'Unknown'
ARCHITECTURES =

Either the CPU architecture for native code or the programming language name for exploits that run code in the programming language's virtual machine.

[
    'armbe',
    'armle',
    'cbea',
    'cbea64',
    'cmd',
    'java',
    'mips',
    'mipsbe',
    'mipsle',
    'php',
    'ppc',
    'ppc64',
    'ruby',
    'sparc',
    'tty',
    # To be used for compatability with 'X86_64'
    'x64',
    'x86',
    'x86_64',
    '',
    UNKNOWN_ARCHITECTURE
]
SEARCH_FIELDS =

Fields searched for the search scope

[
    'address::text',
    'comments',
    'mac',
    'name',
    'os_flavor',
    'os_name',
    'os_sp',
    'purpose'
]
STATES =

Valid values for #state.

[
    'alive',
    'down',
    'unknown'
]
MAC_ADDRESS_HYPHEN_REGEX =

Valid MAC address value hyphen-separated: 1a-2B-3c-4D-5e-6f

/\A(?:[A-F0-9]{2}[-]){5}[A-F0-9]{2}\z/i
MAC_ADDRESS_COLON_REGEX =

colon-separated: 1a:2B:3c:4D:5e:6f

/\A(?:[A-F0-9]{2}[:]){5}[A-F0-9]{2}\z/i
MAC_ADDRESS_EMPTY_REGEX =

XXX for now, allow en empty MAC so as not to break things that exist with empty MACs.

/\A\z/
MAC_ADDRESS_REGEX =

6-tuple of hex (case-insensitive) doublets (or empty)

Regexp.union(MAC_ADDRESS_HYPHEN_REGEX, MAC_ADDRESS_COLON_REGEX,
MAC_ADDRESS_EMPTY_REGEX)

Constants included from OperatingSystemNormalization

OperatingSystemNormalization::MAX_NMAP_CERTAINTY

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from OperatingSystemNormalization

#apply_match_to_host, #get_arch_from_string, #guess_purpose_from_match, #normalize_fusionvm_fingerprint, #normalize_generic_fingerprint, #normalize_match, #normalize_match_family, #normalize_mbsa_fingerprint, #normalize_nessus_fingerprint, #normalize_nexpose_fingerprint, #normalize_nmap_fingerprint, #normalize_os, #normalize_qualys_fingerprint, #normalize_retina_fingerprint, #normalize_scanner_fp, #normalize_session_fingerprint, #parse_windows_os_str, #recog_matches_for_note, #recog_matches_for_service, #sanitize, #service_banner_recog_filter_ssh, #validate_fingerprint_data

Instance Attribute Details

#addressString

The IP address of this host.

Returns:

  • (String)

87
88
89
# File 'app/models/mdm/host.rb', line 87

def address
  self[:address].to_s
end

#archString

The architecture of the host's CPU OR the programming language for virtual machine programming language like Ruby, PHP, and Java.

Returns:


# File 'app/models/mdm/host.rb', line 334

#clientsActiveRecord::Relation<Mdm::Client>

Users connected to this host

Returns:


99
100
101
102
# File 'app/models/mdm/host.rb', line 99

has_many :clients,
class_name: 'Mdm::Client',
dependent: :destroy,
inverse_of: :host

#commString

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 340

#commentsString

User supplied comments about host.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 345

#created_atDateTime

When this host was created in the database.

Returns:

  • (DateTime)

# File 'app/models/mdm/host.rb', line 350

#cred_countInteger

Counter cache for #creds.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 355

#credsActiveRecord::Relation<Mdm::Cred> (readonly)

Credentials captured from #services.

Returns:

See Also:


236
# File 'app/models/mdm/host.rb', line 236

has_many :creds, :class_name => 'Mdm::Cred', :through => :services

#detected_archString

The architecture of the host's CPU as detected by Recog. If #arch is not UNKNOWN_ARCHITECTURE, this is undefined.

Returns:

  • (String)

    a free-form string most likely from network data


# File 'app/models/mdm/host.rb', line 360

#eventsActiveRecord::Relation<Mdm::Event>

Events that occurred on this host.

Returns:


108
109
110
111
# File 'app/models/mdm/host.rb', line 108

has_many :events,
class_name: 'Mdm::Event',
dependent: :delete_all,
inverse_of: :host

#exploit_attempt_countInteger

Counter cache for #exploit_attempts.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 366

#exploit_attemptsActiveRecord::Relation<Mdm::ExploitAttempt]

Attempts to run exploits against this host.

Returns:

  • (ActiveRecord::Relation<Mdm::ExploitAttempt])

    ActiveRecord::Relation<Mdm::ExploitAttempt]


126
127
128
129
# File 'app/models/mdm/host.rb', line 126

has_many :exploit_attempts,
class_name: 'Mdm::ExploitAttempt',
dependent: :destroy,
inverse_of: :host

#exploited_hostsActiveRecord::Relation<Mdm::ExploitedHost>

TODO:

MSP-2732

Returns:


134
135
136
137
# File 'app/models/mdm/host.rb', line 134

has_many :exploited_hosts,
class_name: 'Mdm::ExploitedHost',
dependent: :destroy,
inverse_of: :host

#host_detail_countInteger

Counter cache for #host_details.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 371

#host_detailsActiveRecord::Relation<Mdm::HostDetail>

Returns:


141
142
143
144
# File 'app/models/mdm/host.rb', line 141

has_many :host_details,
class_name: 'Mdm::HostDetail',
dependent: :destroy,
inverse_of: :host

#hosts_tagsActiveRecord::Relation<Mdm::HostTag>

TODO:

MSP-2723

A join model between Tag and Mdm::Host. Use #tags to get the actual Mdm::Tags on this host.

Returns:


151
152
153
154
# File 'app/models/mdm/host.rb', line 151

has_many :hosts_tags,
class_name: 'Mdm::HostTag',
dependent: :destroy,
inverse_of: :host

#infoString

Information about this host gathered from the host.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 376

#lootsActiveRecord::Relation<Mdm::Loot>

TODO:

MSP-3065

Loot gathered from the host with newest loot first.

Returns:


161
162
163
164
165
# File 'app/models/mdm/host.rb', line 161

has_many :loots,
-> { order('loots.created_at DESC')},
class_name: 'Mdm::Loot',
dependent: :destroy,
inverse_of: :host

#macString

The MAC address of this host.

Returns:

  • (String)

See Also:


# File 'app/models/mdm/host.rb', line 381

#module_detailsActiveRecord::Relation<Mdm::Module::Detail] (readonly)

Details about modules that were used to find vulnerabilities on this host.

Returns:

  • (ActiveRecord::Relation<Mdm::Module::Detail])

    ActiveRecord::Relation<Mdm::Module::Detail]


319
320
321
322
# File 'app/models/mdm/host.rb', line 319

has_many :module_details, -> { distinct } ,
:class_name => 'Mdm::Module::Detail',
:source =>:detail,
:through => :module_refs

#module_refsActiveRecord::Relation<Mdm::Module::Ref> (readonly)

Returns:


309
# File 'app/models/mdm/host.rb', line 309

has_many :module_refs, :class_name => 'Mdm::Module::Ref', :through => :refs

#module_runsActiveRecord::Relation<MetasploitDataModels::ModuleRun> (readonly)

Records of Metasploit modules being run on/against this Mdm::Host

Returns:

See Also:


260
261
262
# File 'app/models/mdm/host.rb', line 260

has_many :module_runs,
class_name: 'MetasploitDataModels::ModuleRun',
as: :trackable

#nameString

The name of the host. If the host name is not available, then it will just be the IP address.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 387

#note_countInteger

Counter cache for #notes.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 392

#notesActiveRecord::Relation<Mdm::Note>

Notes about the host entered by a user with oldest notes first.

Returns:


171
172
173
174
175
# File 'app/models/mdm/host.rb', line 171

has_many :notes,
-> { order('notes.created_at') },
class_name: 'Mdm::Note',
inverse_of: :host,
dependent: :delete_all

#os_flavorString

The flavor of #os_name.

Examples:

Windows XP

host.os_name = 'Windows'
host.os_flavor = 'XP'

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 397

#os_langString

Free-form language of operating system. Usually either spelled out like 'English' or an IETF language tag like 'en' or 'en-US'.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 406

#os_nameString

The name of the operating system.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 412

#os_spString

The service pack of the #os_flavor of the #os_name.

Examples:

Windows XP SP2

host.os_name = 'Windows'
host.os_flavor = 'XP'
host.os_sp = 'SP2'

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 417

#purposeString

The purpose of the host on the network, such as 'client' or 'firewall'.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 427

#refsActiveRecord::Relation<Mdm::Ref> (readonly)

External references, such as CVE, to vulnerabilities found on this host.

Returns:

See Also:


299
# File 'app/models/mdm/host.rb', line 299

has_many :refs, :class_name => 'Mdm::Ref', :through => :vuln_refs

#scopeString

Interface identifier for link-local IPv6


# File 'app/models/mdm/host.rb', line 432

#service_countInteger

Counter cache for #services.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 438

#service_notesActiveRecord::Relation<Mdm::Note> (readonly)

Notes about #services running on this host.

Returns:

See Also:


243
244
245
246
# File 'app/models/mdm/host.rb', line 243

has_many :service_notes,
class_name: 'Mdm::Note',
source: :notes,
through: :services

#servicesActiveRecord::Relation<Mdm::Service>

The services running on ports on the host with services ordered by port and protocol.

Returns:


182
183
184
185
186
# File 'app/models/mdm/host.rb', line 182

has_many :services,
-> { order('services.port, services.proto') },
class_name: 'Mdm::Service',
dependent: :destroy,
inverse_of: :host

#sessionsActiveRecord::Relation<Mdm::Session]

Sessions that are open or previously were open on the host ordered by when the session was opened

Returns:

  • (ActiveRecord::Relation<Mdm::Session])

    ActiveRecord::Relation<Mdm::Session]


193
194
195
196
197
# File 'app/models/mdm/host.rb', line 193

has_many :sessions,
-> { order('sessions.opened_at') },
class_name: 'Mdm::Session',
dependent: :destroy,
inverse_of: :host

#stateString

Whether the host is alive, down, or in an unknown state.

Returns:

  • (String)

    element of STATES.


# File 'app/models/mdm/host.rb', line 443

#tagsActiveRecord::Relation<Mdm::Tag> (readonly)

The tags on this host. Tags are used to filter hosts.

Returns:

See Also:


225
# File 'app/models/mdm/host.rb', line 225

has_many :tags, :class_name => 'Mdm::Tag', :through => :hosts_tags

#task_hostsActiveRecord::Relation<Mdm::TaskHost>

Details about what Tasks touched this host

Returns:


117
118
119
120
# File 'app/models/mdm/host.rb', line 117

has_many :task_hosts,
class_name: 'Mdm::TaskHost',
dependent: :destroy,
inverse_of: :host

#tasksActiveRecord::Relation<Mdm::Task>

Tasks that touched this service

Returns:


273
274
275
# File 'app/models/mdm/host.rb', line 273

has_many :tasks,
class_name: 'Mdm::Task',
through: :task_hosts

#updated_atDateTime

The last time this host was updated in the database.

Returns:

  • (DateTime)

# File 'app/models/mdm/host.rb', line 448

#virtual_hostString

The name of the virtual machine host software, such as 'VMWare', 'QEMU', 'XEN', etc.

Returns:

  • (String)

# File 'app/models/mdm/host.rb', line 453

#vuln_countInteger

Counter cache for #vulns.

Returns:

  • (Integer)

# File 'app/models/mdm/host.rb', line 458

#vuln_refsActiveRecord::Relation<Mdm::VulnRef> (readonly)

Join model between #vulns and #refs. Use either of those asssociations instead of this join model.

Returns:

See Also:


288
# File 'app/models/mdm/host.rb', line 288

has_many :vuln_refs, :class_name => 'Mdm::VulnRef', :source => :vulns_refs, :through => :vulns

#vulnsActiveRecord::Relation<Mdm::Vuln>

Vulnerabilities found on the host.

Returns:


203
204
205
206
# File 'app/models/mdm/host.rb', line 203

has_many :vulns,
class_name: 'Mdm::Vuln',
dependent: :delete_all,
inverse_of: :host

#web_sitesActiveRecord::Relation<Mdm::WebSite> (readonly)

Web sites running on top of #services on this host.

Returns:

See Also:


253
# File 'app/models/mdm/host.rb', line 253

has_many :web_sites, :class_name => 'Mdm::WebSite', :through => :services

#workspaceMdm::Workspace

The workspace in which this host was found.

Returns:


212
213
214
# File 'app/models/mdm/host.rb', line 212

belongs_to :workspace,
class_name: 'Mdm::Workspace',
inverse_of: :hosts

Instance Method Details

#attribute_locked?(attr) ⇒ true, false

Returns whether 'host.updated.' note is locked.

Returns:

  • (true)

    if Mdm::Note with 'host.updated.' as Note#name exists and data[:locked] is true.

  • (false)

    otherwise.


576
577
578
579
# File 'app/models/mdm/host.rb', line 576

def attribute_locked?(attr)
  n = notes.find_by_ntype("host.updated.#{attr}")
  n && n.data[:locked]
end

#ip_address_invalid?void

This method returns an undefined value.

This is replicated by the IpAddressValidator class. Had to put it here as well to avoid SQL errors when checking address uniqueness.


585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'app/models/mdm/host.rb', line 585

def ip_address_invalid?
  begin
    if address.is_a? IPAddr
      potential_ip = address.dup
    else
      potential_ip = IPAddr.new(address)
    end

    return true unless potential_ip.ipv4? || potential_ip.ipv6?
  rescue ArgumentError
    return true
  end
end

#is_vm?true, false

Returns whether this host is a virtual machine.

Returns:


603
604
605
# File 'app/models/mdm/host.rb', line 603

def is_vm?
  !!self.virtual_host
end