mihari 6.0.0 → 6.2.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/lib/mihari/actor.rb +4 -6
  4. data/lib/mihari/analyzers/base.rb +10 -3
  5. data/lib/mihari/analyzers/circl.rb +1 -1
  6. data/lib/mihari/analyzers/dnstwister.rb +1 -1
  7. data/lib/mihari/analyzers/hunterhow.rb +1 -1
  8. data/lib/mihari/analyzers/otx.rb +1 -1
  9. data/lib/mihari/analyzers/passivetotal.rb +1 -1
  10. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  11. data/lib/mihari/analyzers/securitytrails.rb +1 -1
  12. data/lib/mihari/analyzers/virustotal.rb +1 -1
  13. data/lib/mihari/clients/google_public_dns.rb +31 -0
  14. data/lib/mihari/config.rb +10 -2
  15. data/lib/mihari/{type_checker.rb → data_type.rb} +32 -37
  16. data/lib/mihari/database.rb +8 -4
  17. data/lib/mihari/emitters/misp.rb +2 -2
  18. data/lib/mihari/emitters/slack.rb +5 -5
  19. data/lib/mihari/emitters/the_hive.rb +2 -2
  20. data/lib/mihari/enrichers/base.rb +2 -0
  21. data/lib/mihari/enrichers/google_public_dns.rb +4 -21
  22. data/lib/mihari/enrichers/ipinfo.rb +1 -0
  23. data/lib/mihari/enrichers/shodan.rb +1 -0
  24. data/lib/mihari/enrichers/whois.rb +11 -16
  25. data/lib/mihari/entities/artifact.rb +1 -0
  26. data/lib/mihari/mixins/falsepositive.rb +2 -2
  27. data/lib/mihari/models/artifact.rb +14 -6
  28. data/lib/mihari/models/dns.rb +3 -8
  29. data/lib/mihari/rule.rb +20 -7
  30. data/lib/mihari/schemas/options.rb +5 -1
  31. data/lib/mihari/structs/google_public_dns.rb +4 -8
  32. data/lib/mihari/version.rb +1 -1
  33. data/lib/mihari/web/app.rb +2 -2
  34. data/lib/mihari/web/public/assets/index-1d77cd61.js +1756 -0
  35. data/lib/mihari/web/public/assets/{index-56fc2187.css → index-4c8509ee.css} +1 -1
  36. data/lib/mihari/web/public/index.html +2 -2
  37. data/lib/mihari/web/public/redoc-static.html +5 -5
  38. data/lib/mihari.rb +10 -10
  39. data/mihari.gemspec +5 -4
  40. data/mkdocs.yml +1 -0
  41. data/requirements.txt +1 -1
  42. metadata +23 -50
  43. data/lib/mihari/web/public/assets/index-07cddfcd.js +0 -1750
@@ -20,16 +20,11 @@ module Mihari
20
20
  # @return [Array<Mihari::Models::DnsRecord>]
21
21
  #
22
22
  def build_by_domain(domain, enricher: Enrichers::GooglePublicDNS.new)
23
- result = enricher.result(domain).bind do |responses|
23
+ enricher.result(domain).bind do |res|
24
24
  Success(
25
- responses.map do |res|
26
- res.answers.map do |answer|
27
- new(resource: answer.resource_type, value: answer.data)
28
- end
29
- end.flatten
25
+ res.answers.map { |answer| new(resource: answer.resource_type, value: answer.data) }
30
26
  )
31
- end
32
- result.value_or []
27
+ end.value_or([])
33
28
  end
34
29
  end
35
30
  end
data/lib/mihari/rule.rb CHANGED
@@ -110,9 +110,7 @@ module Mihari
110
110
  # @return [Array<Mihari::Models::Artifact>]
111
111
  #
112
112
  def artifacts
113
- analyzers.flat_map do |analyzer|
114
- # @type [Dry::Monads::Result::Success<Array<Mihari::Models::Artifact>>, Dry::Monads::Result::Failure]
115
- result = analyzer.result
113
+ analyzer_results.flat_map do |result|
116
114
  case result
117
115
  when Success
118
116
  artifacts = result.value!
@@ -123,7 +121,7 @@ module Mihari
123
121
  else
124
122
  raise result.failure unless analyzer.ignore_error?
125
123
  end
126
- end.compact
124
+ end
127
125
  end
128
126
 
129
127
  #
@@ -292,15 +290,30 @@ module Mihari
292
290
  # @return [Array<Mihari::Analyzers::Base>]
293
291
  #
294
292
  def analyzers
295
- @analyzers ||= queries.map do |query_params|
296
- analyzer_name = query_params[:analyzer]
293
+ @analyzers ||= queries.map do |params|
294
+ analyzer_name = params[:analyzer]
297
295
  klass = get_analyzer_class(analyzer_name)
298
- analyzer = klass.from_query(query_params)
296
+ analyzer = klass.from_query(params)
299
297
  analyzer.validate_configuration!
300
298
  analyzer
301
299
  end
302
300
  end
303
301
 
302
+ def parallel_analyzers
303
+ analyzers.select(&:parallel?)
304
+ end
305
+
306
+ def serial_analyzers
307
+ analyzers.reject(&:parallel?)
308
+ end
309
+
310
+ # @return [Array<Dry::Monads::Result::Success<Array<Mihari::Models::Artifact>>, Dry::Monads::Result::Failure>]
311
+ def analyzer_results
312
+ parallel_results = Parallel.map(parallel_analyzers) { |analyzer| analyzer.result }
313
+ serial_results = serial_analyzers.map(&:result)
314
+ parallel_results + serial_results
315
+ end
316
+
304
317
  #
305
318
  # Get emitter class
306
319
  #
@@ -15,7 +15,11 @@ module Mihari
15
15
  optional(:ignore_error).value(:bool).default(Mihari.config.ignore_error)
16
16
  end
17
17
 
18
- AnalyzerOptions = Options | IgnoreErrorOptions
18
+ ParallelOptions = Dry::Schema.Params do
19
+ optional(:parallel).value(:bool).default(Mihari.config.parallel)
20
+ end
21
+
22
+ AnalyzerOptions = Options | IgnoreErrorOptions | ParallelOptions
19
23
 
20
24
  PaginationOptions = Dry::Schema.Params do
21
25
  optional(:pagination_interval).value(:integer).default(Mihari.config.pagination_interval)
@@ -3,13 +3,9 @@
3
3
  module Mihari
4
4
  module Structs
5
5
  module GooglePublicDNS
6
- INT_TYPE_TO_TYPE = {
7
- 1 => "A",
8
- 2 => "NS",
9
- 5 => "CNAME",
10
- 16 => "TXT",
11
- 28 => "AAAA"
12
- }.freeze
6
+ INT_TYPE_TO_TYPE =
7
+ { 1 => :A, 38 => :A6, 28 => :AAAA, 18 => :AFSDB, 255 => :ANY, 42 => :APL, 34 => :ATMA, 252 => :AXFR, 37 => :CERT,
8
+ 5 => :CNAME, 49 => :DHCID, 32_769 => :DLV, 39 => :DNAME, 48 => :DNSKEY, 43 => :DS, 31 => :EID, 102 => :GID, 27 => :GPOS, 13 => :HINFO, 45 => :IPSECKEY, 20 => :ISDN, 251 => :IXFR, 25 => :KEY, 36 => :KX, 29 => :LOC, 254 => :MAILA, 253 => :MAILB, 7 => :MB, 3 => :MD, 4 => :MF, 8 => :MG, 14 => :MINFO, 9 => :MR, 15 => :MX, 35 => :NAPTR, 32 => :NIMLOC, 2 => :NS, 22 => :NSAP, 23 => :NSAP_PTR, 47 => :NSEC, 50 => :NSEC3, 51 => :NSEC3PARAMS, 10 => :NULL, 30 => :NXT, 41 => :OPT, 12 => :PTR, 26 => :PX, 17 => :RP, 46 => :RRSIG, 21 => :RT, 24 => :SIG, 40 => :SINK, 6 => :SOA, 33 => :SRV, 44 => :SSHFP, 250 => :TSIG, 16 => :TXT, 101 => :UID, 100 => :UINFO, 103 => :UNSPEC, 11 => :WKS, 19 => :X25 }
13
9
 
14
10
  class Answer < Dry::Struct
15
11
  # @!attribute [r] name
@@ -30,7 +26,7 @@ module Mihari
30
26
  #
31
27
  def from_dynamic!(d)
32
28
  d = Types::Hash[d]
33
- resource_type = INT_TYPE_TO_TYPE[d.fetch("type")]
29
+ resource_type = INT_TYPE_TO_TYPE[d.fetch("type")].to_s
34
30
  new(
35
31
  name: d.fetch("name"),
36
32
  data: d.fetch("data"),
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "6.0.0"
4
+ VERSION = "6.2.0"
5
5
  end
@@ -53,17 +53,17 @@ module Mihari
53
53
 
54
54
  class << self
55
55
  def instance
56
- @instance ||= Rack::Builder.new do
56
+ Rack::Builder.new do
57
57
  use Rack::Cors do
58
58
  allow do
59
59
  origins "*"
60
60
  resource "*", headers: :any, methods: %i[get post put delete options]
61
61
  end
62
62
  end
63
-
64
63
  use Middleware::ConnectionAdapter
65
64
  use Middleware::ErrorNotificationAdapter
66
65
 
66
+ use Sentry::Rack::CaptureExceptions if Sentry.initialized?
67
67
  use BetterErrors::Middleware if ENV["RACK_ENV"] == "development" && defined?(BetterErrors::Middleware)
68
68
 
69
69
  run App.new