mihari 5.4.2 → 5.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/frontend/package-lock.json +2399 -1504
  3. data/frontend/package.json +22 -22
  4. data/lib/mihari/analyzers/base.rb +25 -14
  5. data/lib/mihari/analyzers/binaryedge.rb +2 -48
  6. data/lib/mihari/analyzers/censys.rb +4 -20
  7. data/lib/mihari/analyzers/circl.rb +3 -27
  8. data/lib/mihari/analyzers/crtsh.rb +2 -17
  9. data/lib/mihari/analyzers/dnstwister.rb +2 -4
  10. data/lib/mihari/analyzers/greynoise.rb +5 -4
  11. data/lib/mihari/analyzers/hunterhow.rb +8 -23
  12. data/lib/mihari/analyzers/onyphe.rb +5 -39
  13. data/lib/mihari/analyzers/otx.rb +3 -39
  14. data/lib/mihari/analyzers/passivetotal.rb +4 -42
  15. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  16. data/lib/mihari/analyzers/rule.rb +18 -13
  17. data/lib/mihari/analyzers/securitytrails.rb +4 -42
  18. data/lib/mihari/analyzers/shodan.rb +7 -39
  19. data/lib/mihari/analyzers/urlscan.rb +3 -39
  20. data/lib/mihari/analyzers/virustotal.rb +1 -1
  21. data/lib/mihari/analyzers/virustotal_intelligence.rb +2 -25
  22. data/lib/mihari/analyzers/zoomeye.rb +18 -84
  23. data/lib/mihari/clients/base.rb +9 -1
  24. data/lib/mihari/clients/binaryedge.rb +26 -4
  25. data/lib/mihari/clients/censys.rb +32 -2
  26. data/lib/mihari/clients/circl.rb +28 -1
  27. data/lib/mihari/clients/crtsh.rb +7 -2
  28. data/lib/mihari/clients/dnstwister.rb +4 -2
  29. data/lib/mihari/clients/greynoise.rb +31 -4
  30. data/lib/mihari/clients/hunterhow.rb +41 -3
  31. data/lib/mihari/clients/onyphe.rb +25 -3
  32. data/lib/mihari/clients/otx.rb +40 -0
  33. data/lib/mihari/clients/passivetotal.rb +33 -15
  34. data/lib/mihari/clients/publsedive.rb +1 -1
  35. data/lib/mihari/clients/securitytrails.rb +44 -0
  36. data/lib/mihari/clients/shodan.rb +31 -3
  37. data/lib/mihari/clients/urlscan.rb +32 -6
  38. data/lib/mihari/clients/virustotal.rb +29 -4
  39. data/lib/mihari/clients/zoomeye.rb +53 -2
  40. data/lib/mihari/commands/alert.rb +42 -13
  41. data/lib/mihari/commands/rule.rb +11 -7
  42. data/lib/mihari/commands/search.rb +54 -22
  43. data/lib/mihari/commands/web.rb +1 -1
  44. data/lib/mihari/config.rb +6 -1
  45. data/lib/mihari/emitters/base.rb +9 -3
  46. data/lib/mihari/emitters/slack.rb +1 -1
  47. data/lib/mihari/enrichers/base.rb +13 -0
  48. data/lib/mihari/enrichers/google_public_dns.rb +16 -1
  49. data/lib/mihari/enrichers/ipinfo.rb +9 -13
  50. data/lib/mihari/enrichers/shodan.rb +1 -2
  51. data/lib/mihari/enrichers/whois.rb +2 -2
  52. data/lib/mihari/errors.rb +16 -10
  53. data/lib/mihari/feed/parser.rb +2 -2
  54. data/lib/mihari/models/artifact.rb +1 -1
  55. data/lib/mihari/models/autonomous_system.rb +11 -5
  56. data/lib/mihari/models/cpe.rb +10 -4
  57. data/lib/mihari/models/dns.rb +11 -16
  58. data/lib/mihari/models/geolocation.rb +11 -5
  59. data/lib/mihari/models/port.rb +10 -4
  60. data/lib/mihari/models/reverse_dns.rb +10 -4
  61. data/lib/mihari/models/whois.rb +4 -1
  62. data/lib/mihari/schemas/analyzer.rb +1 -0
  63. data/lib/mihari/services/alert_builder.rb +43 -0
  64. data/lib/mihari/services/alert_proxy.rb +7 -25
  65. data/lib/mihari/services/alert_runner.rb +9 -0
  66. data/lib/mihari/services/rule_builder.rb +47 -0
  67. data/lib/mihari/services/rule_proxy.rb +5 -61
  68. data/lib/mihari/services/rule_runner.rb +9 -4
  69. data/lib/mihari/structs/binaryedge.rb +89 -0
  70. data/lib/mihari/structs/censys.rb +11 -11
  71. data/lib/mihari/structs/greynoise.rb +17 -8
  72. data/lib/mihari/structs/onyphe.rb +7 -7
  73. data/lib/mihari/structs/shodan.rb +7 -6
  74. data/lib/mihari/structs/urlscan.rb +4 -6
  75. data/lib/mihari/structs/virustotal_intelligence.rb +4 -6
  76. data/lib/mihari/type_checker.rb +1 -1
  77. data/lib/mihari/version.rb +1 -1
  78. data/lib/mihari/web/endpoints/alerts.rb +33 -15
  79. data/lib/mihari/web/endpoints/artifacts.rb +53 -25
  80. data/lib/mihari/web/endpoints/configs.rb +2 -2
  81. data/lib/mihari/web/endpoints/ip_addresses.rb +3 -5
  82. data/lib/mihari/web/endpoints/rules.rb +97 -71
  83. data/lib/mihari/web/endpoints/tags.rb +15 -5
  84. data/lib/mihari/web/public/assets/index-ef33a6cd.js +1738 -0
  85. data/lib/mihari/web/public/index.html +1 -1
  86. data/lib/mihari/web/public/redoc-static.html +419 -382
  87. data/lib/mihari.rb +4 -0
  88. data/mihari.gemspec +10 -9
  89. metadata +38 -21
  90. data/lib/mihari/web/public/assets/index-4d7eda9f.js +0 -1738
@@ -7,6 +7,8 @@ module Mihari
7
7
  @memo = {}
8
8
 
9
9
  class << self
10
+ include Dry::Monads[:result]
11
+
10
12
  #
11
13
  # Build whois record
12
14
  #
@@ -15,7 +17,8 @@ module Mihari
15
17
  # @return [WhoisRecord, nil]
16
18
  #
17
19
  def build_by_domain(domain)
18
- Enrichers::Whois.query domain
20
+ result = Enrichers::Whois.query_result(domain)
21
+ result.value_or nil
19
22
  end
20
23
  end
21
24
  end
@@ -7,6 +7,7 @@ module Mihari
7
7
  optional(:pagination_limit).value(:integer).default(Mihari.config.pagination_limit)
8
8
  optional(:retry_times).value(:integer).default(Mihari.config.retry_times)
9
9
  optional(:retry_interval).value(:integer).default(Mihari.config.retry_interval)
10
+ optional(:ignore_error).value(:bool).default(Mihari.config.ignore_error)
10
11
  end
11
12
 
12
13
  AnalyzerWithoutAPIKey = Dry::Schema.Params do
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ require "erb"
6
+ require "pathname"
7
+ require "yaml"
8
+
9
+ module Mihari
10
+ module Services
11
+ class AlertBuilder
12
+ include Dry::Monads[:result, :try]
13
+
14
+ # @return [String]
15
+ attr_reader :path
16
+
17
+ #
18
+ # Initialize
19
+ #
20
+ # @param [String] path
21
+ #
22
+ def initialize(path)
23
+ @path = path
24
+ end
25
+
26
+ #
27
+ # @return [Hash]
28
+ #
29
+ def data
30
+ raise ArgumentError, "#{path} does not exist" unless Pathname(path).exist?
31
+
32
+ YAML.safe_load(
33
+ ERB.new(File.read(path)).result,
34
+ permitted_classes: [Date, Symbol]
35
+ )
36
+ end
37
+
38
+ def result
39
+ Try[StandardError] { AlertProxy.new(data) }.to_result
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json"
4
+
3
5
  module Mihari
4
6
  module Services
5
7
  class AlertProxy
@@ -16,10 +18,9 @@ module Mihari
16
18
  #
17
19
  def initialize(data)
18
20
  @data = data.deep_symbolize_keys
19
-
20
21
  @errors = nil
21
22
 
22
- validate
23
+ validate!
23
24
  end
24
25
 
25
26
  #
@@ -31,21 +32,14 @@ module Mihari
31
32
  !@errors.empty?
32
33
  end
33
34
 
34
- def validate
35
+ def validate!
35
36
  contract = Schemas::AlertContract.new
36
37
  result = contract.call(data)
37
38
 
38
39
  @data = result.to_h
39
40
  @errors = result.errors
40
- end
41
-
42
- def validate!
43
- return unless errors?
44
41
 
45
- Mihari.logger.error "Failed to parse the input as an alert:"
46
- Mihari.logger.error JSON.pretty_generate(errors.to_h)
47
-
48
- raise AlertValidationError, errors
42
+ raise ValidationError.new("Validation failed", errors) if errors?
49
43
  end
50
44
 
51
45
  def [](key)
@@ -74,7 +68,7 @@ module Mihari
74
68
  # @return [Mihari::Services::RuleProxy]
75
69
  #
76
70
  def rule
77
- @rule ||= Services::RuleProxy.from_model(Mihari::Rule.find(rule_id))
71
+ @rule ||= Services::RuleProxy.new(Mihari::Rule.find(rule_id).data)
78
72
  end
79
73
 
80
74
  class << self
@@ -86,19 +80,7 @@ module Mihari
86
80
  # @return [Mihari::Services::Alert]
87
81
  #
88
82
  def from_yaml(yaml)
89
- Services::AlertProxy.new YAML.safe_load(yaml, permitted_classes: [Date, Symbol])
90
- rescue Psych::SyntaxError => e
91
- raise YAMLSyntaxError, e.message
92
- end
93
-
94
- # @param [String] path
95
- #
96
- # @return [Mihari::Services::Alert, nil]
97
- #
98
- def from_path(path)
99
- return nil unless Pathname(path).exist?
100
-
101
- from_yaml File.read(path)
83
+ new YAML.safe_load(yaml, permitted_classes: [Date, Symbol])
102
84
  end
103
85
  end
104
86
  end
@@ -3,6 +3,8 @@
3
3
  module Mihari
4
4
  module Services
5
5
  class AlertRunner
6
+ include Dry::Monads[:result, :try]
7
+
6
8
  # @return [Mihari::Services::AlertProxy]
7
9
  attr_reader :alert
8
10
 
@@ -17,6 +19,13 @@ module Mihari
17
19
  emitter = Mihari::Emitters::Database.new(artifacts: alert.artifacts, rule: alert.rule)
18
20
  emitter.emit
19
21
  end
22
+
23
+ #
24
+ # @return [Dry::Monads::Result::Success<Mihari::Alert, nil>, Dry::Monads::Result::Failure]
25
+ #
26
+ def result
27
+ Try[StandardError] { run }.to_result
28
+ end
20
29
  end
21
30
  end
22
31
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "erb"
5
+ require "pathname"
6
+ require "yaml"
7
+
8
+ module Mihari
9
+ module Services
10
+ class RuleBuilder
11
+ include Dry::Monads[:result, :try]
12
+
13
+ # @return [String]
14
+ attr_reader :path_or_id
15
+
16
+ #
17
+ # Initialize
18
+ #
19
+ # @param [String] path_or_id
20
+ #
21
+ def initialize(path_or_id)
22
+ @path_or_id = path_or_id
23
+ end
24
+
25
+ #
26
+ # @return [Hash]
27
+ #
28
+ def data
29
+ if Mihari::Rule.exists?(path_or_id)
30
+ rule = Mihari::Rule.find(path_or_id)
31
+ return rule.data
32
+ end
33
+
34
+ raise ArgumentError, "#{path_or_id} does not exist" unless Pathname(path_or_id).exist?
35
+
36
+ YAML.safe_load(
37
+ ERB.new(File.read(path_or_id)).result,
38
+ permitted_classes: [Date, Symbol]
39
+ )
40
+ end
41
+
42
+ def result
43
+ Try[StandardError] { RuleProxy.new(data) }.to_result
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,11 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "date"
4
- require "erb"
5
3
  require "json"
6
- require "pathname"
7
- require "securerandom"
8
- require "yaml"
9
4
 
10
5
  module Mihari
11
6
  module Services
@@ -29,10 +24,9 @@ module Mihari
29
24
  #
30
25
  def initialize(data)
31
26
  @data = data.deep_symbolize_keys
32
-
33
27
  @errors = nil
34
28
 
35
- validate
29
+ validate!
36
30
  end
37
31
 
38
32
  #
@@ -44,21 +38,14 @@ module Mihari
44
38
  !@errors.empty?
45
39
  end
46
40
 
47
- def validate
41
+ def validate!
48
42
  contract = Schemas::RuleContract.new
49
43
  result = contract.call(data)
50
44
 
51
45
  @data = result.to_h
52
46
  @errors = result.errors
53
- end
54
47
 
55
- def validate!
56
- return unless errors?
57
-
58
- Mihari.logger.error "Failed to parse the input as a rule:"
59
- Mihari.logger.error JSON.pretty_generate(errors.to_h)
60
-
61
- raise RuleValidationError, errors
48
+ raise ValidationError.new("Validation failed", errors) if errors?
62
49
  end
63
50
 
64
51
  def [](key)
@@ -178,9 +165,7 @@ module Mihari
178
165
  # @return [Mihari::Services::Rule]
179
166
  #
180
167
  def from_yaml(yaml)
181
- Services::RuleProxy.new YAML.safe_load(ERB.new(yaml).result, permitted_classes: [Date, Symbol])
182
- rescue Psych::SyntaxError => e
183
- raise YAMLSyntaxError, e.message
168
+ new YAML.safe_load(ERB.new(yaml).result, permitted_classes: [Date, Symbol])
184
169
  end
185
170
 
186
171
  #
@@ -189,48 +174,7 @@ module Mihari
189
174
  # @return [Mihari::Services::Rule]
190
175
  #
191
176
  def from_model(model)
192
- Services::RuleProxy.new model.data
193
- end
194
-
195
- #
196
- # Load a rule from path
197
- #
198
- # @param [String] path
199
- #
200
- # @return [Mihari::Services::Rule, nil]
201
- #
202
- def from_path(path)
203
- return nil unless Pathname(path).exist?
204
-
205
- from_yaml File.read(path)
206
- end
207
-
208
- #
209
- # Load a rule from DB
210
- #
211
- # @param [String] id
212
- #
213
- # @return [Mihari::Services::Rule, nil]
214
- #
215
- def from_id(id)
216
- return nil unless Mihari::Rule.exists?(id)
217
-
218
- Services::RuleProxy.from_model Mihari::Rule.find(id)
219
- end
220
-
221
- #
222
- # @param [String] path_or_id Path to YAML file or YAML string or ID of a rule in the database
223
- #
224
- # @return [Mihari::Services::Rule]
225
- #
226
- def from_path_or_id(path_or_id)
227
- rule = from_path(path_or_id)
228
- return rule unless rule.nil?
229
-
230
- rule = from_id(path_or_id)
231
- return rule unless rule.nil?
232
-
233
- raise ArgumentError, "#{path_or_id} does not exist"
177
+ new model.data
234
178
  end
235
179
  end
236
180
  end
@@ -3,6 +3,8 @@
3
3
  module Mihari
4
4
  module Services
5
5
  class RuleRunner
6
+ include Dry::Monads[:result, :try]
7
+
6
8
  include Mixins::ErrorNotification
7
9
 
8
10
  # @return [Mihari::Services::RuleProxy]
@@ -38,11 +40,14 @@ module Mihari
38
40
  # @return [Mihari::Alert, nil]
39
41
  #
40
42
  def run
41
- analyzer = rule.analyzer
43
+ rule.analyzer.run
44
+ end
42
45
 
43
- with_error_notification do
44
- analyzer.run
45
- end
46
+ #
47
+ # @return [Dry::Monads::Result::Success<Mihari::Alert, nil>, Dry::Monads::Result::Failure]
48
+ #
49
+ def result
50
+ Try[StandardError] { run }.to_result
46
51
  end
47
52
  end
48
53
  end
@@ -0,0 +1,89 @@
1
+ module Mihari
2
+ module Structs
3
+ module BinaryEdge
4
+ class Target < Dry::Struct
5
+ attribute :ip, Types::String
6
+
7
+ #
8
+ # @return [String]
9
+ #
10
+ def ip
11
+ attributes[:ip]
12
+ end
13
+
14
+ class << self
15
+ def from_dynamic!(d)
16
+ d = Types::Hash[d]
17
+ new(
18
+ ip: d.fetch("ip")
19
+ )
20
+ end
21
+ end
22
+ end
23
+
24
+ class Event < Dry::Struct
25
+ attribute :target, Target
26
+
27
+ #
28
+ # @return [Target]
29
+ #
30
+ def target
31
+ attributes[:target]
32
+ end
33
+
34
+ class << self
35
+ def from_dynamic!(d)
36
+ d = Types::Hash[d]
37
+ new(
38
+ target: Target.from_dynamic!(d.fetch("target"))
39
+ )
40
+ end
41
+ end
42
+ end
43
+
44
+ class Response < Dry::Struct
45
+ # @!attribute [r] page
46
+ # @return [Integer]
47
+ attribute :page, Types::Integer
48
+
49
+ # @!attribute [r] pagesize
50
+ # @return [Integer]
51
+ attribute :pagesize, Types::Integer
52
+
53
+ # @!attribute [r] total
54
+ # @return [Integer]
55
+ attribute :total, Types::Integer
56
+
57
+ # @!attribute [r] events
58
+ # @return [Array<Event>]
59
+ attribute :events, Types.Array(Event)
60
+
61
+ #
62
+ # @return [Array<Event>]
63
+ #
64
+ def events
65
+ attributes[:events]
66
+ end
67
+
68
+ #
69
+ # @return [Array<Artifact>]
70
+ #
71
+ def artifacts
72
+ events.map { |event| Artifact.new(data: event.target.ip) }
73
+ end
74
+
75
+ class << self
76
+ def from_dynamic!(d)
77
+ d = Types::Hash[d]
78
+ new(
79
+ page: d.fetch("page"),
80
+ pagesize: d.fetch("pagesize"),
81
+ total: d.fetch("total"),
82
+ events: d.fetch("events").map { |x| Event.from_dynamic!(x) }
83
+ )
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -18,7 +18,7 @@ module Mihari
18
18
  #
19
19
  # @return [Mihari::AutonomousSystem]
20
20
  #
21
- def to_as
21
+ def as
22
22
  Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
23
23
  end
24
24
 
@@ -58,7 +58,7 @@ module Mihari
58
58
  #
59
59
  # @return [Mihari::Geolocation] <description>
60
60
  #
61
- def to_geolocation
61
+ def geolocation
62
62
  # sometimes Censys overlooks country
63
63
  # then set geolocation as nil
64
64
  return nil if country.nil?
@@ -98,7 +98,7 @@ module Mihari
98
98
  #
99
99
  # @return [Mihari::Port]
100
100
  #
101
- def to_port
101
+ def _port
102
102
  Port.new(port: port)
103
103
  end
104
104
 
@@ -162,20 +162,20 @@ module Mihari
162
162
  #
163
163
  # @return [Array<Mihari::Port>]
164
164
  #
165
- def to_ports
166
- services.map(&:to_port)
165
+ def ports
166
+ services.map(&:_port)
167
167
  end
168
168
 
169
169
  #
170
170
  # @return [Mihari::Artifact]
171
171
  #
172
- def to_artifact
172
+ def artifact
173
173
  Artifact.new(
174
174
  data: ip,
175
175
  metadata: metadata,
176
- autonomous_system: autonomous_system.to_as,
177
- geolocation: location.to_geolocation,
178
- ports: to_ports
176
+ autonomous_system: autonomous_system.as,
177
+ geolocation: location.geolocation,
178
+ ports: ports
179
179
  )
180
180
  end
181
181
 
@@ -269,8 +269,8 @@ module Mihari
269
269
  #
270
270
  # @return [Array<Mihari::Artifact>]
271
271
  #
272
- def to_artifacts
273
- hits.map(&:to_artifact)
272
+ def artifacts
273
+ hits.map(&:artifact)
274
274
  end
275
275
 
276
276
  class << self
@@ -34,14 +34,14 @@ module Mihari
34
34
  #
35
35
  # @return [Mihari::AutonomousSystem]
36
36
  #
37
- def to_as
37
+ def as
38
38
  Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
39
39
  end
40
40
 
41
41
  #
42
42
  # @return [Mihari::Geolocation]
43
43
  #
44
- def to_geolocation
44
+ def geolocation
45
45
  Mihari::Geolocation.new(
46
46
  country: country,
47
47
  country_code: country_code
@@ -94,12 +94,12 @@ module Mihari
94
94
  #
95
95
  # @return [Mihari::Artifact]
96
96
  #
97
- def to_artifact
97
+ def artifact
98
98
  Mihari::Artifact.new(
99
99
  data: ip,
100
100
  metadata: metadata_,
101
- autonomous_system: metadata.to_as,
102
- geolocation: metadata.to_geolocation
101
+ autonomous_system: metadata.as,
102
+ geolocation: metadata.geolocation
103
103
  )
104
104
  end
105
105
 
@@ -126,6 +126,7 @@ module Mihari
126
126
  attribute :data, Types.Array(Datum)
127
127
  attribute :message, Types::String
128
128
  attribute :query, Types::String
129
+ attribute :scroll, Types::String.optional
129
130
 
130
131
  #
131
132
  # @return [Boolean]
@@ -162,11 +163,18 @@ module Mihari
162
163
  attributes[:query]
163
164
  end
164
165
 
166
+ #
167
+ # @return [String, nil]
168
+ #
169
+ def scroll
170
+ attributes[:scroll]
171
+ end
172
+
165
173
  #
166
174
  # @return [Array<Mihari::Artifact>]
167
175
  #
168
- def to_artifacts
169
- data.map { |datum| datum.to_artifact }
176
+ def artifacts
177
+ data.map(&:artifact)
170
178
  end
171
179
 
172
180
  class << self
@@ -182,7 +190,8 @@ module Mihari
182
190
  count: d.fetch("count"),
183
191
  data: d.fetch("data").map { |x| Datum.from_dynamic!(x) },
184
192
  message: d.fetch("message"),
185
- query: d.fetch("query")
193
+ query: d.fetch("query"),
194
+ scroll: d["scroll"]
186
195
  )
187
196
  end
188
197
  end
@@ -42,19 +42,19 @@ module Mihari
42
42
  #
43
43
  # @return [Mihari::Artifact]
44
44
  #
45
- def to_artifact
45
+ def artifact
46
46
  Mihari::Artifact.new(
47
47
  data: ip,
48
48
  metadata: metadata,
49
- autonomous_system: to_as,
50
- geolocation: to_geolocation
49
+ autonomous_system: as,
50
+ geolocation: geolocation
51
51
  )
52
52
  end
53
53
 
54
54
  #
55
55
  # @return [Mihari::Geolocation, nil]
56
56
  #
57
- def to_geolocation
57
+ def geolocation
58
58
  return nil if country_code.nil?
59
59
 
60
60
  Mihari::Geolocation.new(
@@ -66,7 +66,7 @@ module Mihari
66
66
  #
67
67
  # @return [Mihari::AutonomousSystem]
68
68
  #
69
- def to_as
69
+ def as
70
70
  Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
71
71
  end
72
72
 
@@ -150,8 +150,8 @@ module Mihari
150
150
  #
151
151
  # @return [Array<Mihari::Artifact>]
152
152
  #
153
- def to_artifacts
154
- results.map(&:to_artifact)
153
+ def artifacts
154
+ results.map(&:artifact)
155
155
  end
156
156
 
157
157
  class << self
@@ -24,7 +24,7 @@ module Mihari
24
24
  #
25
25
  # @return [Mihari::Geolocation, nil]
26
26
  #
27
- def to_geolocation
27
+ def geolocation
28
28
  return nil if country_name.nil? && country_code.nil?
29
29
 
30
30
  Mihari::Geolocation.new(
@@ -105,7 +105,7 @@ module Mihari
105
105
  #
106
106
  # @return [Mihari::AutonomousSystem, nil]
107
107
  #
108
- def to_asn
108
+ def _asn
109
109
  return nil if asn.nil?
110
110
 
111
111
  Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
@@ -140,7 +140,7 @@ module Mihari
140
140
  end
141
141
  end
142
142
 
143
- class Result < Dry::Struct
143
+ class Response < Dry::Struct
144
144
  attribute :matches, Types.Array(Match)
145
145
  attribute :total, Types::Int
146
146
 
@@ -194,9 +194,10 @@ module Mihari
194
194
  #
195
195
  # @return [Array<Mihari::Artifact>]
196
196
  #
197
- def to_artifacts
197
+ def artifacts
198
198
  matches.map do |match|
199
199
  metadata = collect_metadata_by_ip(match.ip_str)
200
+
200
201
  ports = collect_ports_by_ip(match.ip_str).map do |port|
201
202
  Mihari::Port.new(port: port)
202
203
  end
@@ -207,8 +208,8 @@ module Mihari
207
208
  Mihari::Artifact.new(
208
209
  data: match.ip_str,
209
210
  metadata: metadata,
210
- autonomous_system: match.to_asn,
211
- geolocation: match.location.to_geolocation,
211
+ autonomous_system: match._asn,
212
+ geolocation: match.location.geolocation,
212
213
  ports: ports,
213
214
  reverse_dns_names: reverse_dns_names
214
215
  )
@@ -83,11 +83,9 @@ module Mihari
83
83
  #
84
84
  # @return [Array<Mihari::Artifact>]
85
85
  #
86
- def to_artifacts
86
+ def artifacts
87
87
  values = [page.url, page.domain, page.ip].compact
88
- values.map do |value|
89
- Mihari::Artifact.new(data: value, metadata: metadata)
90
- end
88
+ values.map { |value| Mihari::Artifact.new(data: value, metadata: metadata) }
91
89
  end
92
90
 
93
91
  class << self
@@ -129,8 +127,8 @@ module Mihari
129
127
  #
130
128
  # @return [Array<Mihari::Artifact>]
131
129
  #
132
- def to_artifacts
133
- results.map(&:to_artifacts).flatten
130
+ def artifacts
131
+ results.map(&:artifacts).flatten
134
132
  end
135
133
 
136
134
  class << self