mihari 5.5.0 → 5.6.0

Sign up to get free protection for your applications and to get access to all the features.
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