lib/mihari/analyzers/rule.rb in mihari-4.12.0 vs lib/mihari/analyzers/rule.rb in mihari-5.0.0
- old
+ new
@@ -27,42 +27,25 @@
"zoomeye" => ZoomEye
}.freeze
EMITTER_TO_CLASS = {
"database" => Emitters::Database,
- "http" => Emitters::HTTP,
"misp" => Emitters::MISP,
"slack" => Emitters::Slack,
"the_hive" => Emitters::TheHive,
"webhook" => Emitters::Webhook
}.freeze
+ # @return [Mihari::Structs::Rule]
+ attr_reader :rule
+
class Rule < Base
- include Mixins::DisallowedDataValue
+ include Mixins::FalsePositive
- option :title
- option :description
- option :queries
-
- option :id, default: proc { "" }
- option :tags, default: proc { [] }
- option :allowed_data_types, default: proc { ALLOWED_DATA_TYPES }
- option :disallowed_data_values, default: proc { [] }
-
- option :emitters, optional: true
- option :enrichers, optional: true
-
- attr_reader :source
-
def initialize(**kwargs)
super(**kwargs)
- @source = id
-
- @emitters = emitters || DEFAULT_EMITTERS
- @enrichers = enrichers || DEFAULT_ENRICHERS
-
validate_analyzer_configurations
end
#
# Returns a list of artifacts matched with queries
@@ -70,23 +53,27 @@
# @return [Array<Mihari::Artifact>]
#
def artifacts
artifacts = []
- queries.each do |original_params|
+ 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
@@ -104,24 +91,24 @@
#
# @return [Array<Mihari::Artifact>]
#
def normalized_artifacts
@normalized_artifacts ||= artifacts.uniq(&:data).select(&:valid?).select do |artifact|
- allowed_data_types.include? artifact.data_type
+ rule.data_types.include? artifact.data_type
end.reject do |artifact|
- disallowed_data_value? artifact.data
+ falsepositive? artifact.data
end
end
#
# Enriched artifacts
#
# @return [Array<Mihari::Artifact>]
#
def enriched_artifacts
@enriched_artifacts ||= Parallel.map(unique_artifacts) do |artifact|
- enrichers.each do |enricher|
+ rule.enrichers.each do |enricher|
artifact.enrich_by_enricher(enricher[:enricher])
end
artifact
end
@@ -130,26 +117,26 @@
#
# Normalized disallowed data values
#
# @return [Array<Regexp, String>]
#
- def normalized_disallowed_data_values
- @normalized_disallowed_data_values ||= disallowed_data_values.map { |v| normalize_disallowed_data_value v }
+ def normalized_falsepositives
+ @normalized_falsepositives ||= rule.falsepositives.map { |v| normalize_falsepositive v }
end
#
- # Check whether a value is a disallowed data value or not
+ # Check whether a value is a falsepositive value or not
#
# @return [Boolean]
#
- def disallowed_data_value?(value)
- return true if normalized_disallowed_data_values.include?(value)
+ def falsepositive?(value)
+ return true if normalized_falsepositives.include?(value)
- normalized_disallowed_data_values.select do |disallowed_data_value|
- disallowed_data_value.is_a?(Regexp)
- end.any? do |disallowed_data_value|
- disallowed_data_value.match?(value)
+ normalized_falsepositives.select do |falsepositive|
+ falsepositive.is_a?(Regexp)
+ end.any? do |falseposistive|
+ falseposistive.match?(value)
end
end
private
@@ -166,11 +153,11 @@
raise ArgumentError, "#{emitter_name} is not supported"
end
def valid_emitters
- @valid_emitters ||= emitters.filter_map do |original_params|
+ @valid_emitters ||= rule.emitters.filter_map do |original_params|
params = original_params.deep_dup
name = params[:emitter]
params.delete(:emitter)
@@ -197,10 +184,10 @@
#
# Validate configuration of analyzers
#
def validate_analyzer_configurations
- queries.each do |params|
+ rule.queries.each do |params|
analyzer_name = params[:analyzer]
klass = get_analyzer_class(analyzer_name)
instance = klass.new("dummy")
unless instance.configured?