mihari 4.6.1 → 4.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 491cb9d0477c4101251c1f3e5705328008a196920efb41c239048247937f21f4
4
- data.tar.gz: 14bcfd11b8871a759e70f6658cf2773dadc6afe7ffde44dbbffaef99961b8e00
3
+ metadata.gz: '091892853042ab3f1010c89b943eb2a885370da2d619016f3f3cd9dcb59e80cf'
4
+ data.tar.gz: 119ccbb407a49c741a4bf6c7cfafc7cd99855c3af950af9d0f1dc3735fc24672
5
5
  SHA512:
6
- metadata.gz: d833915545629ade609ec994e6139387fd66247fa1c48fdbe4e3eab01679fb42820e3b07cb95fdbb8cff092753394f1dfa9aaa4459259837c2c0d7d5f2f855ed
7
- data.tar.gz: dcbb112faa805b27157ec72d0f3544031c7e7789e855eb082a69a76216d0fcd644013ade95aea28ae138ebfb3bc8eb90d8fb922c83999d292c12b78d15acfe5c
6
+ metadata.gz: 5364837634a6cde1b370db5613e745f05b40bf7321a5b7fcc4a2c7d32b1d395fa45e4472ef2a5f9f28d664f0b45e31d0554acec7bb641a21ce179ebf70bf9317
7
+ data.tar.gz: 57ca2f920db2da9e8c9a10f59aa81984dff0a81f0073ba839c351f3fe5e7979358ce44d87f48adcffd7df1bf7268bab178fec82731f72d62c24aa9ce04eed026
@@ -51,6 +51,7 @@ module Mihari
51
51
  option :disallowed_data_values, default: proc { [] }
52
52
 
53
53
  option :emitters, optional: true
54
+ option :enrichers, optional: true
54
55
 
55
56
  attr_reader :source
56
57
 
@@ -60,6 +61,7 @@ module Mihari
60
61
  @source = id
61
62
 
62
63
  @emitters = emitters || DEFAULT_EMITTERS
64
+ @enrichers = enrichers || DEFAULT_ENRICHERS
63
65
 
64
66
  validate_analyzer_configurations
65
67
  end
@@ -112,6 +114,21 @@ module Mihari
112
114
  end
113
115
  end
114
116
 
117
+ #
118
+ # Enriched artifacts
119
+ #
120
+ # @return [Array<Mihari::Artifact>]
121
+ #
122
+ def enriched_artifacts
123
+ @enriched_artifacts ||= Parallel.map(unique_artifacts) do |artifact|
124
+ enrichers.each do |enricher|
125
+ artifact.enrich_by_enricher(enricher[:enricher])
126
+ end
127
+
128
+ artifact
129
+ end
130
+ end
131
+
115
132
  #
116
133
  # Normalized disallowed data values
117
134
  #
@@ -4,4 +4,6 @@ module Mihari
4
4
  ALLOWED_DATA_TYPES = ["hash", "ip", "domain", "url", "mail"].freeze
5
5
 
6
6
  DEFAULT_EMITTERS = ["database", "misp", "slack", "the_hive", "webhook"].map { |name| { emitter: name } }.freeze
7
+
8
+ DEFAULT_ENRICHERS = ["whois", "ipinfo", "shodan", "google_public_dns"].map { |name| { enricher: name } }.freeze
7
9
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/https"
4
+
5
+ module Mihari
6
+ module Enrichers
7
+ class GooglePublicDNS < Base
8
+ # @return [Boolean]
9
+ def valid?
10
+ true
11
+ end
12
+
13
+ class << self
14
+ #
15
+ # Query Google Public DNS
16
+ #
17
+ # @param [String] name
18
+ # @param [String] resource_type
19
+ #
20
+ # @return [Mihari::Structs::Shodan::GooglePublicDNS::Response, nil]
21
+ #
22
+ def query(name, resource_type)
23
+ url = "https://dns.google/resolve"
24
+ params = { name: name, type: resource_type }
25
+ res = HTTP.get(url, params: params)
26
+
27
+ data = JSON.parse(res.body.to_s)
28
+
29
+ Structs::GooglePublicDNS::Response.from_dynamic! data
30
+ rescue HTTPError
31
+ nil
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "whois-parser"
4
+
5
+ module Mihari
6
+ module Enrichers
7
+ class Whois < Base
8
+ @memo = {}
9
+
10
+ # @return [Boolean]
11
+ def valid?
12
+ true
13
+ end
14
+
15
+ class << self
16
+ #
17
+ # Query IAIA Whois API
18
+ #
19
+ # @param [String] name
20
+ #
21
+ # @return [Mihari::WhoisRecord, nil]
22
+ #
23
+ def query(domain)
24
+ domain = PublicSuffix.domain(domain)
25
+
26
+ # check memo
27
+ if @memo.key?(domain)
28
+ whois_record = @memo[domain]
29
+ # return clone of the record
30
+ return whois_record.dup
31
+ end
32
+
33
+ record = ::Whois.whois(domain)
34
+ parser = record.parser
35
+
36
+ return nil if parser.available?
37
+
38
+ whois_record = WhoisRecord.new(
39
+ domain: domain,
40
+ created_on: get_created_on(parser),
41
+ updated_on: get_updated_on(parser),
42
+ expires_on: get_expires_on(parser),
43
+ registrar: get_registrar(parser),
44
+ contacts: get_contacts(parser)
45
+ )
46
+ # set memo
47
+ @memo[domain] = whois_record
48
+ whois_record
49
+ rescue ::Whois::Error, ::Whois::ParserError, Timeout::Error
50
+ nil
51
+ end
52
+
53
+ def reset_cache
54
+ @memo = {}
55
+ end
56
+
57
+ private
58
+
59
+ #
60
+ # Get created_on
61
+ #
62
+ # @param [::Whois::Parser:] parser
63
+ #
64
+ # @return [Date, nil]
65
+ #
66
+ def get_created_on(parser)
67
+ parser.created_on
68
+ rescue ::Whois::AttributeNotImplemented
69
+ nil
70
+ end
71
+
72
+ #
73
+ # Get updated_on
74
+ #
75
+ # @param [::Whois::Parser:] parser
76
+ #
77
+ # @return [Date, nil]
78
+ #
79
+ def get_updated_on(parser)
80
+ parser.updated_on
81
+ rescue ::Whois::AttributeNotImplemented
82
+ nil
83
+ end
84
+
85
+ #
86
+ # Get expires_on
87
+ #
88
+ # @param [::Whois::Parser:] parser
89
+ #
90
+ # @return [Date, nil]
91
+ #
92
+ def get_expires_on(parser)
93
+ parser.expires_on
94
+ rescue ::Whois::AttributeNotImplemented
95
+ nil
96
+ end
97
+
98
+ #
99
+ # Get registrar
100
+ #
101
+ # @param [::Whois::Parser:] parser
102
+ #
103
+ # @return [Hash, nil]
104
+ #
105
+ def get_registrar(parser)
106
+ parser.registrar&.to_h
107
+ rescue ::Whois::AttributeNotImplemented
108
+ nil
109
+ end
110
+
111
+ #
112
+ # Get contacts
113
+ #
114
+ # @param [::Whois::Parser:] parser
115
+ #
116
+ # @return [Array[Hash], nil]
117
+ #
118
+ def get_contacts(parser)
119
+ parser.contacts.map(&:to_h)
120
+ rescue ::Whois::AttributeNotImplemented
121
+ nil
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
data/lib/mihari/http.rb CHANGED
@@ -44,8 +44,8 @@ module Mihari
44
44
  end
45
45
 
46
46
  class << self
47
- def get(uri, headers: {}, payload: {})
48
- client = new(uri, headers: headers, payload: payload)
47
+ def get(uri, headers: {}, params: {})
48
+ client = new(uri, headers: headers, payload: params)
49
49
  client.get
50
50
  end
51
51
 
@@ -135,6 +135,36 @@ module Mihari
135
135
  enrich_cpes
136
136
  end
137
137
 
138
+ ENRICH_METHODS_BY_ENRICHER = {
139
+ whois: [
140
+ :enrich_whois
141
+ ],
142
+ ipinfo: [
143
+ :enrich_autonomous_system,
144
+ :enrich_geolocation
145
+ ],
146
+ shodan: [
147
+ :enrich_ports,
148
+ :enrich_cpes,
149
+ :enrich_reverse_dns
150
+ ],
151
+ google_public_dns: [
152
+ :enrich_dns
153
+ ]
154
+ }.freeze
155
+
156
+ #
157
+ # Enrich by name of enricher
158
+ #
159
+ # @param [String] enricher
160
+ #
161
+ def enrich_by_enricher(enricher)
162
+ methods = ENRICH_METHODS_BY_ENRICHER[enricher.downcase.to_sym] || []
163
+ methods.each do |method|
164
+ send(method) if respond_to?(method)
165
+ end
166
+ end
167
+
138
168
  private
139
169
 
140
170
  def normalize_as_domain(url_or_domain)
@@ -13,14 +13,7 @@ module Mihari
13
13
  # @return [Array<Mihari::DnsRecord>]
14
14
  #
15
15
  def build_by_domain(domain)
16
- resource_types = [
17
- Resolv::DNS::Resource::IN::A,
18
- Resolv::DNS::Resource::IN::AAAA,
19
- Resolv::DNS::Resource::IN::CNAME,
20
- Resolv::DNS::Resource::IN::TXT,
21
- Resolv::DNS::Resource::IN::NS
22
- ]
23
-
16
+ resource_types = %w[A AAAA CNAME TXT NS]
24
17
  resource_types.map do |resource_type|
25
18
  get_values domain, resource_type
26
19
  rescue Resolv::ResolvError
@@ -31,20 +24,11 @@ module Mihari
31
24
  private
32
25
 
33
26
  def get_values(domain, resource_type)
34
- resources = Resolv::DNS.new.getresources(domain, resource_type)
35
- resource_name = resource_type.to_s.split("::").last
27
+ response = Enrichers::GooglePublicDNS.query(domain, resource_type)
28
+ answers = response.answers || []
36
29
 
37
- resources.filter_map do |resource|
38
- # A, AAAA
39
- if resource.respond_to?(:address)
40
- new(resource: resource_name, value: resource.address.to_s)
41
- # CNAME, NS
42
- elsif resource.respond_to?(:name)
43
- new(resource: resource_name, value: resource.name.to_s)
44
- # TXT
45
- elsif resource.respond_to?(:data)
46
- new(resource: resource_name, value: resource.data.to_s)
47
- end
30
+ answers.filter_map do |answer|
31
+ new(resource: answer.resource_type, value: answer.data)
48
32
  end
49
33
  end
50
34
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "whois-parser"
4
-
5
3
  module Mihari
6
4
  class WhoisRecord < ActiveRecord::Base
7
5
  belongs_to :artifact
@@ -17,100 +15,7 @@ module Mihari
17
15
  # @return [WhoisRecord, nil]
18
16
  #
19
17
  def build_by_domain(domain)
20
- domain = PublicSuffix.domain(domain)
21
-
22
- # check memo
23
- if @memo.key?(domain)
24
- whois_record = @memo[domain]
25
- # return clone of the record
26
- return whois_record.dup
27
- end
28
-
29
- record = Whois.whois(domain)
30
- parser = record.parser
31
-
32
- return nil if parser.available?
33
-
34
- whois_record = new(
35
- domain: domain,
36
- created_on: get_created_on(parser),
37
- updated_on: get_updated_on(parser),
38
- expires_on: get_expires_on(parser),
39
- registrar: get_registrar(parser),
40
- contacts: get_contacts(parser)
41
- )
42
- # set memo
43
- @memo[domain] = whois_record
44
- whois_record
45
- rescue Whois::Error, Whois::ParserError, Timeout::Error
46
- nil
47
- end
48
-
49
- private
50
-
51
- #
52
- # Get created_on
53
- #
54
- # @param [::Whois::Parser:] parser
55
- #
56
- # @return [Date, nil]
57
- #
58
- def get_created_on(parser)
59
- parser.created_on
60
- rescue ::Whois::AttributeNotImplemented
61
- nil
62
- end
63
-
64
- #
65
- # Get updated_on
66
- #
67
- # @param [::Whois::Parser:] parser
68
- #
69
- # @return [Date, nil]
70
- #
71
- def get_updated_on(parser)
72
- parser.updated_on
73
- rescue ::Whois::AttributeNotImplemented
74
- nil
75
- end
76
-
77
- #
78
- # Get expires_on
79
- #
80
- # @param [::Whois::Parser:] parser
81
- #
82
- # @return [Date, nil]
83
- #
84
- def get_expires_on(parser)
85
- parser.expires_on
86
- rescue ::Whois::AttributeNotImplemented
87
- nil
88
- end
89
-
90
- #
91
- # Get registrar
92
- #
93
- # @param [::Whois::Parser:] parser
94
- #
95
- # @return [Hash, nil]
96
- #
97
- def get_registrar(parser)
98
- parser.registrar&.to_h
99
- rescue ::Whois::AttributeNotImplemented
100
- nil
101
- end
102
-
103
- #
104
- # Get contacts
105
- #
106
- # @param [::Whois::Parser:] parser
107
- #
108
- # @return [Array[Hash], nil]
109
- #
110
- def get_contacts(parser)
111
- parser.contacts.map(&:to_h)
112
- rescue ::Whois::AttributeNotImplemented
113
- nil
18
+ Enrichers::Whois.query domain
114
19
  end
115
20
  end
116
21
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Schemas
5
+ Enricher = Dry::Schema.Params do
6
+ required(:enricher).value(Types::EnricherTypes)
7
+ end
8
+ end
9
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "mihari/schemas/analyzer"
4
4
  require "mihari/schemas/emitter"
5
+ require "mihari/schemas/enricher"
5
6
 
6
7
  module Mihari
7
8
  module Schemas
@@ -20,6 +21,8 @@ module Mihari
20
21
 
21
22
  optional(:emitters).value(:array).each { Emitter | MISP | TheHive | Slack | HTTP }
22
23
 
24
+ optional(:enrichers).value(:array).each(Enricher)
25
+
23
26
  optional(:allowed_data_types).value(array[Types::DataTypes]).default(ALLOWED_DATA_TYPES)
24
27
  optional(:disallowed_data_values).value(array[:string]).default([])
25
28
 
@@ -35,6 +38,9 @@ module Mihari
35
38
  emitters = h[:emitters]
36
39
  h[:emitters] = emitters || DEFAULT_EMITTERS
37
40
 
41
+ enrichers = h[:enrichers]
42
+ h[:enrichers] = enrichers || DEFAULT_ENRICHERS
43
+
38
44
  h
39
45
  end
40
46
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Structs
5
+ module GooglePublicDNS
6
+ INT_TYPE_TO_TYPE = {
7
+ 1 => "A",
8
+ 2 => "NS",
9
+ 5 => "CNAME",
10
+ 16 => "TXT",
11
+ 28 => "AAAA"
12
+ }
13
+
14
+ class Answer < Dry::Struct
15
+ attribute :name, Types::String
16
+ attribute :data, Types::String
17
+ attribute :resource_type, Types::String
18
+
19
+ def self.from_dynamic!(d)
20
+ d = Types::Hash[d]
21
+ resource_type = INT_TYPE_TO_TYPE[d.fetch("type")]
22
+ new(
23
+ name: d.fetch("name"),
24
+ data: d.fetch("data"),
25
+ resource_type: resource_type
26
+ )
27
+ end
28
+ end
29
+
30
+ class Response < Dry::Struct
31
+ attribute :answers, Types.Array(Answer)
32
+
33
+ def self.from_dynamic!(d)
34
+ d = Types::Hash[d]
35
+ new(
36
+ answers: d.fetch("Answer", []).map { |x| Answer.from_dynamic!(x) }
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -88,7 +88,7 @@ module Mihari
88
88
 
89
89
  raise RuleValidationError, error_messages.join("\n") if errors?
90
90
 
91
- raise RuleValidationError, "Something wrong with queries or emitters." unless @no_method_error.nil?
91
+ raise RuleValidationError, "Something wrong with queries, emitters or enrichers." unless @no_method_error.nil?
92
92
  end
93
93
 
94
94
  def [](key)
@@ -150,6 +150,7 @@ module Mihari
150
150
  allowed_data_types: self[:allowed_data_types],
151
151
  disallowed_data_values: self[:disallowed_data_values],
152
152
  emitters: self[:emitters],
153
+ enrichers: self[:enrichers],
153
154
  id: id
154
155
  )
155
156
  analyzer.ignore_old_artifacts = self[:ignore_old_artifacts]
data/lib/mihari/types.rb CHANGED
@@ -21,5 +21,12 @@ module Mihari
21
21
  "database",
22
22
  "webhook"
23
23
  )
24
+
25
+ EnricherTypes = Types::String.enum(
26
+ "whois",
27
+ "ipinfo",
28
+ "shodan",
29
+ "google_public_dns"
30
+ )
24
31
  end
25
32
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "4.6.1"
4
+ VERSION = "4.7.0"
5
5
  end
data/lib/mihari.rb CHANGED
@@ -173,6 +173,7 @@ require "mihari/types"
173
173
  # Structs
174
174
  require "mihari/structs/alert"
175
175
  require "mihari/structs/censys"
176
+ require "mihari/structs/google_public_dns"
176
177
  require "mihari/structs/greynoise"
177
178
  require "mihari/structs/ipinfo"
178
179
  require "mihari/structs/onyphe"
@@ -189,8 +190,10 @@ require "mihari/schemas/rule"
189
190
 
190
191
  # Enrichers
191
192
  require "mihari/enrichers/base"
193
+ require "mihari/enrichers/google_public_dns"
192
194
  require "mihari/enrichers/ipinfo"
193
195
  require "mihari/enrichers/shodan"
196
+ require "mihari/enrichers/whois"
194
197
 
195
198
  # Models
196
199
  require "mihari/models/alert"
data/mihari.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 2.3"
31
31
  spec.add_development_dependency "coveralls_reborn", "~> 0.24"
32
- spec.add_development_dependency "fakefs", "~> 1.4"
32
+ spec.add_development_dependency "fakefs", "~> 1.5"
33
33
  spec.add_development_dependency "mysql2", "~> 0.5"
34
34
  spec.add_development_dependency "overcommit", "~> 0.59"
35
35
  spec.add_development_dependency "pg", "~> 1.3"
@@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency "rspec", "~> 3.11"
41
41
  spec.add_development_dependency "simplecov-lcov", "~> 0.8.0"
42
42
  spec.add_development_dependency "standard", "~> 1.12"
43
- spec.add_development_dependency "steep", "~> 0.52"
43
+ spec.add_development_dependency "steep", "~> 1.0"
44
44
  spec.add_development_dependency "timecop", "~> 0.9"
45
45
  spec.add_development_dependency "vcr", "~> 6.1"
46
46
  spec.add_development_dependency "webmock", "~> 3.14"
@@ -58,9 +58,9 @@ Gem::Specification.new do |spec|
58
58
  spec.add_dependency "dry-container", "0.9.0"
59
59
  spec.add_dependency "dry-files", "0.1.0"
60
60
  spec.add_dependency "dry-initializer", "3.1.1"
61
- spec.add_dependency "dry-schema", "1.9.1"
61
+ spec.add_dependency "dry-schema", "1.9.2"
62
62
  spec.add_dependency "dry-struct", "1.4.0"
63
- spec.add_dependency "dry-validation", "1.8.0"
63
+ spec.add_dependency "dry-validation", "1.8.1"
64
64
  spec.add_dependency "email_address", "0.2.3"
65
65
  spec.add_dependency "grape", "1.6.2"
66
66
  spec.add_dependency "grape-entity", "0.10.1"
@@ -84,7 +84,7 @@ Gem::Specification.new do |spec|
84
84
  spec.add_dependency "public_suffix", "4.0.7"
85
85
  spec.add_dependency "pulsedive", "0.1.5"
86
86
  spec.add_dependency "puma", "5.6.4"
87
- spec.add_dependency "rack", "2.2.3"
87
+ spec.add_dependency "rack", "2.2.3.1"
88
88
  spec.add_dependency "rack-contrib", "2.3.0"
89
89
  spec.add_dependency "rack-cors", "1.1.1"
90
90
  spec.add_dependency "securitytrails", "1.0.0"
@@ -0,0 +1,18 @@
1
+ module Mihari
2
+ module Enrichers
3
+ class GooglePublicDNS < Base
4
+ # @return [Boolean]
5
+ def valid?: () -> true
6
+
7
+ #
8
+ # Query Google Public DNS
9
+ #
10
+ # @param [String] name
11
+ # @param [String] resource_type
12
+ #
13
+ # @return [Mihari::Structs::Shodan::GooglePublicDNS::Response, nil]
14
+ #
15
+ def self.query: (String name, String resource_type) -> Mihari::Structs::Shodan::GooglePublicDNS::Response?
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module Mihari
2
+ module Structs
3
+ module GooglePublicDNS
4
+ INT_TYPE_TO_TYPE: { 1 => "A", 2 => "NS", 5 => "CNAME", 16 => "TXT", 28 => "AAAA" }
5
+
6
+ class Answer < Dry::Struct
7
+ attr_reader name: String
8
+ attr_reader data: String
9
+ attr_reader resource_type: String
10
+
11
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::GooglePublicDNS::Answer
12
+ end
13
+
14
+ class Response < Dry::Struct
15
+ attr_reader answers: Array[Mihari::Structs::GooglePublicDNS::Answer]
16
+
17
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::GooglePublicDNS::Response
18
+ end
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mihari
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.1
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-19 00:00:00.000000000 Z
11
+ date: 2022-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.4'
47
+ version: '1.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.4'
54
+ version: '1.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mysql2
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '0.52'
201
+ version: '1.0'
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: '0.52'
208
+ version: '1.0'
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: timecop
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -436,14 +436,14 @@ dependencies:
436
436
  requirements:
437
437
  - - '='
438
438
  - !ruby/object:Gem::Version
439
- version: 1.9.1
439
+ version: 1.9.2
440
440
  type: :runtime
441
441
  prerelease: false
442
442
  version_requirements: !ruby/object:Gem::Requirement
443
443
  requirements:
444
444
  - - '='
445
445
  - !ruby/object:Gem::Version
446
- version: 1.9.1
446
+ version: 1.9.2
447
447
  - !ruby/object:Gem::Dependency
448
448
  name: dry-struct
449
449
  requirement: !ruby/object:Gem::Requirement
@@ -464,14 +464,14 @@ dependencies:
464
464
  requirements:
465
465
  - - '='
466
466
  - !ruby/object:Gem::Version
467
- version: 1.8.0
467
+ version: 1.8.1
468
468
  type: :runtime
469
469
  prerelease: false
470
470
  version_requirements: !ruby/object:Gem::Requirement
471
471
  requirements:
472
472
  - - '='
473
473
  - !ruby/object:Gem::Version
474
- version: 1.8.0
474
+ version: 1.8.1
475
475
  - !ruby/object:Gem::Dependency
476
476
  name: email_address
477
477
  requirement: !ruby/object:Gem::Requirement
@@ -800,14 +800,14 @@ dependencies:
800
800
  requirements:
801
801
  - - '='
802
802
  - !ruby/object:Gem::Version
803
- version: 2.2.3
803
+ version: 2.2.3.1
804
804
  type: :runtime
805
805
  prerelease: false
806
806
  version_requirements: !ruby/object:Gem::Requirement
807
807
  requirements:
808
808
  - - '='
809
809
  - !ruby/object:Gem::Version
810
- version: 2.2.3
810
+ version: 2.2.3.1
811
811
  - !ruby/object:Gem::Dependency
812
812
  name: rack-contrib
813
813
  requirement: !ruby/object:Gem::Requirement
@@ -1110,8 +1110,10 @@ files:
1110
1110
  - lib/mihari/emitters/the_hive.rb
1111
1111
  - lib/mihari/emitters/webhook.rb
1112
1112
  - lib/mihari/enrichers/base.rb
1113
+ - lib/mihari/enrichers/google_public_dns.rb
1113
1114
  - lib/mihari/enrichers/ipinfo.rb
1114
1115
  - lib/mihari/enrichers/shodan.rb
1116
+ - lib/mihari/enrichers/whois.rb
1115
1117
  - lib/mihari/entities/alert.rb
1116
1118
  - lib/mihari/entities/artifact.rb
1117
1119
  - lib/mihari/entities/autonomous_system.rb
@@ -1153,11 +1155,13 @@ files:
1153
1155
  - lib/mihari/models/whois.rb
1154
1156
  - lib/mihari/schemas/analyzer.rb
1155
1157
  - lib/mihari/schemas/emitter.rb
1158
+ - lib/mihari/schemas/enricher.rb
1156
1159
  - lib/mihari/schemas/macros.rb
1157
1160
  - lib/mihari/schemas/rule.rb
1158
1161
  - lib/mihari/status.rb
1159
1162
  - lib/mihari/structs/alert.rb
1160
1163
  - lib/mihari/structs/censys.rb
1164
+ - lib/mihari/structs/google_public_dns.rb
1161
1165
  - lib/mihari/structs/greynoise.rb
1162
1166
  - lib/mihari/structs/ipinfo.rb
1163
1167
  - lib/mihari/structs/onyphe.rb
@@ -1243,6 +1247,7 @@ files:
1243
1247
  - sig/lib/mihari/emitters/the_hive.rbs
1244
1248
  - sig/lib/mihari/emitters/webhook.rbs
1245
1249
  - sig/lib/mihari/enrichers/base.rbs
1250
+ - sig/lib/mihari/enrichers/google_public_dns.rbs
1246
1251
  - sig/lib/mihari/enrichers/ipinfo.rbs
1247
1252
  - sig/lib/mihari/errors.rbs
1248
1253
  - sig/lib/mihari/feed/parser.rbs
@@ -1272,6 +1277,7 @@ files:
1272
1277
  - sig/lib/mihari/status.rbs
1273
1278
  - sig/lib/mihari/structs/alert.rbs
1274
1279
  - sig/lib/mihari/structs/censys.rbs
1280
+ - sig/lib/mihari/structs/google_public_dns.rbs
1275
1281
  - sig/lib/mihari/structs/greynoise.rbs
1276
1282
  - sig/lib/mihari/structs/ipinfo.rbs
1277
1283
  - sig/lib/mihari/structs/onyphe.rbs