mihari 5.5.0 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/passivetotal.md +4 -0
  3. data/docs/analyzers/securitytrails.md +4 -0
  4. data/docs/analyzers/virustotal.md +4 -0
  5. data/docs/analyzers/virustotal_intelligence.md +4 -0
  6. data/docs/emitters/hive.md +1 -1
  7. data/docs/emitters/slack.md +0 -5
  8. data/docs/rule.md +1 -4
  9. data/docs/usage.md +5 -2
  10. data/frontend/src/components/ErrorMessage.vue +0 -1
  11. data/frontend/src/components/alert/Alerts.vue +0 -1
  12. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
  13. data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
  14. data/frontend/src/components/alert/Form.vue +1 -3
  15. data/frontend/src/components/artifact/Artifact.vue +0 -17
  16. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
  17. data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
  18. data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
  19. data/frontend/src/components/rule/EditRule.vue +0 -3
  20. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
  21. data/frontend/src/components/rule/Form.vue +1 -3
  22. data/frontend/src/components/rule/NewRule.vue +0 -3
  23. data/frontend/src/components/rule/Rule.vue +1 -7
  24. data/frontend/src/components/rule/RuleWrapper.vue +0 -2
  25. data/frontend/src/components/rule/RulesWrapper.vue +0 -6
  26. data/frontend/src/swagger.yaml +254 -254
  27. data/lib/mihari/analyzers/base.rb +4 -41
  28. data/lib/mihari/analyzers/passivetotal.rb +9 -0
  29. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  30. data/lib/mihari/analyzers/rule.rb +24 -59
  31. data/lib/mihari/analyzers/securitytrails.rb +9 -0
  32. data/lib/mihari/analyzers/virustotal.rb +11 -2
  33. data/lib/mihari/analyzers/virustotal_intelligence.rb +16 -0
  34. data/lib/mihari/analyzers/zoomeye.rb +2 -2
  35. data/lib/mihari/base.rb +69 -0
  36. data/lib/mihari/cli/main.rb +36 -0
  37. data/lib/mihari/commands/alert.rb +6 -33
  38. data/lib/mihari/commands/rule.rb +7 -12
  39. data/lib/mihari/commands/search.rb +10 -38
  40. data/lib/mihari/constants.rb +3 -3
  41. data/lib/mihari/emitters/base.rb +3 -33
  42. data/lib/mihari/emitters/database.rb +1 -1
  43. data/lib/mihari/enrichers/base.rb +2 -33
  44. data/lib/mihari/enrichers/google_public_dns.rb +9 -0
  45. data/lib/mihari/schemas/analyzer.rb +24 -24
  46. data/lib/mihari/schemas/emitter.rb +6 -13
  47. data/lib/mihari/schemas/enricher.rb +4 -11
  48. data/lib/mihari/schemas/options.rb +27 -0
  49. data/lib/mihari/schemas/rule.rb +2 -2
  50. data/lib/mihari/services/alert_runner.rb +1 -1
  51. data/lib/mihari/services/rule_runner.rb +1 -11
  52. data/lib/mihari/types.rb +1 -14
  53. data/lib/mihari/version.rb +1 -1
  54. data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
  55. data/lib/mihari/web/public/assets/{index-b5d817a3.js → index-9cc489e6.js} +2 -2
  56. data/lib/mihari/web/public/index.html +2 -2
  57. data/lib/mihari.rb +67 -37
  58. data/mihari.gemspec +1 -0
  59. metadata +20 -4
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mihari
4
4
  module Analyzers
5
- class Base
5
+ class Base < Mihari::Base
6
6
  include Dry::Monads[:result, :try]
7
7
 
8
8
  include Mixins::Configurable
@@ -11,37 +11,14 @@ module Mihari
11
11
  # @return [String]
12
12
  attr_reader :query
13
13
 
14
- # @return [Hash]
15
- attr_reader :options
16
-
17
14
  #
18
15
  # @param [String] query
19
16
  # @param [Hash, nil] options
20
17
  #
21
18
  def initialize(query, options: nil)
22
- @query = query
23
- @options = options || {}
24
- end
25
-
26
- #
27
- # @return [Integer]
28
- #
29
- def retry_interval
30
- options[:retry_interval] || Mihari.config.retry_interval
31
- end
32
-
33
- #
34
- # @return [Boolean]
35
- #
36
- def retry_exponential_backoff
37
- options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
38
- end
19
+ super(options: options)
39
20
 
40
- #
41
- # @return [Integer]
42
- #
43
- def retry_times
44
- options[:retry_times] || Mihari.config.retry_times
21
+ @query = query
45
22
  end
46
23
 
47
24
  #
@@ -68,13 +45,6 @@ module Mihari
68
45
  Mihari.config.ignore_error
69
46
  end
70
47
 
71
- #
72
- # @return [Integer, nil]
73
- #
74
- def timeout
75
- options[:timeout]
76
- end
77
-
78
48
  # @return [Array<String>, Array<Mihari::Artifact>]
79
49
  def artifacts
80
50
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
@@ -93,7 +63,7 @@ module Mihari
93
63
  # No need to set data_type manually
94
64
  # It is set automatically in #initialize
95
65
  artifact = artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact)
96
- artifact.source = source
66
+ artifact.source = self.class.class_key
97
67
  artifact
98
68
  end.select(&:valid?).uniq(&:data)
99
69
  end
@@ -106,13 +76,6 @@ module Mihari
106
76
  Try[StandardError] { normalized_artifacts }.to_result
107
77
  end
108
78
 
109
- # @return [String]
110
- def class_name
111
- self.class.to_s.split("::").last
112
- end
113
-
114
- alias_method :source, :class_name
115
-
116
79
  class << self
117
80
  #
118
81
  # Initialize an analyzer by query params
@@ -50,6 +50,15 @@ module Mihari
50
50
  %w[passivetotal_username passivetotal_api_key]
51
51
  end
52
52
 
53
+ class << self
54
+ #
55
+ # @return [Array<String>, nil]
56
+ #
57
+ def key_aliases
58
+ ["pt"]
59
+ end
60
+ end
61
+
53
62
  private
54
63
 
55
64
  def client
@@ -35,7 +35,7 @@ module Mihari
35
35
  nil
36
36
  else
37
37
  data = property["value"]
38
- Artifact.new(data: data, source: source, metadata: property)
38
+ Artifact.new(data: data, metadata: property)
39
39
  end
40
40
  end
41
41
  end
@@ -2,46 +2,6 @@
2
2
 
3
3
  module Mihari
4
4
  module Analyzers
5
- ANALYZER_TO_CLASS = {
6
- "binaryedge" => BinaryEdge,
7
- "censys" => Censys,
8
- "circl" => CIRCL,
9
- "crtsh" => Crtsh,
10
- "dnstwister" => DNSTwister,
11
- "feed" => Feed,
12
- "greynoise" => GreyNoise,
13
- "hunterhow" => HunterHow,
14
- "onyphe" => Onyphe,
15
- "otx" => OTX,
16
- "passivetotal" => PassiveTotal,
17
- "pt" => PassiveTotal,
18
- "pulsedive" => Pulsedive,
19
- "securitytrails" => SecurityTrails,
20
- "shodan" => Shodan,
21
- "st" => SecurityTrails,
22
- "urlscan" => Urlscan,
23
- "virustotal_intelligence" => VirusTotalIntelligence,
24
- "virustotal" => VirusTotal,
25
- "vt_intel" => VirusTotalIntelligence,
26
- "vt" => VirusTotal,
27
- "zoomeye" => ZoomEye
28
- }.freeze
29
-
30
- EMITTER_TO_CLASS = {
31
- "database" => Emitters::Database,
32
- "misp" => Emitters::MISP,
33
- "slack" => Emitters::Slack,
34
- "the_hive" => Emitters::TheHive,
35
- "webhook" => Emitters::Webhook
36
- }.freeze
37
-
38
- ENRICHER_TO_CLASS = {
39
- "whois" => Enrichers::Whois,
40
- "ipinfo" => Enrichers::IPInfo,
41
- "shodan" => Enrichers::Shodan,
42
- "google_public_dns" => Enrichers::GooglePublicDNS
43
- }.freeze
44
-
45
5
  class Rule
46
6
  include Mixins::FalsePositive
47
7
 
@@ -126,8 +86,14 @@ module Mihari
126
86
  def bulk_emit
127
87
  return [] if enriched_artifacts.empty?
128
88
 
129
- Parallel.map(valid_emitters) do |emitter|
130
- result = emitter.result
89
+ # NOTE: separate parallel execution and logging
90
+ # because the logger does not work along with Parallel
91
+ results = Parallel.map(valid_emitters) do |emitter|
92
+ emitter.result
93
+ end
94
+
95
+ results.zip(valid_emitters).map do |result_and_emitter|
96
+ result, emitter = result_and_emitter
131
97
 
132
98
  Mihari.logger.info "Emission by #{emitter.class} is failed: #{result.failure}" if result.failure?
133
99
  Mihari.logger.info "Emission by #{emitter.class} is succeeded" if result.success?
@@ -164,15 +130,14 @@ module Mihari
164
130
  #
165
131
  # Get analyzer class
166
132
  #
167
- # @param [String] analyzer_name
133
+ # @param [String] key
168
134
  #
169
135
  # @return [Class<Mihari::Analyzers::Base>] analyzer class
170
136
  #
171
- def get_analyzer_class(analyzer_name)
172
- analyzer = ANALYZER_TO_CLASS[analyzer_name]
173
- return analyzer if analyzer
137
+ def get_analyzer_class(key)
138
+ raise ArgumentError, "#{key} is not supported" unless Mihari.analyzer_to_class.key?(key)
174
139
 
175
- raise ArgumentError, "#{analyzer_name} is not supported"
140
+ Mihari.analyzer_to_class[key]
176
141
  end
177
142
 
178
143
  #
@@ -189,15 +154,14 @@ module Mihari
189
154
  #
190
155
  # Get emitter class
191
156
  #
192
- # @param [String] emitter_name
157
+ # @param [String] key
193
158
  #
194
159
  # @return [Class<Mihari::Emitters::Base>] emitter class
195
160
  #
196
- def get_emitter_class(emitter_name)
197
- emitter = EMITTER_TO_CLASS[emitter_name]
198
- return emitter if emitter
161
+ def get_emitter_class(key)
162
+ raise ArgumentError, "#{key} is not supported" unless Mihari.emitter_to_class.key?(key)
199
163
 
200
- raise ArgumentError, "#{emitter_name} is not supported"
164
+ Mihari.emitter_to_class[key]
201
165
  end
202
166
 
203
167
  #
@@ -219,21 +183,20 @@ module Mihari
219
183
  # @return [Array<Mihari::Emitters::Base>]
220
184
  #
221
185
  def valid_emitters
222
- emitters.select(&:valid?)
186
+ @valid_emitters ||= emitters.select(&:valid?)
223
187
  end
224
188
 
225
189
  #
226
190
  # Get enricher class
227
191
  #
228
- # @param [String] enricher_name
192
+ # @param [String] key
229
193
  #
230
194
  # @return [Class<Mihari::Enrichers::Base>] enricher class
231
195
  #
232
- def get_enricher_class(enricher_name)
233
- enricher = ENRICHER_TO_CLASS[enricher_name]
234
- return enricher if enricher
196
+ def get_enricher_class(key)
197
+ raise ArgumentError, "#{key} is not supported" unless Mihari.enricher_to_class.key?(key)
235
198
 
236
- raise ArgumentError, "#{enricher_name} is not supported"
199
+ Mihari.enricher_to_class[key]
237
200
  end
238
201
 
239
202
  #
@@ -258,7 +221,9 @@ module Mihari
258
221
  analyzers.map do |analyzer|
259
222
  next if analyzer.configured?
260
223
 
261
- message = "#{analyzer.source} is not configured correctly. #{analyzer.configuration_keys.join(", ")} is/are missing."
224
+ joined = analyzer.configuration_keys.join(", ")
225
+ be = (analyzer.configuration_keys.length > 1) ? "are" : "is"
226
+ message = "#{analyzer.class.class_key} is not configured correctly. #{joined} #{be} missing."
262
227
  raise ConfigurationError, message
263
228
  end
264
229
  end
@@ -44,6 +44,15 @@ module Mihari
44
44
  %w[securitytrails_api_key]
45
45
  end
46
46
 
47
+ class << self
48
+ #
49
+ # @return [Array<String>, nil]
50
+ #
51
+ def key_aliases
52
+ ["st"]
53
+ end
54
+ end
55
+
47
56
  private
48
57
 
49
58
  def client
@@ -39,6 +39,15 @@ module Mihari
39
39
  %w[virustotal_api_key]
40
40
  end
41
41
 
42
+ class << self
43
+ #
44
+ # @return [Array<String>, nil]
45
+ #
46
+ def key_aliases
47
+ ["vt"]
48
+ end
49
+ end
50
+
42
51
  private
43
52
 
44
53
  def client
@@ -65,7 +74,7 @@ module Mihari
65
74
  data = res["data"] || []
66
75
  data.filter_map do |item|
67
76
  data = item.dig("attributes", "ip_address")
68
- data.nil? ? nil : Artifact.new(data: data, source: source, metadata: item)
77
+ data.nil? ? nil : Artifact.new(data: data, metadata: item)
69
78
  end
70
79
  end
71
80
 
@@ -80,7 +89,7 @@ module Mihari
80
89
  data = res["data"] || []
81
90
  data.filter_map do |item|
82
91
  data = item.dig("attributes", "host_name")
83
- Artifact.new(data: data, source: source, metadata: item)
92
+ Artifact.new(data: data, metadata: item)
84
93
  end.uniq
85
94
  end
86
95
  end
@@ -25,6 +25,22 @@ module Mihari
25
25
  %w[virustotal_api_key]
26
26
  end
27
27
 
28
+ class << self
29
+ #
30
+ # @return [String]
31
+ #
32
+ def class_key
33
+ "virustotal_intelligence"
34
+ end
35
+
36
+ #
37
+ # @return [Array<String>, nil]
38
+ #
39
+ def class_key_aliases
40
+ ["vt_intel"]
41
+ end
42
+ end
43
+
28
44
  private
29
45
 
30
46
  #
@@ -73,9 +73,9 @@ module Mihari
73
73
  data = match["ip"]
74
74
 
75
75
  if data.is_a?(Array)
76
- data.map { |d| Artifact.new(data: d, source: source, metadata: match) }
76
+ data.map { |d| Artifact.new(data: d, metadata: match) }
77
77
  else
78
- Artifact.new(data: data, source: source, metadata: match)
78
+ Artifact.new(data: data, metadata: match)
79
79
  end
80
80
  end.flatten
81
81
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ #
5
+ # Base class for Analyzer, Emitter and Enricher
6
+ #
7
+ class Base
8
+ # @return [Hash]
9
+ attr_reader :options
10
+
11
+ #
12
+ # @param [Hash, nil] options
13
+ #
14
+ def initialize(*_args, options: nil, **_kwargs)
15
+ @options = options || {}
16
+ end
17
+
18
+ #
19
+ # @return [Integer]
20
+ #
21
+ def retry_interval
22
+ options[:retry_interval] || Mihari.config.retry_interval
23
+ end
24
+
25
+ #
26
+ # @return [Boolean]
27
+ #
28
+ def retry_exponential_backoff
29
+ options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
30
+ end
31
+
32
+ #
33
+ # @return [Integer]
34
+ #
35
+ def retry_times
36
+ options[:retry_times] || Mihari.config.retry_times
37
+ end
38
+
39
+ #
40
+ # @return [Integer, nil]
41
+ #
42
+ def timeout
43
+ options[:timeout]
44
+ end
45
+
46
+ class << self
47
+ #
48
+ # @return [String]
49
+ #
50
+ def class_key
51
+ to_s.split("::").last
52
+ end
53
+
54
+ #
55
+ # @return [Array<String>, nil]
56
+ #
57
+ def class_key_aliases
58
+ nil
59
+ end
60
+
61
+ #
62
+ # @return [Array<String>]
63
+ #
64
+ def class_keys
65
+ ([class_key] + [class_key_aliases]).flatten.compact
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "thor"
4
+ require "thor/hollaback"
4
5
 
5
6
  # Commands
6
7
  require "mihari/commands/alert"
@@ -19,10 +20,45 @@ require "mihari/cli/rule"
19
20
  module Mihari
20
21
  module CLI
21
22
  class Main < Base
23
+ class_option :debug, desc: "Sets up debug mode", aliases: ["-d"], type: :boolean
24
+ class_around :safe_execute
25
+
22
26
  include Mihari::Commands::Search
23
27
  include Mihari::Commands::Version
24
28
  include Mihari::Commands::Web
25
29
 
30
+ no_commands do
31
+ def unwrap_error(err)
32
+ return err unless err.is_a?(Dry::Monads::UnwrapError)
33
+
34
+ # NOTE: UnwrapError's receiver can be either of:
35
+ # - Dry::Monads::Try::Error
36
+ # - Dry::Monads::Result::Failure
37
+ receiver = err.receiver
38
+ return receiver.exception if receiver.is_a?(Dry::Monads::Try::Error)
39
+
40
+ receiver.failure
41
+ end
42
+
43
+ def safe_execute
44
+ yield
45
+ rescue StandardError => e
46
+ err = unwrap_error(e)
47
+
48
+ raise err if options["debug"]
49
+
50
+ case err
51
+ when ValidationError
52
+ warn JSON.pretty_generate(err.errors.to_h)
53
+ when StandardError
54
+ Sentry.capture_exception(err) if Sentry.initialized?
55
+ warn err
56
+ end
57
+
58
+ exit 1
59
+ end
60
+ end
61
+
26
62
  desc "db", "Sub commands for DB"
27
63
  subcommand "db", Database
28
64
 
@@ -14,30 +14,14 @@ module Mihari
14
14
  #
15
15
  def add(path)
16
16
  Mihari::Database.with_db_connection do
17
- builder = Mihari::Services::AlertBuilder.new(path)
17
+ builder = Services::AlertBuilder.new(path)
18
18
 
19
19
  run_proxy_l = ->(proxy) { run_proxy proxy }
20
- check_nil_l = ->(alert_or_nil) { check_nil alert_or_nil }
20
+ result = builder.result.bind(run_proxy_l)
21
21
 
22
- result = builder.result.bind(run_proxy_l).bind(check_nil_l)
23
-
24
- if result.success?
25
- alert = result.value!
26
- data = Mihari::Entities::Alert.represent(alert)
27
- puts JSON.pretty_generate(data.as_json)
28
- return
29
- end
30
-
31
- failure = result.failure
32
- case failure
33
- when ValidationError
34
- Mihari.logger.error "Failed to parse the input as an alert:"
35
- Mihari.logger.error JSON.pretty_generate(failure.errors.to_h)
36
- when StandardError
37
- raise failure
38
- else
39
- Mihari.logger.info failure
40
- end
22
+ alert = result.value!
23
+ data = Entities::Alert.represent(alert)
24
+ puts JSON.pretty_generate(data.as_json)
41
25
  end
42
26
  end
43
27
 
@@ -47,21 +31,10 @@ module Mihari
47
31
  #
48
32
  def run_proxy(proxy)
49
33
  Dry::Monads::Try[StandardError] do
50
- runner = Mihari::Services::AlertRunner.new(proxy)
34
+ runner = Services::AlertRunner.new(proxy)
51
35
  runner.run
52
36
  end.to_result
53
37
  end
54
-
55
- #
56
- # @param [Mihari::Alert, nil] alert_or_nil
57
- #
58
- def check_nil(alert_or_nil)
59
- if alert_or_nil.nil?
60
- Failure "There is no new artifact found"
61
- else
62
- Success alert_or_nil
63
- end
64
- end
65
38
  end
66
39
  end
67
40
  end
@@ -8,7 +8,7 @@ module Mihari
8
8
  class << self
9
9
  def included(thor)
10
10
  thor.class_eval do
11
- include Dry::Monads[:result, :try]
11
+ include Dry::Monads[:try, :result]
12
12
 
13
13
  desc "validate [PATH]", "Validate a rule file"
14
14
  #
@@ -18,16 +18,11 @@ module Mihari
18
18
  #
19
19
  def validate(path)
20
20
  res = Dry::Monads::Try[ValidationError] do
21
- Services::RuleProxy.from_yaml(File.read(path))
22
- end.fmap do |rule|
23
- Mihari.logger.info "Valid format. The input is parsed as the following:"
24
- Mihari.logger.info rule.data.to_yaml
21
+ Services::RuleProxy.from_yaml File.read(path)
25
22
  end
26
23
 
27
- return unless res.error?
28
-
29
- Mihari.logger.error "Failed to parse the input as a rule:"
30
- Mihari.logger.error JSON.pretty_generate(res.exception.errors.to_h)
24
+ rule = res.value!
25
+ puts rule.data.to_yaml
31
26
  end
32
27
 
33
28
  desc "init [PATH]", "Initialize a new rule file"
@@ -43,14 +38,14 @@ module Mihari
43
38
 
44
39
  initialize_rule path
45
40
 
46
- Mihari.logger.info "A new rule file has been initialized: #{path}."
41
+ puts "A new rule file has been initialized: #{path}."
47
42
  end
48
43
 
49
44
  no_commands do
50
45
  #
51
46
  # @return [Mihari::Services::Rule]
52
47
  #
53
- def rule_template
48
+ def rule
54
49
  Services::RuleProxy.from_yaml File.read(File.expand_path("../templates/rule.yml.erb", __dir__))
55
50
  end
56
51
 
@@ -63,7 +58,7 @@ module Mihari
63
58
  # @return [nil]
64
59
  #
65
60
  def initialize_rule(path, files = Dry::Files.new)
66
- files.write(path, rule_template.yaml)
61
+ files.write(path, rule.yaml)
67
62
  end
68
63
  end
69
64
  end
@@ -6,10 +6,10 @@ module Mihari
6
6
  class << self
7
7
  def included(thor)
8
8
  thor.class_eval do
9
- include Dry::Monads[:result, :try]
9
+ include Dry::Monads[:try, :result]
10
10
 
11
- desc "search [PATH_OR_ID]", "Search by a rule"
12
- method_option :force_overwrite, type: :boolean, aliases: "-f", desc: "Force an overwrite the rule"
11
+ desc "search [PATH_OR_ID]", "Search by a rule (Outputs null if there is no new finding)"
12
+ method_option :force_overwrite, type: :boolean, aliases: "-f", desc: "Force overwriting a rule"
13
13
  #
14
14
  # Search by a rule
15
15
  #
@@ -21,27 +21,12 @@ module Mihari
21
21
 
22
22
  check_diff_l = ->(rule) { check_diff rule }
23
23
  update_and_run_l = ->(runner) { update_and_run runner }
24
- check_nil_l = ->(alert_or_nil) { check_nil alert_or_nil }
25
24
 
26
- result = builder.result.bind(check_diff_l).bind(update_and_run_l).bind(check_nil_l)
25
+ result = builder.result.bind(check_diff_l).bind(update_and_run_l)
27
26
 
28
- if result.success?
29
- alert = result.value!
30
- data = Mihari::Entities::Alert.represent(alert)
31
- puts JSON.pretty_generate(data.as_json)
32
- return
33
- end
34
-
35
- failure = result.failure
36
- case failure
37
- when ValidationError
38
- Mihari.logger.error "Failed to parse the input as a rule:"
39
- Mihari.logger.error JSON.pretty_generate(failure.errors.to_h)
40
- when StandardError
41
- raise failure
42
- else
43
- Mihari.logger.info failure
44
- end
27
+ alert = result.value!
28
+ data = Entities::Alert.represent(alert)
29
+ puts JSON.pretty_generate(data.as_json)
45
30
  end
46
31
  end
47
32
 
@@ -51,27 +36,14 @@ module Mihari
51
36
  #
52
37
  def check_diff(rule)
53
38
  force_overwrite = options["force_overwrite"] || false
54
- runner = Services::RuleRunner.new(rule, force_overwrite: force_overwrite)
55
- message = "There is a diff in the rule (#{rule.id}). Are you sure you want to overwrite the rule? (y/n)"
39
+ message = "There is a diff in the rule. Are you sure you want to overwrite the rule? (y/n)"
40
+ runner = Services::RuleRunner.new(rule)
56
41
 
57
- if runner.diff? && !force_overwrite && !yes?(message)
58
- return Failure("Stop overwriting the rule (#{rule.id})")
59
- end
42
+ exit 0 if runner.diff? && !force_overwrite && !yes?(message)
60
43
 
61
44
  Success runner
62
45
  end
63
46
 
64
- #
65
- # @param [Mihari::Alert, nil] alert_or_nil
66
- #
67
- def check_nil(alert_or_nil)
68
- if alert_or_nil.nil?
69
- Failure "There is no new artifact found"
70
- else
71
- Success alert_or_nil
72
- end
73
- end
74
-
75
47
  #
76
48
  # @param [Mihari::Services::RuleRunner] runner
77
49
  #
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Mihari
4
4
  # @return [Array<String>]
5
- DEFAULT_DATA_TYPES = %w[hash ip domain url mail].freeze
5
+ DEFAULT_DATA_TYPES = Types::DataTypes.values.freeze
6
6
 
7
7
  # @return [Array<Hash>]
8
- DEFAULT_EMITTERS = %w[database misp slack the_hive].map { |name| { emitter: name } }.freeze
8
+ DEFAULT_EMITTERS = %w[database].map { |name| { emitter: name } }.freeze
9
9
 
10
10
  # @return [Array<Hash>]
11
- DEFAULT_ENRICHERS = %w[whois ipinfo shodan google_public_dns].map { |name| { enricher: name } }.freeze
11
+ DEFAULT_ENRICHERS = Mihari.enricher_to_class.keys.map { |name| { enricher: name.downcase } }.freeze
12
12
  end