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?