Class: Mihari::Models::Artifact

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
ActiveModel::Validations, Concerns::Searchable, SearchCop
Defined in:
lib/mihari/models/artifact.rb

Overview

Artifact model

Constant Summary collapse

ENRICH_METHODS_BY_ENRICHER =
{
  Enrichers::Whois => %i[
    enrich_whois
  ],
  Enrichers::MMDB => %i[
    enrich_autonomous_system
    enrich_geolocation
  ],
  Enrichers::Shodan => %i[
    enrich_ports
    enrich_cpes
    enrich_reverse_dns
  ],
  Enrichers::GooglePublicDNS => %i[
    enrich_dns
  ]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#rule_idString?

Returns:

  • (String, nil)


55
56
57
# File 'lib/mihari/models/artifact.rb', line 55

def rule_id
  @rule_id
end

Instance Method Details

#count_by_filter(filter) ⇒ Integer

Parameters:

Returns:

  • (Integer)


# File 'lib/mihari/models/artifact.rb', line 205

#enrich_allObject

Enrich all the enrichable relationships of the artifact



162
163
164
165
166
167
168
169
170
# File 'lib/mihari/models/artifact.rb', line 162

def enrich_all
  enrich_autonomous_system mmdb
  enrich_dns
  enrich_geolocation mmdb
  enrich_reverse_dns shodan
  enrich_whois
  enrich_ports shodan
  enrich_cpes shodan
end

#enrich_autonomous_system(enricher = Enrichers::MMDB.new) ⇒ Object

Enrich AS

Parameters:

  • enricher (Mihari::Enrichers::IPInfo) (defaults to: Enrichers::MMDB.new)


131
132
133
134
135
# File 'lib/mihari/models/artifact.rb', line 131

def enrich_autonomous_system(enricher = Enrichers::MMDB.new)
  return unless can_enrich_autonomous_system?

  self.autonomous_system = Services::AutonomousSystemBuilder.call(data, enricher: enricher)
end

#enrich_by_enricher(enricher) ⇒ Object

Enrich by name of enricher

Parameters:



195
196
197
198
# File 'lib/mihari/models/artifact.rb', line 195

def enrich_by_enricher(enricher)
  methods = ENRICH_METHODS_BY_ENRICHER[enricher.class] || []
  methods.each { |method| send(method, enricher) if respond_to?(method) }
end

#enrich_cpes(enricher = Enrichers::Shodan.new) ⇒ Object

Enrich CPEs

Parameters:



153
154
155
156
157
# File 'lib/mihari/models/artifact.rb', line 153

def enrich_cpes(enricher = Enrichers::Shodan.new)
  return unless can_enrich_cpes?

  self.cpes = Services::CPEBuilder.call(data, enricher: enricher)
end

#enrich_dns(enricher = Enrichers::GooglePublicDNS.new) ⇒ Object

Enrich DNS records

Parameters:



98
99
100
101
102
# File 'lib/mihari/models/artifact.rb', line 98

def enrich_dns(enricher = Enrichers::GooglePublicDNS.new)
  return unless can_enrich_dns?

  self.dns_records = Services::DnsRecordBuilder.call(domain, enricher: enricher)
end

#enrich_geolocation(enricher = Enrichers::MMDB.new) ⇒ Object

Enrich geolocation

Parameters:

  • enricher (Mihari::Enrichers::IPInfo) (defaults to: Enrichers::MMDB.new)


120
121
122
123
124
# File 'lib/mihari/models/artifact.rb', line 120

def enrich_geolocation(enricher = Enrichers::MMDB.new)
  return unless can_enrich_geolocation?

  self.geolocation = Services::GeolocationBuilder.call(data, enricher: enricher)
end

#enrich_ports(enricher = Enrichers::Shodan.new) ⇒ Object

Enrich ports

Parameters:



142
143
144
145
146
# File 'lib/mihari/models/artifact.rb', line 142

def enrich_ports(enricher = Enrichers::Shodan.new)
  return unless can_enrich_ports?

  self.ports = Services::PortBuilder.call(data, enricher: enricher)
end

#enrich_reverse_dns(enricher = Enrichers::Shodan.new) ⇒ Object

Enrich reverse DNS names

Parameters:



109
110
111
112
113
# File 'lib/mihari/models/artifact.rb', line 109

def enrich_reverse_dns(enricher = Enrichers::Shodan.new)
  return unless can_enrich_reverse_dns?

  self.reverse_dns_names = Services::ReverseDnsNameBuilder.call(data, enricher: enricher)
end

#enrich_whois(enricher = Enrichers::Whois.new) ⇒ Object

Enrich whois record

Parameters:



87
88
89
90
91
# File 'lib/mihari/models/artifact.rb', line 87

def enrich_whois(enricher = Enrichers::Whois.new)
  return unless can_enrich_whois?

  self.whois_record = Services::WhoisRecordBuilder.call(domain, enricher: enricher)
end

#search_by_filter(filter) ⇒ Array<Mihari::Models::Alert>

Parameters:

Returns:



# File 'lib/mihari/models/artifact.rb', line 201

#unique?(base_time: nil, artifact_ttl: nil) ⇒ Boolean

Check uniqueness

Parameters:

  • base_time (Time, nil) (defaults to: nil)

    Base time to check decaying

  • artifact_ttl (Integer, nil) (defaults to: nil)

    Artifact TTL in seconds

Returns:

  • (Boolean)

    true if it is unique. Otherwise false.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/mihari/models/artifact.rb', line 65

def unique?(base_time: nil, artifact_ttl: nil)
  artifact = self.class.joins(:alert).where(
    data: data,
    alert: { rule_id: rule_id }
  ).order(created_at: :desc).first
  return true if artifact.nil?

  # check whether the artifact is decayed or not
  return false if artifact_ttl.nil?

  # use the current UTC time if base_time is not given (for testing)
  base_time ||= Time.now.utc

  decayed_at = base_time - (artifact_ttl || -1).seconds
  artifact.created_at < decayed_at
end