Class: Mihari::Artifact

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

Constant Summary collapse

ENRICH_METHODS_BY_ENRICHER =
{
  whois: [
    :enrich_whois
  ],
  ipinfo: i[
    enrich_autonomous_system
    enrich_geolocation
  ],
  shodan: i[
    enrich_ports
    enrich_cpes
    enrich_reverse_dns
  ],
  google_public_dns: [
    :enrich_dns
  ]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, **kwargs) ⇒ Artifact

Returns a new instance of Artifact.



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/mihari/models/artifact.rb', line 34

def initialize(*args, **kwargs)
  attrs = args.first || kwargs
  data_ = attrs[:data]

  raise InvalidArtifactFormatError if data_.is_a?(Array) || data_.is_a?(Hash)

  super(*args, **kwargs)

  self.data_type = TypeChecker.type(data)

  @tags = []
  @rule_id = ""
end

Instance Attribute Details

#rule_idString?

Returns Rule ID.

Returns:

  • (String, nil)

    Rule ID



32
33
34
# File 'lib/mihari/models/artifact.rb', line 32

def rule_id
  @rule_id
end

#tagsArray<Mihari::Tag>

Returns Tags.

Returns:



29
30
31
# File 'lib/mihari/models/artifact.rb', line 29

def tags
  @tags
end

Instance Method Details

#enrich_allObject

Enrich all the enrichable relationships of the artifact



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

def enrich_all
  enrich_autonomous_system
  enrich_dns
  enrich_geolocation
  enrich_reverse_dns
  enrich_whois
  enrich_ports
  enrich_cpes
end

#enrich_autonomous_systemObject

Enrich AS



112
113
114
115
116
# File 'lib/mihari/models/artifact.rb', line 112

def enrich_autonomous_system
  return unless can_enrich_autonomous_system?

  self.autonomous_system = AutonomousSystem.build_by_ip(data)
end

#enrich_by_enricher(enricher) ⇒ Object

Enrich by name of enricher

Parameters:

  • enricher (String)


172
173
174
175
176
177
# File 'lib/mihari/models/artifact.rb', line 172

def enrich_by_enricher(enricher)
  methods = ENRICH_METHODS_BY_ENRICHER[enricher.downcase.to_sym] || []
  methods.each do |method|
    send(method) if respond_to?(method)
  end
end

#enrich_cpesObject

Enrich CPEs



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

def enrich_cpes
  return unless can_enrich_cpes?

  self.cpes = CPE.build_by_ip(data)
end

#enrich_dnsObject

Enrich(add) DNS records



85
86
87
88
89
# File 'lib/mihari/models/artifact.rb', line 85

def enrich_dns
  return unless can_enrich_dns?

  self.dns_records = DnsRecord.build_by_domain(normalize_as_domain(data))
end

#enrich_geolocationObject

Enrich(add) geolocation



103
104
105
106
107
# File 'lib/mihari/models/artifact.rb', line 103

def enrich_geolocation
  return unless can_enrich_geolocation?

  self.geolocation = Geolocation.build_by_ip(data)
end

#enrich_portsObject

Enrich ports



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

def enrich_ports
  return unless can_enrich_ports?

  self.ports = Port.build_by_ip(data)
end

#enrich_reverse_dnsObject

Enrich(add) reverse DNS names



94
95
96
97
98
# File 'lib/mihari/models/artifact.rb', line 94

def enrich_reverse_dns
  return unless can_enrich_revese_dns?

  self.reverse_dns_names = ReverseDnsName.build_by_ip(data)
end

#enrich_whoisObject

Enrich(add) whois record



76
77
78
79
80
# File 'lib/mihari/models/artifact.rb', line 76

def enrich_whois
  return unless can_enrich_whois?

  self.whois_record = WhoisRecord.build_by_domain(normalize_as_domain(data))
end

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

Check uniqueness of artifact

Parameters:

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

    Base time to check decaying

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

    Artifact lifetime (TTL) in seconds

Returns:

  • (Boolean)

    true if it is unique. Otherwise false.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/mihari/models/artifact.rb', line 56

def unique?(base_time: nil, artifact_lifetime: 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 whetehr the artifact is decayed or not
  return false if artifact_lifetime.nil?

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

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