mihari 4.8.0 → 4.10.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: 3e827da38142045be9b680636eb69b61d18e465b83f33d3a2a435c251041c7fc
4
- data.tar.gz: 91d0c1fa7e50512c9a2bb8aceb914f69bec149c3fd7dc16f136a4b391a086e56
3
+ metadata.gz: 54ef0421cb5da34c8174fe0fdc3b43d310770dca779dd51fac284a678b86fc0a
4
+ data.tar.gz: 6b24c7b37c00f7ebed9ee0fcfbfb66b95d7d60ea7c7792a40be32607bdda07fe
5
5
  SHA512:
6
- metadata.gz: c6c06c7d217091158d3fc354ccf3e0640494cfcd26b38cf5927d4d2a43f961ce8d2bf7d87bc965037554e745bf54b7dcf06e02b96d93962e6b0948bff11119d7
7
- data.tar.gz: 5dd97d8c4a4d9ae9eac0e3823e8da97210de5dae87c448f48f6df565a12c99e7f0620d0477862762465aa77b0727912ccc935cd941e9a291a48a763fbf9ab8f3
6
+ metadata.gz: 941a6e47d53a2287d793fe28fab3e6e9295076ed39e50fcf8f55e6cdca102381ae425b3db603acdfea9b28e438a7f57627ed793be1efcb0093d83b17ac128535
7
+ data.tar.gz: 25055c04746f33620e0c762f1d79d6407d8a9156d47820c2129ed4b72e926e7cf2d3ea275ff546046bb5b9ce82fe069b222d56f5b69700eb44179f83d80c058c
data/README.md CHANGED
@@ -44,7 +44,6 @@ Mihari supports the following services by default.
44
44
  - [Pulsedive](https://pulsedive.com/)
45
45
  - [SecurityTrails](https://securitytrails.com/)
46
46
  - [Shodan](https://shodan.io)
47
- - [Spyse](https://spyse.com)
48
47
  - [urlscan.io](https://urlscan.io)
49
48
  - [VirusTotal](http://virustotal.com) & [VirusTotal Intelligence](https://www.virustotal.com/gui/intelligence-overview)
50
49
  - [ZoomEye](https://zoomeye.org)
@@ -72,10 +72,22 @@ module Mihari
72
72
  #
73
73
  # @param [Mihari::Emitters::Base] emitter
74
74
  #
75
- # @return [nil]
75
+ # @return [Mihari::Alert, nil]
76
76
  #
77
77
  def run_emitter(emitter)
78
- emitter.run(title: title, description: description, artifacts: enriched_artifacts, source: source, tags: tags)
78
+ return if enriched_artifacts.empty?
79
+
80
+ alert_or_something = emitter.run(
81
+ title: title,
82
+ description: description,
83
+ artifacts: enriched_artifacts,
84
+ source: source,
85
+ tags: tags
86
+ )
87
+
88
+ Mihari.logger.info "Emission by #{emitter.class} is succedded"
89
+
90
+ alert_or_something
79
91
  rescue StandardError => e
80
92
  Mihari.logger.info "Emission by #{emitter.class} is failed: #{e}"
81
93
  end
@@ -18,7 +18,6 @@ module Mihari
18
18
  "pulsedive" => Pulsedive,
19
19
  "securitytrails" => SecurityTrails,
20
20
  "shodan" => Shodan,
21
- "spyse" => Spyse,
22
21
  "st" => SecurityTrails,
23
22
  "urlscan" => Urlscan,
24
23
  "virustotal_intelligence" => VirusTotalIntelligence,
@@ -14,7 +14,11 @@ module Mihari
14
14
  rule = Structs::Rule.from_path_or_id path_or_id
15
15
 
16
16
  # validate
17
- rule.validate!
17
+ begin
18
+ rule.validate!
19
+ rescue RuleValidationError
20
+ return
21
+ end
18
22
 
19
23
  # check update
20
24
  id = rule.id
@@ -23,7 +27,9 @@ module Mihari
23
27
  with_db_connection do
24
28
  rule_ = Mihari::Rule.find(id)
25
29
  next if rule.yaml == rule_.yaml
26
- return unless yes?("This operation will overwrite the rule in the database (Rule ID: #{id}). Are you sure you want to update the rule? (yes/no)")
30
+ unless yes?("This operation will overwrite the rule in the database (Rule ID: #{id}). Are you sure you want to update the rule? (yes/no)")
31
+ return
32
+ end
27
33
  rescue ActiveRecord::RecordNotFound
28
34
  next
29
35
  end
@@ -38,7 +44,7 @@ module Mihari
38
44
  data = Mihari::Entities::Alert.represent(alert)
39
45
  puts JSON.pretty_generate(data.as_json)
40
46
  else
41
- Mihari.logger.info "There is no new artifact"
47
+ Mihari.logger.info "No new alert created in the database"
42
48
  end
43
49
 
44
50
  # record a rule
@@ -6,7 +6,7 @@ module Mihari
6
6
  module Emitters
7
7
  class MISP < Base
8
8
  # @return [String, nil]
9
- attr_reader :api_endpoint
9
+ attr_reader :url
10
10
 
11
11
  # @return [String, nil]
12
12
  attr_reader :api_key
@@ -14,18 +14,29 @@ module Mihari
14
14
  def initialize(*args, **kwargs)
15
15
  super(*args, **kwargs)
16
16
 
17
- @api_endpoint = kwargs[:api_endpoint] || Mihari.config.misp_api_endpoint
17
+ @url = kwargs[:url] || kwargs[:api_endpoint] || Mihari.config.misp_url
18
18
  @api_key = kwargs[:api_key] || Mihari.config.misp_api_key
19
19
 
20
20
  ::MISP.configure do |config|
21
- config.api_endpoint = api_endpoint
21
+ config.api_endpoint = url
22
22
  config.api_key = api_key
23
23
  end
24
24
  end
25
25
 
26
26
  # @return [Boolean]
27
27
  def valid?
28
- api_endpoint? && api_key? && ping?
28
+ unless url? && api_key?
29
+ Mihari.logger.info("MISP URL is not set") unless url?
30
+ Mihari.logger.info("MISP API key is not set") unless api_key?
31
+ return false
32
+ end
33
+
34
+ unless ping?
35
+ Mihari.logger.info("MISP URL (#{url}) is not reachable")
36
+ return false
37
+ end
38
+
39
+ true
29
40
  end
30
41
 
31
42
  def emit(title:, artifacts:, tags: [], **_options)
@@ -47,7 +58,7 @@ module Mihari
47
58
  private
48
59
 
49
60
  def configuration_keys
50
- %w[misp_api_endpoint misp_api_key]
61
+ %w[misp_url misp_api_key]
51
62
  end
52
63
 
53
64
  #
@@ -103,12 +114,12 @@ module Mihari
103
114
  end
104
115
 
105
116
  #
106
- # Check whether an API endpoint is set or not
117
+ # Check whether a URL is set or not
107
118
  #
108
119
  # @return [Boolean]
109
120
  #
110
- def api_endpoint?
111
- !api_endpoint.nil? && !api_endpoint.empty?
121
+ def url?
122
+ !url.nil? && !url.empty?
112
123
  end
113
124
 
114
125
  #
@@ -121,15 +132,15 @@ module Mihari
121
132
  end
122
133
 
123
134
  #
124
- # Check whether an API endpoint is reachable or not
135
+ # Check whether a URL is reachable or not
125
136
  #
126
137
  # @return [Boolean]
127
138
  #
128
139
  def ping?
129
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
130
- url = "#{base_url}/users/login"
140
+ base_url = url.end_with?("/") ? url[0..-2] : url
141
+ login_url = "#{base_url}/users/login"
131
142
 
132
- http = Net::Ping::HTTP.new(url)
143
+ http = Net::Ping::HTTP.new(login_url)
133
144
  http.ping?
134
145
  end
135
146
  end
@@ -6,7 +6,7 @@ module Mihari
6
6
  module Emitters
7
7
  class TheHive < Base
8
8
  # @return [String, nil]
9
- attr_reader :api_endpoint
9
+ attr_reader :url
10
10
 
11
11
  # @return [String, nil]
12
12
  attr_reader :api_key
@@ -17,14 +17,25 @@ module Mihari
17
17
  def initialize(*args, **kwargs)
18
18
  super(*args, **kwargs)
19
19
 
20
- @api_endpoint = kwargs[:api_endpoint] || Mihari.config.thehive_api_endpoint
20
+ @url = kwargs[:url] || kwargs[:api_endpoint] || Mihari.config.thehive_url
21
21
  @api_key = kwargs[:api_key] || Mihari.config.thehive_api_key
22
22
  @api_version = kwargs[:api_version] || Mihari.config.thehive_api_version
23
23
  end
24
24
 
25
25
  # @return [Boolean]
26
26
  def valid?
27
- api_endpont? && api_key? && ping?
27
+ unless url? && api_key?
28
+ Mihari.logger.info("TheHive URL is not set") unless url?
29
+ Mihari.logger.info("TheHive API key is not set") unless api_key?
30
+ return false
31
+ end
32
+
33
+ unless ping?
34
+ Mihari.logger.info("TheHive URL (#{url}) is not reachable")
35
+ return false
36
+ end
37
+
38
+ true
28
39
  end
29
40
 
30
41
  def emit(title:, description:, artifacts:, tags: [], **_options)
@@ -57,20 +68,20 @@ module Mihari
57
68
  private
58
69
 
59
70
  def configuration_keys
60
- %w[thehive_api_endpoint thehive_api_key]
71
+ %w[thehive_url thehive_api_key]
61
72
  end
62
73
 
63
74
  def api
64
- @api ||= Hachi::API.new(api_endpoint: api_endpoint, api_key: api_key, api_version: normalized_api_version)
75
+ @api ||= Hachi::API.new(api_endpoint: url, api_key: api_key, api_version: normalized_api_version)
65
76
  end
66
77
 
67
78
  #
68
- # Check whether an API endpoint is set or not
79
+ # Check whether a URL is set or not
69
80
  #
70
81
  # @return [Boolean]
71
82
  #
72
- def api_endpont?
73
- !api_endpoint.nil?
83
+ def url?
84
+ !url.nil?
74
85
  end
75
86
 
76
87
  #
@@ -83,7 +94,10 @@ module Mihari
83
94
  end
84
95
 
85
96
  def payload(title:, description:, artifacts:, tags: [])
86
- return v4_payload(title: title, description: description, artifacts: artifacts, tags: tags) if normalized_api_version.nil?
97
+ if normalized_api_version.nil?
98
+ return v4_payload(title: title, description: description, artifacts: artifacts,
99
+ tags: tags)
100
+ end
87
101
 
88
102
  v5_payload(title: title, description: description, artifacts: artifacts, tags: tags)
89
103
  end
@@ -92,7 +106,9 @@ module Mihari
92
106
  {
93
107
  title: title,
94
108
  description: description,
95
- artifacts: artifacts.map { |artifact| { data: artifact.data, data_type: artifact.data_type, message: description } },
109
+ artifacts: artifacts.map do |artifact|
110
+ { data: artifact.data, data_type: artifact.data_type, message: description }
111
+ end,
96
112
  tags: tags,
97
113
  type: "external",
98
114
  source: "mihari"
@@ -103,7 +119,9 @@ module Mihari
103
119
  {
104
120
  title: title,
105
121
  description: description,
106
- observables: artifacts.map { |artifact| { data: artifact.data, data_type: artifact.data_type, message: description } },
122
+ observables: artifacts.map do |artifact|
123
+ { data: artifact.data, data_type: artifact.data_type, message: description }
124
+ end,
107
125
  tags: tags,
108
126
  type: "external",
109
127
  source: "mihari",
@@ -112,23 +130,23 @@ module Mihari
112
130
  end
113
131
 
114
132
  #
115
- # Check whether an API endpoint is reachable or not
133
+ # Check whether a URL is reachable or not
116
134
  #
117
135
  # @return [Boolean]
118
136
  #
119
137
  def ping?
120
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
138
+ base_url = url.end_with?("/") ? url[0..-2] : url
121
139
 
122
140
  if normalized_api_version.nil?
123
141
  # for v4
124
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
125
- url = "#{base_url}/index.html"
142
+ base_url = url.end_with?("/") ? url[0..-2] : url
143
+ public_url = "#{base_url}/index.html"
126
144
  else
127
145
  # for v5
128
- url = "#{base_url}/api/v1/status/public"
146
+ public_url = "#{base_url}/api/v1/status/public"
129
147
  end
130
148
 
131
- http = Net::Ping::HTTP.new(url)
149
+ http = Net::Ping::HTTP.new(public_url)
132
150
 
133
151
  # use GET for v5
134
152
  http.get_request = true if normalized_api_version
@@ -58,13 +58,6 @@ module Mihari
58
58
  optional(:options).hash(AnalyzerOptions)
59
59
  end
60
60
 
61
- Spyse = Dry::Schema.Params do
62
- required(:analyzer).value(Types::String.enum("spyse"))
63
- required(:query).value(:string)
64
- required(:type).value(Types::String.enum("ip", "domain"))
65
- optional(:options).hash(AnalyzerOptions)
66
- end
67
-
68
61
  ZoomEye = Dry::Schema.Params do
69
62
  required(:analyzer).value(Types::String.enum("zoomeye"))
70
63
  required(:query).value(:string)
@@ -9,12 +9,14 @@ module Mihari
9
9
  MISP = Dry::Schema.Params do
10
10
  required(:emitter).value(Types::String.enum("misp"))
11
11
  optional(:api_endpoint).value(:string)
12
+ optional(:url).value(:string)
12
13
  optional(:api_key).value(:string)
13
14
  end
14
15
 
15
16
  TheHive = Dry::Schema.Params do
16
17
  required(:emitter).value(Types::String.enum("the_hive"))
17
18
  optional(:api_endpoint).value(:string)
19
+ optional(:url).value(:string)
18
20
  optional(:api_key).value(:string)
19
21
  optional(:api_version).value(Types::String.enum("v4", "v5")).default("v4")
20
22
  end
@@ -22,7 +22,9 @@ module Mihari
22
22
  optional(:created_on).value(:date)
23
23
  optional(:updated_on).value(:date)
24
24
 
25
- required(:queries).value(:array).each { AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | Spyse | ZoomEye | Urlscan | Crtsh | Feed }
25
+ required(:queries).value(:array).each do
26
+ AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | ZoomEye | Urlscan | Crtsh | Feed
27
+ end
26
28
 
27
29
  optional(:emitters).value(:array).each { Emitter | MISP | TheHive | Slack | HTTP }
28
30
 
@@ -57,9 +59,7 @@ module Mihari
57
59
 
58
60
  rule(:disallowed_data_values) do
59
61
  value.each do |v|
60
- unless valid_disallowed_data_value?(v)
61
- key.failure("#{v} is not a valid format.")
62
- end
62
+ key.failure("#{v} is not a valid format.") unless valid_disallowed_data_value?(v)
63
63
  end
64
64
  end
65
65
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "4.8.0"
4
+ VERSION = "4.10.0"
5
5
  end
data/lib/mihari.rb CHANGED
@@ -84,7 +84,8 @@ module Mihari
84
84
 
85
85
  setting :ipinfo_api_key, default: ENV.fetch("IPINFO_API_KEY", nil)
86
86
 
87
- setting :misp_api_endpoint, default: ENV.fetch("MISP_API_ENDPOINT", nil)
87
+ # TODO: deprecate MISP_API_ENDPOINT
88
+ setting :misp_url, default: ENV.fetch("MISP_URL", nil) || ENV.fetch("MISP_API_ENDPOINT", nil)
88
89
  setting :misp_api_key, default: ENV.fetch("MISP_API_KEY", nil)
89
90
 
90
91
  setting :onyphe_api_key, default: ENV.fetch("ONYPHE_API_KEY", nil)
@@ -105,7 +106,8 @@ module Mihari
105
106
 
106
107
  setting :spyse_api_key, default: ENV.fetch("SPYSE_API_KEY", nil)
107
108
 
108
- setting :thehive_api_endpoint, default: ENV.fetch("THEHIVE_API_ENDPOINT", nil)
109
+ # TODO: deprecate THEHIVE_API_ENDPOINT
110
+ setting :thehive_url, default: ENV.fetch("THEHIVE_URL", nil) || ENV.fetch("THEHIVE_API_ENDPOINT", nil)
109
111
  setting :thehive_api_key, default: ENV.fetch("THEHIVE_API_KEY", nil)
110
112
  setting :thehive_api_version, default: ENV.fetch("THEHIVE_API_VERSION", nil)
111
113
 
@@ -235,7 +237,6 @@ require "mihari/analyzers/passivetotal"
235
237
  require "mihari/analyzers/pulsedive"
236
238
  require "mihari/analyzers/securitytrails"
237
239
  require "mihari/analyzers/shodan"
238
- require "mihari/analyzers/spyse"
239
240
  require "mihari/analyzers/urlscan"
240
241
  require "mihari/analyzers/virustotal_intelligence"
241
242
  require "mihari/analyzers/virustotal"
data/mihari.gemspec CHANGED
@@ -40,12 +40,12 @@ 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.16"
43
- spec.add_development_dependency "steep", "~> 1.1"
43
+ spec.add_development_dependency "steep", "~> 1.2"
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.18"
47
47
 
48
- spec.add_dependency "activerecord", "7.0.3.1"
48
+ spec.add_dependency "activerecord", "7.0.4"
49
49
  spec.add_dependency "addressable", "2.8.1"
50
50
  spec.add_dependency "awrence", "2.0.1"
51
51
  spec.add_dependency "binaryedge", "0.1.0"
@@ -54,11 +54,11 @@ Gem::Specification.new do |spec|
54
54
  spec.add_dependency "dnpedia", "0.1.0"
55
55
  spec.add_dependency "dnstwister", "0.1.0"
56
56
  spec.add_dependency "dotenv", "2.8.1"
57
- spec.add_dependency "dry-configurable", "0.15.0"
58
- spec.add_dependency "dry-container", "0.10.1"
59
- spec.add_dependency "dry-files", "0.2.0"
57
+ spec.add_dependency "dry-configurable", "0.16.0"
58
+ spec.add_dependency "dry-container", "0.11.0"
59
+ spec.add_dependency "dry-files", "0.3.0"
60
60
  spec.add_dependency "dry-initializer", "3.1.1"
61
- spec.add_dependency "dry-schema", "1.10.2"
61
+ spec.add_dependency "dry-schema", "1.10.6"
62
62
  spec.add_dependency "dry-struct", "1.4.0"
63
63
  spec.add_dependency "dry-validation", "1.8.1"
64
64
  spec.add_dependency "email_address", "0.2.4"
@@ -88,16 +88,15 @@ Gem::Specification.new do |spec|
88
88
  spec.add_dependency "rack-cors", "1.1.1"
89
89
  spec.add_dependency "securitytrails", "1.0.0"
90
90
  spec.add_dependency "semantic_logger", "4.11.0"
91
- spec.add_dependency "sentry-ruby", "5.4.2"
91
+ spec.add_dependency "sentry-ruby", "5.5.0"
92
92
  spec.add_dependency "shodanx", "0.2.1"
93
93
  spec.add_dependency "slack-notifier", "2.4.0"
94
- spec.add_dependency "spysex", "0.2.0"
95
- spec.add_dependency "sqlite3", "1.4.4"
94
+ spec.add_dependency "sqlite3", "1.5.0"
96
95
  spec.add_dependency "thor", "1.2.1"
97
96
  spec.add_dependency "urlscan", "0.8.0"
98
97
  spec.add_dependency "uuidtools", "2.2.0"
99
98
  spec.add_dependency "virustotalx", "1.2.0"
100
99
  spec.add_dependency "whois", "5.1.0"
101
- spec.add_dependency "whois-parser", "1.2.0"
100
+ spec.add_dependency "whois-parser", "2.0.0"
102
101
  spec.add_dependency "zoomeye-rb", "0.2.0"
103
102
  end
@@ -2,7 +2,7 @@ module Mihari
2
2
  module Emitters
3
3
  class MISP < Base
4
4
 
5
- attr_reader api_endpiont: String?
5
+ attr_reader url: String?
6
6
 
7
7
  attr_reader api_key: String?
8
8
 
@@ -16,7 +16,7 @@ module Mihari
16
16
 
17
17
  private
18
18
 
19
- def configuration_keys: () -> ::Array["misp_api_endpoint" | "misp_api_key"]
19
+ def configuration_keys: () -> ::Array["misp_url" | "misp_api_key"]
20
20
 
21
21
  def build_attribute: (Mihari::Artifact artifact) -> untyped
22
22
 
@@ -24,7 +24,7 @@ module Mihari
24
24
 
25
25
  def to_misp_type: (type: String `type`, value: String value) -> String?
26
26
 
27
- def api_endpoint?: () -> bool
27
+ def url?: () -> bool
28
28
 
29
29
  def api_key?: () -> bool
30
30
 
@@ -1,7 +1,7 @@
1
1
  module Mihari
2
2
  module Emitters
3
3
  class TheHive < Base
4
- attr_reader api_endpiont: String?
4
+ attr_reader url: String?
5
5
 
6
6
  attr_reader api_key: String?
7
7
 
@@ -16,12 +16,12 @@ module Mihari
16
16
 
17
17
  private
18
18
 
19
- def configuration_keys: () -> ::Array["thehive_api_endpoint" | "thehive_api_key"]
19
+ def configuration_keys: () -> ::Array["thehive_url" | "thehive_api_key"]
20
20
 
21
21
  def api: () -> untyped
22
22
 
23
23
  # @return [true, false]
24
- def api_endpont?: () -> bool
24
+ def url?: () -> bool
25
25
 
26
26
  # @return [true, false]
27
27
  def api_key?: () -> bool
data/sig/lib/mihari.rbs CHANGED
@@ -5,7 +5,7 @@ class Configuration
5
5
  attr_accessor circl_passive_password (): String?
6
6
  attr_accessor circl_passive_username (): String?
7
7
  attr_accessor ipinfo_api_key (): String?
8
- attr_accessor misp_api_endpoint (): String?
8
+ attr_accessor misp_url (): String?
9
9
  attr_accessor misp_api_key (): String?
10
10
  attr_accessor onyphe_api_key (): String?
11
11
  attr_accessor otx_api_key (): String?
@@ -17,7 +17,7 @@ class Configuration
17
17
  attr_accessor slack_channel (): String?
18
18
  attr_accessor slack_webhook_url (): String?
19
19
  attr_accessor spyse_api_key (): String?
20
- attr_accessor thehive_api_endpoint (): String?
20
+ attr_accessor thehive_url (): String?
21
21
  attr_accessor thehive_api_key (): String?
22
22
  attr_accessor thehive_api_version (): String?
23
23
  attr_accessor urlscan_api_key (): String?
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.8.0
4
+ version: 4.10.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-08-28 00:00:00.000000000 Z
11
+ date: 2022-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '1.1'
201
+ version: '1.2'
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: '1.1'
208
+ version: '1.2'
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: timecop
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -254,14 +254,14 @@ dependencies:
254
254
  requirements:
255
255
  - - '='
256
256
  - !ruby/object:Gem::Version
257
- version: 7.0.3.1
257
+ version: 7.0.4
258
258
  type: :runtime
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - '='
263
263
  - !ruby/object:Gem::Version
264
- version: 7.0.3.1
264
+ version: 7.0.4
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: addressable
267
267
  requirement: !ruby/object:Gem::Requirement
@@ -380,42 +380,42 @@ dependencies:
380
380
  requirements:
381
381
  - - '='
382
382
  - !ruby/object:Gem::Version
383
- version: 0.15.0
383
+ version: 0.16.0
384
384
  type: :runtime
385
385
  prerelease: false
386
386
  version_requirements: !ruby/object:Gem::Requirement
387
387
  requirements:
388
388
  - - '='
389
389
  - !ruby/object:Gem::Version
390
- version: 0.15.0
390
+ version: 0.16.0
391
391
  - !ruby/object:Gem::Dependency
392
392
  name: dry-container
393
393
  requirement: !ruby/object:Gem::Requirement
394
394
  requirements:
395
395
  - - '='
396
396
  - !ruby/object:Gem::Version
397
- version: 0.10.1
397
+ version: 0.11.0
398
398
  type: :runtime
399
399
  prerelease: false
400
400
  version_requirements: !ruby/object:Gem::Requirement
401
401
  requirements:
402
402
  - - '='
403
403
  - !ruby/object:Gem::Version
404
- version: 0.10.1
404
+ version: 0.11.0
405
405
  - !ruby/object:Gem::Dependency
406
406
  name: dry-files
407
407
  requirement: !ruby/object:Gem::Requirement
408
408
  requirements:
409
409
  - - '='
410
410
  - !ruby/object:Gem::Version
411
- version: 0.2.0
411
+ version: 0.3.0
412
412
  type: :runtime
413
413
  prerelease: false
414
414
  version_requirements: !ruby/object:Gem::Requirement
415
415
  requirements:
416
416
  - - '='
417
417
  - !ruby/object:Gem::Version
418
- version: 0.2.0
418
+ version: 0.3.0
419
419
  - !ruby/object:Gem::Dependency
420
420
  name: dry-initializer
421
421
  requirement: !ruby/object:Gem::Requirement
@@ -436,14 +436,14 @@ dependencies:
436
436
  requirements:
437
437
  - - '='
438
438
  - !ruby/object:Gem::Version
439
- version: 1.10.2
439
+ version: 1.10.6
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.10.2
446
+ version: 1.10.6
447
447
  - !ruby/object:Gem::Dependency
448
448
  name: dry-struct
449
449
  requirement: !ruby/object:Gem::Requirement
@@ -856,14 +856,14 @@ dependencies:
856
856
  requirements:
857
857
  - - '='
858
858
  - !ruby/object:Gem::Version
859
- version: 5.4.2
859
+ version: 5.5.0
860
860
  type: :runtime
861
861
  prerelease: false
862
862
  version_requirements: !ruby/object:Gem::Requirement
863
863
  requirements:
864
864
  - - '='
865
865
  - !ruby/object:Gem::Version
866
- version: 5.4.2
866
+ version: 5.5.0
867
867
  - !ruby/object:Gem::Dependency
868
868
  name: shodanx
869
869
  requirement: !ruby/object:Gem::Requirement
@@ -892,34 +892,20 @@ dependencies:
892
892
  - - '='
893
893
  - !ruby/object:Gem::Version
894
894
  version: 2.4.0
895
- - !ruby/object:Gem::Dependency
896
- name: spysex
897
- requirement: !ruby/object:Gem::Requirement
898
- requirements:
899
- - - '='
900
- - !ruby/object:Gem::Version
901
- version: 0.2.0
902
- type: :runtime
903
- prerelease: false
904
- version_requirements: !ruby/object:Gem::Requirement
905
- requirements:
906
- - - '='
907
- - !ruby/object:Gem::Version
908
- version: 0.2.0
909
895
  - !ruby/object:Gem::Dependency
910
896
  name: sqlite3
911
897
  requirement: !ruby/object:Gem::Requirement
912
898
  requirements:
913
899
  - - '='
914
900
  - !ruby/object:Gem::Version
915
- version: 1.4.4
901
+ version: 1.5.0
916
902
  type: :runtime
917
903
  prerelease: false
918
904
  version_requirements: !ruby/object:Gem::Requirement
919
905
  requirements:
920
906
  - - '='
921
907
  - !ruby/object:Gem::Version
922
- version: 1.4.4
908
+ version: 1.5.0
923
909
  - !ruby/object:Gem::Dependency
924
910
  name: thor
925
911
  requirement: !ruby/object:Gem::Requirement
@@ -996,14 +982,14 @@ dependencies:
996
982
  requirements:
997
983
  - - '='
998
984
  - !ruby/object:Gem::Version
999
- version: 1.2.0
985
+ version: 2.0.0
1000
986
  type: :runtime
1001
987
  prerelease: false
1002
988
  version_requirements: !ruby/object:Gem::Requirement
1003
989
  requirements:
1004
990
  - - '='
1005
991
  - !ruby/object:Gem::Version
1006
- version: 1.2.0
992
+ version: 2.0.0
1007
993
  - !ruby/object:Gem::Dependency
1008
994
  name: zoomeye-rb
1009
995
  requirement: !ruby/object:Gem::Requirement
@@ -1074,7 +1060,6 @@ files:
1074
1060
  - lib/mihari/analyzers/rule.rb
1075
1061
  - lib/mihari/analyzers/securitytrails.rb
1076
1062
  - lib/mihari/analyzers/shodan.rb
1077
- - lib/mihari/analyzers/spyse.rb
1078
1063
  - lib/mihari/analyzers/urlscan.rb
1079
1064
  - lib/mihari/analyzers/virustotal.rb
1080
1065
  - lib/mihari/analyzers/virustotal_intelligence.rb
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spyse"
4
-
5
- module Mihari
6
- module Analyzers
7
- class Spyse < Base
8
- param :query
9
-
10
- option :type, default: proc { "domain" }
11
-
12
- # @return [String, nil]
13
- attr_reader :api_key
14
-
15
- def initialize(*args, **kwargs)
16
- super(*args, **kwargs)
17
-
18
- @api_key = kwargs[:api_key] || Mihari.config.spyse_api_key
19
- end
20
-
21
- def artifacts
22
- search || []
23
- end
24
-
25
- private
26
-
27
- def search_params
28
- @search_params ||= JSON.parse(query)
29
- end
30
-
31
- def configuration_keys
32
- %w[spyse_api_key]
33
- end
34
-
35
- def api
36
- @api ||= ::Spyse::API.new(api_key)
37
- end
38
-
39
- #
40
- # Check whether a type is valid or not
41
- #
42
- # @return [Boolean]
43
- #
44
- def valid_type?
45
- %w[ip domain cert].include? type
46
- end
47
-
48
- #
49
- # Domain search
50
- #
51
- # @return [Array<Mihari::Artifact>]
52
- #
53
- def domain_search
54
- res = api.domain.search(search_params, limit: 100)
55
- items = res.dig("data", "items") || []
56
- items.map do |item|
57
- data = item["name"]
58
- Artifact.new(data: data, source: source, metadata: item)
59
- end
60
- end
61
-
62
- #
63
- # IP search
64
- #
65
- # @return [Array<Mihari::Artifact>]
66
- #
67
- def ip_search
68
- res = api.ip.search(search_params, limit: 100)
69
- items = res.dig("data", "items") || []
70
- items.map do |item|
71
- data = item["ip"]
72
- Artifact.new(data: data, source: source, metadata: item)
73
- end
74
- end
75
-
76
- #
77
- # IP/domain search
78
- #
79
- # @return [Array<Mihari::Artifact>]
80
- #
81
- def search
82
- case type
83
- when "domain"
84
- domain_search
85
- when "ip"
86
- ip_search
87
- else
88
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
89
- end
90
- end
91
- end
92
- end
93
- end