Class: Mihari::Analyzers::Base

Inherits:
Object
  • Object
show all
Extended by:
Dry::Initializer
Includes:
Mixins::AutonomousSystem, Mixins::Configurable, Mixins::Retriable
Defined in:
lib/mihari/analyzers/base.rb

Constant Summary

Constants included from Mixins::Retriable

Mixins::Retriable::DEFAULT_ON

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixins::Retriable

#retry_on_error

Methods included from Mixins::Configurable

#configuration_keys, #configuration_values, #configured?

Methods included from Mixins::AutonomousSystem

#normalize_asn

Constructor Details

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

Returns a new instance of Base.



17
18
19
20
21
# File 'lib/mihari/analyzers/base.rb', line 17

def initialize(*args, **kwargs)
  super(*args, **kwargs)

  @base_time = Time.now.utc
end

Instance Attribute Details

#ruleMihari::Structs::Rule? (readonly)

Returns:



15
16
17
# File 'lib/mihari/analyzers/base.rb', line 15

def rule
  @rule
end

Class Method Details

.inherited(child) ⇒ Object



74
75
76
77
# File 'lib/mihari/analyzers/base.rb', line 74

def inherited(child)
  super
  Mihari.analyzers << child
end

Instance Method Details

#artifactsArray<String>, Array<Mihari::Artifact>

Returns:

Raises:

  • (NotImplementedError)


24
25
26
# File 'lib/mihari/analyzers/base.rb', line 24

def artifacts
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end

#normalized_artifactsArray<Mihari::Artifact>

Normalize artifacts

  • Convert data (string) into an artifact

  • Reject an invalid artifact

  • Uniquefy artifacts by data

Returns:



88
89
90
91
92
93
94
95
96
97
# File 'lib/mihari/analyzers/base.rb', line 88

def normalized_artifacts
  @normalized_artifacts ||= artifacts.compact.sort.map do |artifact|
    # No need to set data_type manually
    # It is set automatically in #initialize
    artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact, source: source)
  end.select(&:valid?).uniq(&:data).map do |artifact|
    artifact.rule_id = rule&.id
    artifact
  end
end

#runMihari::Alert?

Set artifacts & run emitters in parallel

Returns:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/mihari/analyzers/base.rb', line 38

def run
  unless configured?
    class_name = self.class.to_s.split("::").last
    raise ConfigurationError, "#{class_name} is not configured correctly"
  end

  set_enriched_artifacts

  responses = Parallel.map(valid_emitters) do |emitter|
    run_emitter emitter
  end

  # returns Mihari::Alert created by the database emitter
  responses.find { |res| res.is_a?(Mihari::Alert) }
end

#run_emitter(emitter) ⇒ Mihari::Alert?

Run emitter

Parameters:

Returns:



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/mihari/analyzers/base.rb', line 61

def run_emitter(emitter)
  return if enriched_artifacts.empty?

  alert_or_something = emitter.run(artifacts: enriched_artifacts, rule: rule)

  Mihari.logger.info "Emission by #{emitter.class} is succedded"

  alert_or_something
rescue StandardError => e
  Mihari.logger.info "Emission by #{emitter.class} is failed: #{e}"
end

#sourceString

Returns:

  • (String)


29
30
31
# File 'lib/mihari/analyzers/base.rb', line 29

def source
  self.class.to_s.split("::").last.to_s
end