From 7a4521f276d67a913338bfba0e238e37b6e64121 Mon Sep 17 00:00:00 2001 From: Manabu Niseki Date: Sat, 2 Mar 2024 12:35:55 +0900 Subject: [PATCH] feat: attribute/observable level tagging --- docs/emitters/hive.md | 8 ++++++++ docs/emitters/misp.md | 8 ++++++++ lib/mihari/emitters/misp.rb | 12 ++++++++++-- lib/mihari/emitters/the_hive.rb | 9 +++++++-- lib/mihari/models/tag.rb | 3 +++ lib/mihari/schemas/emitter.rb | 2 ++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/emitters/hive.md b/docs/emitters/hive.md index fef045e74..ad4d4e433 100644 --- a/docs/emitters/hive.md +++ b/docs/emitters/hive.md @@ -19,3 +19,11 @@ api_key: ... ### API Key `api_key` (`string`) is an API key. Optional. Configurable via `THEHIVE_API_KEY` environment variable. + +### Observable Tags + +`observable_tags` (`array[:string]`) is a list of observable tags. Optional. Defaults to `[]`. + +!!! note + + `tags` of a rule are set as tags of an alert. diff --git a/docs/emitters/misp.md b/docs/emitters/misp.md index b7a1bd3c0..381bfc152 100644 --- a/docs/emitters/misp.md +++ b/docs/emitters/misp.md @@ -19,3 +19,11 @@ api_key: ... ### API Key `api_key` (`string`) is an API key. Optional. Configurable via `MISP_API_KEY` environment variable. + +### Attribute Tags + +`attribute_tags` (`array[:string]`) is a list of attribute tags. Optional. Defaults to `[]`. + +!!! note + + `tags` of a rule are set as tags of an event. diff --git a/lib/mihari/emitters/misp.rb b/lib/mihari/emitters/misp.rb index 48301cbbe..6ee8e7516 100644 --- a/lib/mihari/emitters/misp.rb +++ b/lib/mihari/emitters/misp.rb @@ -12,6 +12,9 @@ class MISP < Base # @return [String, nil] attr_reader :api_key + # @return [Array] + attr_reader :attribute_tags + # @return [Mihari::Rule] attr_reader :rule @@ -28,6 +31,7 @@ def initialize(rule:, options: nil, **params) @url = params[:url] || Mihari.config.misp_url @api_key = params[:api_key] || Mihari.config.misp_api_key + @attribute_tags = params[:attribute_tags] || [] @artifacts = [] end @@ -51,7 +55,7 @@ def call(artifacts) Event: { info: rule.title, Attribute: artifacts.map { |artifact| build_attribute(artifact) }, - Tag: rule.tags.map { |tag| {name: tag} } + Tag: rule.tags.map { |tag| {name: tag.name} } } }) end @@ -77,7 +81,11 @@ def client # @return [Hash] # def build_attribute(artifact) - {value: artifact.data, type: to_misp_type(type: artifact.data_type, value: artifact.data)} + { + value: artifact.data, + type: to_misp_type(type: artifact.data_type, value: artifact.data), + Tag: attribute_tags.map { |tag| {name: tag} } + } end # diff --git a/lib/mihari/emitters/the_hive.rb b/lib/mihari/emitters/the_hive.rb index 29fb798ca..966113efa 100644 --- a/lib/mihari/emitters/the_hive.rb +++ b/lib/mihari/emitters/the_hive.rb @@ -9,6 +9,9 @@ class TheHive < Base # @return [String, nil] attr_reader :api_key + # @return [Array] + attr_reader :observable_tags + # @return [Array] attr_accessor :artifacts @@ -22,6 +25,7 @@ def initialize(rule:, options: nil, **params) @url = params[:url] || Mihari.config.thehive_url @api_key = params[:api_key] || Mihari.config.thehive_api_key + @observable_tags = params[:observable_tags] || [] @artifacts = [] end @@ -81,10 +85,11 @@ def payload { data: artifact.data, data_type: artifact.data_type, - message: rule.description + message: rule.description, + tags: observable_tags } end, - tags: rule.tags, + tags: rule.tags.map(&:name), type: "external", source: "mihari", source_ref: SecureRandom.uuid diff --git a/lib/mihari/models/tag.rb b/lib/mihari/models/tag.rb index 40e592e41..c9e2b9235 100644 --- a/lib/mihari/models/tag.rb +++ b/lib/mihari/models/tag.rb @@ -6,6 +6,9 @@ module Models # Tag model # class Tag < ActiveRecord::Base + # @!attribute [rw] name + # @return [String] + has_many :taggings, dependent: :destroy include SearchCop diff --git a/lib/mihari/schemas/emitter.rb b/lib/mihari/schemas/emitter.rb index 6248fcbb9..5fc467ba6 100644 --- a/lib/mihari/schemas/emitter.rb +++ b/lib/mihari/schemas/emitter.rb @@ -17,6 +17,7 @@ module Emitters required(:emitter).value(Types::String.enum(*Mihari::Emitters::MISP.keys)) optional(:url).filled(:string) optional(:api_key).filled(:string) + optional(:attribute_tags).array { filled(:string) }.default([]) optional(:options).hash(EmitterOptions) end @@ -24,6 +25,7 @@ module Emitters required(:emitter).value(Types::String.enum(*Mihari::Emitters::TheHive.keys)) optional(:url).filled(:string) optional(:api_key).filled(:string) + optional(:observable_tags).array { filled(:string) }.default([]) optional(:options).hash(EmitterOptions) end