mihari 4.8.0 → 4.10.0

Sign up to get free protection for your applications and to get access to all the features.
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