Class: Mihari::Analyzers::Rule

Inherits:
Base
  • Object
show all
Includes:
Mixins::FalsePositive
Defined in:
lib/mihari/analyzers/rule.rb

Constant Summary

Constants included from Mixins::Retriable

Mixins::Retriable::DEFAULT_ON

Instance Attribute Summary

Attributes inherited from Base

#rule

Instance Method Summary collapse

Methods included from Mixins::FalsePositive

#normalize_falsepositive, #valid_falsepositive?

Methods inherited from Base

inherited, #run, #run_emitter, #source

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(**kwargs) ⇒ Rule

Returns a new instance of Rule.



44
45
46
47
48
# File 'lib/mihari/analyzers/rule.rb', line 44

def initialize(**kwargs)
  super(**kwargs)

  validate_analyzer_configurations
end

Instance Method Details

#artifactsArray<Mihari::Artifact>

Returns a list of artifacts matched with queries

Returns:



55
56
57
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
# File 'lib/mihari/analyzers/rule.rb', line 55

def artifacts
  artifacts = []

  rule.queries.each do |original_params|
    parmas = original_params.deep_dup

    analyzer_name = parmas[:analyzer]
    klass = get_analyzer_class(analyzer_name)

    query = parmas[:query]

    # set interval in the top level
    options = parmas[:options] || {}
    interval = options[:interval]

    parmas[:interval] = interval if interval

    # set rule
    parmas[:rule] = rule

    analyzer = klass.new(query, **parmas)

    # Use #normalized_artifacts method to get atrifacts as Array<Mihari::Artifact>
    # So Mihari::Artifact object has "source" attribute (e.g. "Shodan")
    artifacts << analyzer.normalized_artifacts
  end

  artifacts.flatten
end

#enriched_artifactsArray<Mihari::Artifact>

Enriched artifacts

Returns:



107
108
109
110
111
112
113
114
115
# File 'lib/mihari/analyzers/rule.rb', line 107

def enriched_artifacts
  @enriched_artifacts ||= Parallel.map(unique_artifacts) do |artifact|
    rule.enrichers.each do |enricher|
      artifact.enrich_by_enricher(enricher[:enricher])
    end

    artifact
  end
end

#falsepositive?(value) ⇒ Boolean

Check whether a value is a falsepositive value or not

Returns:

  • (Boolean)


131
132
133
134
135
136
137
138
139
# File 'lib/mihari/analyzers/rule.rb', line 131

def falsepositive?(value)
  return true if normalized_falsepositives.include?(value)

  normalized_falsepositives.select do |falsepositive|
    falsepositive.is_a?(Regexp)
  end.any? do |falseposistive|
    falseposistive.match?(value)
  end
end

#normalized_artifactsArray<Mihari::Artifact>

Normalize artifacts

  • Uniquefy artifacts by #uniq(&:data)

  • Reject an invalid artifact (for just in case)

  • Select artifacts with allowed data types

  • Reject artifacts with disallowed data values

Returns:



94
95
96
97
98
99
100
# File 'lib/mihari/analyzers/rule.rb', line 94

def normalized_artifacts
  @normalized_artifacts ||= artifacts.uniq(&:data).select(&:valid?).select do |artifact|
    rule.data_types.include? artifact.data_type
  end.reject do |artifact|
    falsepositive? artifact.data
  end
end

#normalized_falsepositivesArray<Regexp, String>

Normalized disallowed data values

Returns:

  • (Array<Regexp, String>)


122
123
124
# File 'lib/mihari/analyzers/rule.rb', line 122

def normalized_falsepositives
  @normalized_falsepositives ||= rule.falsepositives.map { |v| normalize_falsepositive v }
end