mihari 6.0.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2846f5154fcdde4cda4f0237c79e047fc498b96b5c21a6152287ac9ab11faac9
4
- data.tar.gz: f43b4e20a59b1274b62c5e9768f153429540067882508b34f0c36932cc9cb5ef
3
+ metadata.gz: d49d8a079c765cb4b7ad7a08825a9d0bd4e9e21fbaf2c0f185c4f27e8f2f2ca6
4
+ data.tar.gz: aa693115eb1dacc09d13ca0942d859e24566c09a4cd6d702840ec9df6c3cc87a
5
5
  SHA512:
6
- metadata.gz: b54da0da25e57531c1efef94bdc42df715569b9e88842ca330d1d0893f4c20990bb2ded22a001f31816cbd72f00f43473f0254f222a9849308be746576128e3c
7
- data.tar.gz: 7167afd356c4f945e66631bb3c6cefc06678961b480511d85939e6ede9eccec9a5f83a948a169be9ee7ba5cc79af918a447b8f01e5280faff3138071e7808beb
6
+ metadata.gz: e50a254b0c5565c3691cc34df0413258a1903f8864f0ced141fab63cb673f02998451723036917f2adf21f759ec3f0086b772e98a02ee0436869dd5846bf3427
7
+ data.tar.gz: 63738367f8edd23331518eb839c188dde8fb67257b83b5cd6a11e79dc725aa89b151753e7429515ff1b2f7c689da77adf4eac998241b7bfd04f88302aa52c923
data/.rubocop.yml CHANGED
@@ -13,6 +13,10 @@ Metrics/MethodLength:
13
13
  Max: 50
14
14
  Metrics/AbcSize:
15
15
  Max: 50
16
+ RSpec/MultipleMemoizedHelpers:
17
+ Max: 10
18
+ RSpec/ExampleLength:
19
+ Max: 20
16
20
  require:
17
21
  - rubocop-rspec
18
22
  - rubocop-yard
data/lib/mihari/actor.rb CHANGED
@@ -65,11 +65,9 @@ module Mihari
65
65
 
66
66
  def result(...)
67
67
  Try[StandardError] do
68
- retry_on_error(
69
- times: retry_times,
70
- interval: retry_interval,
71
- exponential_backoff: retry_exponential_backoff
72
- ) { call(...) }
68
+ retry_on_error(times: retry_times, interval: retry_interval, exponential_backoff: retry_exponential_backoff) do
69
+ call(...)
70
+ end
73
71
  end.to_result
74
72
  end
75
73
 
@@ -78,7 +76,7 @@ module Mihari
78
76
  # @return [String]
79
77
  #
80
78
  def class_key
81
- to_s.split("::").last
79
+ to_s.split("::").last.downcase
82
80
  end
83
81
 
84
82
  #
@@ -37,10 +37,14 @@ module Mihari
37
37
  # @return [Boolean]
38
38
  #
39
39
  def ignore_error?
40
- ignore_error = options[:ignore_error]
41
- return ignore_error unless ignore_error.nil?
40
+ options[:ignore_error] || Mihari.config.ignore_error
41
+ end
42
42
 
43
- Mihari.config.ignore_error
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def parallel?
47
+ options[:parallel] || Mihari.config.parallel
44
48
  end
45
49
 
46
50
  # @return [Array<String>, Array<Mihari::Models::Artifact>]
@@ -60,7 +64,10 @@ module Mihari
60
64
  # No need to set data_type manually
61
65
  # It is set automatically in #initialize
62
66
  artifact = artifact.is_a?(Models::Artifact) ? artifact : Models::Artifact.new(data: artifact)
67
+
63
68
  artifact.source = self.class.class_key
69
+ artifact.query = query
70
+
64
71
  artifact
65
72
  end.select(&:valid?).uniq(&:data)
66
73
  end
@@ -26,7 +26,7 @@ module Mihari
26
26
  def initialize(query, options: nil, username: nil, password: nil)
27
27
  super(refang(query), options: options)
28
28
 
29
- @type = TypeChecker.type(query)
29
+ @type = DataType.type(query)
30
30
 
31
31
  @username = username || Mihari.config.circl_passive_username
32
32
  @password = password || Mihari.config.circl_passive_password
@@ -18,7 +18,7 @@ module Mihari
18
18
  def initialize(query, options: nil)
19
19
  super(refang(query), options: options)
20
20
 
21
- @type = TypeChecker.type(query)
21
+ @type = DataType.type(query)
22
22
  end
23
23
 
24
24
  def artifacts
@@ -22,7 +22,7 @@ module Mihari
22
22
  # @param [Hash, nil] options
23
23
  # @param [String, nil] api_key
24
24
  #
25
- def initialize(query, start_time:, end_time:, options: nil, api_key: nil)
25
+ def initialize(query, start_time: nil, end_time: nil, options: nil, api_key: nil)
26
26
  super(query, options: options)
27
27
 
28
28
  @api_key = api_key || Mihari.config.hunterhow_api_key
@@ -22,7 +22,7 @@ module Mihari
22
22
  def initialize(query, options: nil, api_key: nil)
23
23
  super(refang(query), options: options)
24
24
 
25
- @type = TypeChecker.type(query)
25
+ @type = DataType.type(query)
26
26
 
27
27
  @api_key = api_key || Mihari.config.otx_api_key
28
28
  end
@@ -26,7 +26,7 @@ module Mihari
26
26
  def initialize(query, options: nil, api_key: nil, username: nil)
27
27
  super(refang(query), options: options)
28
28
 
29
- @type = TypeChecker.type(query)
29
+ @type = DataType.type(query)
30
30
 
31
31
  @username = username || Mihari.config.passivetotal_username
32
32
  @api_key = api_key || Mihari.config.passivetotal_api_key
@@ -22,7 +22,7 @@ module Mihari
22
22
  def initialize(query, options: nil, api_key: nil)
23
23
  super(refang(query), options: options)
24
24
 
25
- @type = TypeChecker.type(query)
25
+ @type = DataType.type(query)
26
26
 
27
27
  @api_key = api_key || Mihari.config.pulsedive_api_key
28
28
  end
@@ -25,7 +25,7 @@ module Mihari
25
25
  def initialize(query, options: nil, api_key: nil)
26
26
  super(refang(query), options: options)
27
27
 
28
- @type = TypeChecker.type(query)
28
+ @type = DataType.type(query)
29
29
 
30
30
  @api_key = api_key || Mihari.config.securitytrails_api_key
31
31
  end
@@ -22,7 +22,7 @@ module Mihari
22
22
  def initialize(query, options: nil, api_key: nil)
23
23
  super(refang(query), options: options)
24
24
 
25
- @type = TypeChecker.type(query)
25
+ @type = DataType.type(query)
26
26
 
27
27
  @api_key = api_key || Mihari.config.virustotal_api_key
28
28
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Clients
5
+ #
6
+ # Google Public DNS enricher
7
+ #
8
+ class GooglePublicDNS < Base
9
+ #
10
+ # @param [String] base_url
11
+ # @param [Hash] headers
12
+ # @param [Integer, nil] timeout
13
+ #
14
+ def initialize(base_url = "https://dns.google", headers: {}, timeout: nil)
15
+ super(base_url, headers: headers, timeout: timeout)
16
+ end
17
+
18
+ #
19
+ # Query Google Public DNS by resource type
20
+ #
21
+ # @param [String] name
22
+ #
23
+ # @return [Mihari::Structs::GooglePublicDNS::Response, nil]
24
+ #
25
+ def query_all(name)
26
+ Structs::GooglePublicDNS::Response.from_dynamic! get_json("/resolve",
27
+ params: { name: name, type: "ALL" })
28
+ end
29
+ end
30
+ end
31
+ end
data/lib/mihari/config.rb CHANGED
@@ -42,10 +42,12 @@ module Mihari
42
42
  ignore_error: false,
43
43
  pagination_interval: 0,
44
44
  pagination_limit: 100,
45
+ parallel: false,
45
46
  retry_exponential_backoff: true,
46
47
  retry_interval: 5,
47
48
  retry_times: 3,
48
- sentry_dsn: nil
49
+ sentry_dsn: nil,
50
+ sentry_trace_sample_rate: 0.25
49
51
  )
50
52
 
51
53
  # @!attribute [r] binaryedge_api_key
@@ -61,7 +63,7 @@ module Mihari
61
63
  # @return [String, nil]
62
64
 
63
65
  # @!attribute [r] database_url
64
- # @return [String, nil]
66
+ # @return [URI, nil]
65
67
 
66
68
  # @!attribute [r] fofa_api_key
67
69
  # @return [String, nil]
@@ -132,6 +134,9 @@ module Mihari
132
134
  # @!attribute [r] sentry_dsn
133
135
  # @return [String, nil]
134
136
 
137
+ # @!attribute [r] sentry_trace_sample_rate
138
+ # @return [Float]
139
+
135
140
  # @!attribute [r] retry_interval
136
141
  # @return [Integer]
137
142
 
@@ -147,6 +152,9 @@ module Mihari
147
152
  # @!attribute [r] pagination_limit
148
153
  # @return [Integer]
149
154
 
155
+ # @!attribute [r] parallel
156
+ # @return [Boolean]
157
+
150
158
  # @!attribute [r] ignore_error
151
159
  # @return [Boolean]
152
160
 
@@ -2,9 +2,11 @@
2
2
 
3
3
  module Mihari
4
4
  #
5
- # Artifact type checker
5
+ # (Artifact) Data Type
6
6
  #
7
- class TypeChecker
7
+ class DataType
8
+ include Dry::Monads[:try]
9
+
8
10
  # @return [String]
9
11
  attr_reader :data
10
12
 
@@ -24,26 +26,25 @@ module Mihari
24
26
 
25
27
  # @return [Boolean]
26
28
  def ip?
27
- IPAddr.new data
28
- true
29
- rescue IPAddr::InvalidAddressError => _e
30
- false
29
+ Try[IPAddr::InvalidAddressError] do
30
+ IPAddr.new(data).to_s == data
31
+ end.to_result.value_or(false)
31
32
  end
32
33
 
33
34
  # @return [Boolean]
34
35
  def domain?
35
- uri = Addressable::URI.parse("http://#{data}")
36
- uri.host == data && PublicSuffix.valid?(uri.host)
37
- rescue Addressable::URI::InvalidURIError => _e
38
- false
36
+ Try[Addressable::URI::InvalidURIError] do
37
+ uri = Addressable::URI.parse("http://#{data}")
38
+ uri.host == data && PublicSuffix.valid?(uri.host)
39
+ end.to_result.value_or(false)
39
40
  end
40
41
 
41
42
  # @return [Boolean]
42
43
  def url?
43
- uri = Addressable::URI.parse(data)
44
- uri.scheme && uri.host && uri.path && PublicSuffix.valid?(uri.host)
45
- rescue Addressable::URI::InvalidURIError => _e
46
- false
44
+ Try[Addressable::URI::InvalidURIError] do
45
+ uri = Addressable::URI.parse(data)
46
+ uri.scheme && uri.host && uri.path && PublicSuffix.valid?(uri.host)
47
+ end.to_result.value_or(false)
47
48
  end
48
49
 
49
50
  # @return [Boolean]
@@ -53,38 +54,20 @@ module Mihari
53
54
 
54
55
  # @return [String, nil]
55
56
  def type
56
- return "hash" if hash?
57
- return "ip" if ip?
58
- return "domain" if domain?
59
- return "url" if url?
57
+ found = %i[hash? ip? domain? url? mail?].find { |method| send(method) if respond_to?(method) }
58
+ return nil if found.nil?
60
59
 
61
- "mail" if mail?
60
+ found[...-1].to_s
62
61
  end
63
62
 
64
63
  # @return [String, nil]
65
64
  def detailed_type
66
- return "md5" if md5?
67
- return "sha1" if sha1?
68
- return "sha256" if sha256?
69
- return "sha512" if sha512?
65
+ found = %i[md5? sha1? sha256? sha512?].find { |method| send(method) if respond_to?(method) }
66
+ return found[...-1].to_s unless found.nil?
70
67
 
71
68
  type
72
69
  end
73
70
 
74
- class << self
75
- # @return [String, nil]
76
- def type(data)
77
- new(data).type
78
- end
79
-
80
- # @return [String, nil]
81
- def detailed_type(data)
82
- new(data).detailed_type
83
- end
84
- end
85
-
86
- private
87
-
88
71
  # @return [Boolean]
89
72
  def md5?
90
73
  data.match?(/^[A-Fa-f0-9]{32}$/)
@@ -104,5 +87,17 @@ module Mihari
104
87
  def sha512?
105
88
  data.match?(/^[A-Fa-f0-9]{128}$/)
106
89
  end
90
+
91
+ class << self
92
+ # @return [String, nil]
93
+ def type(data)
94
+ new(data).type
95
+ end
96
+
97
+ # @return [String, nil]
98
+ def detailed_type(data)
99
+ new(data).detailed_type
100
+ end
101
+ end
107
102
  end
108
103
  end
@@ -111,6 +111,12 @@ class V5Schema < ActiveRecord::Migration[7.1]
111
111
  end
112
112
  end
113
113
 
114
+ class V61Schema < ActiveRecord::Migration[7.1]
115
+ def change
116
+ add_column :artifacts, :query, :string
117
+ end
118
+ end
119
+
114
120
  def adapter
115
121
  return "postgresql" if %w[postgresql postgres].include?(Mihari.config.database_url.scheme)
116
122
  return "mysql2" if Mihari.config.database_url.scheme == "mysql2"
@@ -122,7 +128,7 @@ end
122
128
  # @return [Array<ActiveRecord::Migration>] schemas
123
129
  #
124
130
  def schemas
125
- [V5Schema]
131
+ [V5Schema, V61Schema]
126
132
  end
127
133
 
128
134
  module Mihari
@@ -148,7 +154,7 @@ module Mihari
148
154
 
149
155
  case adapter
150
156
  when "postgresql", "mysql2"
151
- ActiveRecord::Base.establish_connection(Mihari.config.database_url.to_s)
157
+ ActiveRecord::Base.establish_connection Mihari.config.database_url.to_s
152
158
  else
153
159
  ActiveRecord::Base.establish_connection(
154
160
  adapter: adapter,
@@ -156,8 +162,6 @@ module Mihari
156
162
  )
157
163
  end
158
164
  ActiveRecord::Base.logger = Logger.new($stdout) if development_env?
159
- rescue StandardError => e
160
- Mihari.logger.error e
161
165
  end
162
166
 
163
167
  #
@@ -56,12 +56,12 @@ module Mihari
56
56
  })
57
57
  end
58
58
 
59
- private
60
-
61
59
  def configuration_keys
62
60
  %w[misp_url misp_api_key]
63
61
  end
64
62
 
63
+ private
64
+
65
65
  def client
66
66
  @client ||= Clients::MISP.new(url, api_key: api_key, timeout: timeout)
67
67
  end
@@ -6,7 +6,7 @@ require "slack-notifier"
6
6
  module Mihari
7
7
  module Emitters
8
8
  class Attachment
9
- include Memist::Memoizable
9
+ prepend MemoWise
10
10
 
11
11
  # @return [String]
12
12
  attr_reader :data
@@ -76,7 +76,7 @@ module Mihari
76
76
  "https://urlscan.io/domain/#{uri.hostname}"
77
77
  end
78
78
  end
79
- memoize :_urlscan_link
79
+ memo_wise :_urlscan_link
80
80
 
81
81
  # @return [String, nil]
82
82
  def _vt_link
@@ -93,19 +93,19 @@ module Mihari
93
93
  "https://www.virustotal.com/#/search/#{data}"
94
94
  end
95
95
  end
96
- memoize :_vt_link
96
+ memo_wise :_vt_link
97
97
 
98
98
  # @return [String, nil]
99
99
  def _censys_link
100
100
  (data_type == "ip") ? "https://search.censys.io/hosts/#{data}" : nil
101
101
  end
102
- memoize :_censys_link
102
+ memo_wise :_censys_link
103
103
 
104
104
  # @return [String, nil]
105
105
  def _shodan_link
106
106
  (data_type == "ip") ? "https://www.shodan.io/host/#{data}" : nil
107
107
  end
108
- memoize :_shodan_link
108
+ memo_wise :_shodan_link
109
109
 
110
110
  # @return [String]
111
111
  def sha256
@@ -66,12 +66,12 @@ module Mihari
66
66
  end.first
67
67
  end
68
68
 
69
- private
70
-
71
69
  def configuration_keys
72
70
  %w[thehive_url thehive_api_key]
73
71
  end
74
72
 
73
+ private
74
+
75
75
  def client
76
76
  @client ||= Clients::TheHive.new(url, api_key: api_key, api_version: normalized_api_version, timeout: timeout)
77
77
  end
@@ -6,6 +6,8 @@ module Mihari
6
6
  # Base class for enrichers
7
7
  #
8
8
  class Base < Actor
9
+ prepend MemoWise
10
+
9
11
  def initialize(options: nil)
10
12
  super(options: options)
11
13
  end
@@ -11,27 +11,10 @@ module Mihari
11
11
  #
12
12
  # @param [String] name
13
13
  #
14
- # @return [Array<Mihari::Structs::GooglePublicDNS::Response>]
14
+ # @return [Mihari::Structs::GooglePublicDNS::Response]
15
15
  #
16
16
  def call(name)
17
- %w[A AAAA CNAME TXT NS].filter_map { |resource_type| query_by_type(name, resource_type) }
18
- end
19
-
20
- #
21
- # Query Google Public DNS by resource type
22
- #
23
- # @param [String] name
24
- # @param [String] resource_type
25
- #
26
- # @return [Mihari::Structs::GooglePublicDNS::Response, nil]
27
- #
28
- def query_by_type(name, resource_type)
29
- url = "https://dns.google/resolve"
30
- params = { name: name, type: resource_type }
31
- res = http.get(url, params: params)
32
- Structs::GooglePublicDNS::Response.from_dynamic! JSON.parse(res.body.to_s)
33
- rescue HTTPError
34
- nil
17
+ client.query_all name
35
18
  end
36
19
 
37
20
  class << self
@@ -45,8 +28,8 @@ module Mihari
45
28
 
46
29
  private
47
30
 
48
- def http
49
- HTTP::Factory.build timeout: timeout
31
+ def client
32
+ Clients::GooglePublicDNS.new
50
33
  end
51
34
  end
52
35
  end
@@ -35,6 +35,7 @@ module Mihari
35
35
  res = http.get(url)
36
36
  Structs::IPInfo::Response.from_dynamic! JSON.parse(res.body.to_s)
37
37
  end
38
+ memo_wise :call
38
39
 
39
40
  private
40
41
 
@@ -18,6 +18,7 @@ module Mihari
18
18
  res = http.get(url)
19
19
  Structs::Shodan::InternetDBResponse.from_dynamic! JSON.parse(res.body.to_s)
20
20
  end
21
+ memo_wise :call
21
22
 
22
23
  private
23
24
 
@@ -8,16 +8,11 @@ module Mihari
8
8
  # Whois enricher
9
9
  #
10
10
  class Whois < Base
11
- # @return [Hash]
12
- attr_accessor :memo
13
-
14
11
  #
15
12
  # @param [Hash, nil] options
16
13
  #
17
14
  def initialize(options: nil)
18
15
  super(options: options)
19
-
20
- @memo = {}
21
16
  end
22
17
 
23
18
  #
@@ -28,16 +23,22 @@ module Mihari
28
23
  # @return [Mihari::Models::WhoisRecord, nil]
29
24
  #
30
25
  def call(domain)
31
- domain = PublicSuffix.domain(domain)
26
+ _call PublicSuffix.domain(domain)
27
+ end
32
28
 
33
- # check memo
34
- return memo[domain].dup if memo.key?(domain)
29
+ private
35
30
 
31
+ #
32
+ # @param [String] domain
33
+ #
34
+ # @return [Mihari::Models::WhoisRecord, nil]
35
+ #
36
+ def _call(domain)
36
37
  record = whois.lookup(domain)
37
38
  parser = record.parser
38
39
  return nil if parser.available?
39
40
 
40
- whois_record = Models::WhoisRecord.new(
41
+ Models::WhoisRecord.new(
41
42
  domain: domain,
42
43
  created_on: get_created_on(parser),
43
44
  updated_on: get_updated_on(parser),
@@ -45,14 +46,8 @@ module Mihari
45
46
  registrar: get_registrar(parser),
46
47
  contacts: get_contacts(parser)
47
48
  )
48
-
49
- # set memo
50
- memo[domain] = whois_record
51
-
52
- whois_record
53
49
  end
54
-
55
- private
50
+ memo_wise :_call
56
51
 
57
52
  #
58
53
  # @return [::Whois::Client]
@@ -11,6 +11,7 @@ module Mihari
11
11
  expose :data, documentation: { type: String, required: true }
12
12
  expose :data_type, documentation: { type: String, required: true }, as: :dataType
13
13
  expose :source, documentation: { type: String, required: true }
14
+ expose :query, documentation: { type: String, required: false }
14
15
  expose :tags, documentation: { type: String, is_array: true }
15
16
  end
16
17
 
@@ -6,7 +6,7 @@ module Mihari
6
6
  # False positive mixins
7
7
  #
8
8
  module FalsePositive
9
- include Memist::Memoizable
9
+ prepend MemoWise
10
10
 
11
11
  #
12
12
  # Normalize a falsepositive value
@@ -22,7 +22,7 @@ module Mihari
22
22
  value_without_slashes = value[1..-2]
23
23
  Regexp.compile value_without_slashes.to_s
24
24
  end
25
- memoize :normalize_falsepositive
25
+ memo_wise :normalize_falsepositive
26
26
 
27
27
  #
28
28
  # Check whether a value is valid format as a disallowed data value
@@ -46,7 +46,7 @@ module Mihari
46
46
 
47
47
  super(*args, **kwargs)
48
48
 
49
- self.data_type = TypeChecker.type(data)
49
+ self.data_type = DataType.type(data)
50
50
 
51
51
  @tags = []
52
52
  @rule_id = ""
@@ -158,13 +158,13 @@ module Mihari
158
158
  # Enrich all the enrichable relationships of the artifact
159
159
  #
160
160
  def enrich_all
161
- enrich_autonomous_system
161
+ enrich_autonomous_system ipinfo
162
162
  enrich_dns
163
- enrich_geolocation
164
- enrich_reverse_dns
163
+ enrich_geolocation ipinfo
164
+ enrich_reverse_dns shodan
165
165
  enrich_whois
166
- enrich_ports
167
- enrich_cpes
166
+ enrich_ports shodan
167
+ enrich_cpes shodan
168
168
  end
169
169
 
170
170
  ENRICH_METHODS_BY_ENRICHER = {
@@ -197,6 +197,14 @@ module Mihari
197
197
 
198
198
  private
199
199
 
200
+ def ipinfo
201
+ @ipinfo ||= Enrichers::IPInfo.new
202
+ end
203
+
204
+ def shodan
205
+ @shodan ||= Enrichers::Shodan.new
206
+ end
207
+
200
208
  def normalize_as_domain(url_or_domain)
201
209
  return url_or_domain if data_type == "domain"
202
210