mihari 5.0.1 → 5.1.1

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/docker/Dockerfile +1 -1
  4. data/lib/mihari/analyzers/binaryedge.rb +9 -7
  5. data/lib/mihari/analyzers/censys.rb +3 -5
  6. data/lib/mihari/analyzers/circl.rb +4 -6
  7. data/lib/mihari/analyzers/crtsh.rb +6 -7
  8. data/lib/mihari/analyzers/dnpedia.rb +3 -7
  9. data/lib/mihari/analyzers/dnstwister.rb +3 -5
  10. data/lib/mihari/analyzers/feed.rb +12 -10
  11. data/lib/mihari/analyzers/greynoise.rb +3 -5
  12. data/lib/mihari/analyzers/onyphe.rb +3 -4
  13. data/lib/mihari/analyzers/otx.rb +1 -3
  14. data/lib/mihari/analyzers/passivetotal.rb +5 -7
  15. data/lib/mihari/analyzers/pulsedive.rb +5 -7
  16. data/lib/mihari/analyzers/shodan.rb +3 -9
  17. data/lib/mihari/analyzers/urlscan.rb +7 -6
  18. data/lib/mihari/analyzers/virustotal.rb +4 -6
  19. data/lib/mihari/analyzers/virustotal_intelligence.rb +4 -5
  20. data/lib/mihari/analyzers/zoomeye.rb +4 -10
  21. data/lib/mihari/cli/database.rb +11 -0
  22. data/lib/mihari/cli/main.rb +10 -4
  23. data/lib/mihari/cli/rule.rb +11 -0
  24. data/lib/mihari/clients/base.rb +53 -0
  25. data/lib/mihari/clients/binaryedge.rb +33 -0
  26. data/lib/mihari/clients/censys.rb +42 -0
  27. data/lib/mihari/clients/circl.rb +59 -0
  28. data/lib/mihari/clients/crtsh.rb +31 -0
  29. data/lib/mihari/clients/dnpedia.rb +64 -0
  30. data/lib/mihari/clients/dnstwister.rb +40 -0
  31. data/lib/mihari/clients/greynoise.rb +29 -0
  32. data/lib/mihari/clients/misp.rb +24 -0
  33. data/lib/mihari/clients/onyphe.rb +23 -0
  34. data/lib/mihari/clients/otx.rb +29 -0
  35. data/lib/mihari/clients/passivetotal.rb +65 -0
  36. data/lib/mihari/clients/publsedive.rb +39 -0
  37. data/lib/mihari/clients/shodan.rb +30 -0
  38. data/lib/mihari/clients/the_hive.rb +28 -0
  39. data/lib/mihari/clients/urlscan.rb +31 -0
  40. data/lib/mihari/clients/virustotal.rb +56 -0
  41. data/lib/mihari/clients/zoomeye.rb +68 -0
  42. data/lib/mihari/commands/database.rb +28 -0
  43. data/lib/mihari/commands/{initializer.rb → rule.rb} +27 -6
  44. data/lib/mihari/commands/searcher.rb +5 -0
  45. data/lib/mihari/database.rb +8 -22
  46. data/lib/mihari/emitters/misp.rb +13 -20
  47. data/lib/mihari/emitters/the_hive.rb +3 -5
  48. data/lib/mihari/emitters/webhook.rb +2 -2
  49. data/lib/mihari/feed/reader.rb +14 -11
  50. data/lib/mihari/http.rb +29 -21
  51. data/lib/mihari/mixins/database.rb +2 -0
  52. data/lib/mihari/mixins/retriable.rb +3 -1
  53. data/lib/mihari/schemas/analyzer.rb +5 -4
  54. data/lib/mihari/version.rb +1 -1
  55. data/lib/mihari.rb +21 -0
  56. data/mihari.gemspec +14 -20
  57. metadata +61 -238
  58. data/lib/mihari/analyzers/clients/otx.rb +0 -36
  59. data/lib/mihari/commands/validator.rb +0 -31
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Clients
5
+ class ZoomEye < Base
6
+ attr_reader :api_key
7
+
8
+ def initialize(base_url = "https://api.zoomeye.org", api_key:, headers: {})
9
+ raise(ArgumentError, "'api_key' argument is required") unless api_key
10
+
11
+ headers["api-key"] = api_key
12
+ super(base_url, headers: headers)
13
+ end
14
+
15
+ #
16
+ # Search the Host devices
17
+ #
18
+ # @param [String] query Query string
19
+ # @param [Integer, nil] page The page number to paging(default:1)
20
+ # @param [String, nil] facets A comma-separated list of properties to get summary information on query
21
+ #
22
+ # @return [Hash]
23
+ #
24
+ def host_search(query, page: nil, facets: nil)
25
+ params = {
26
+ query: query,
27
+ page: page,
28
+ facets: facets
29
+ }.compact
30
+
31
+ _get("/host/search", params: params)
32
+ end
33
+
34
+ #
35
+ # Search the Web technologies
36
+ #
37
+ # @param [String] query Query string
38
+ # @param [Integer, nil] page The page number to paging(default:1)
39
+ # @param [String, nil] facets A comma-separated list of properties to get summary information on query
40
+ #
41
+ # @return [Hash]
42
+ #
43
+ def web_search(query, page: nil, facets: nil)
44
+ params = {
45
+ query: query,
46
+ page: page,
47
+ facets: facets
48
+ }.compact
49
+
50
+ _get("/web/search", params: params)
51
+ end
52
+
53
+ private
54
+
55
+ #
56
+ #
57
+ # @param [String] path
58
+ # @param [Hash] params
59
+ #
60
+ def _get(path, params: {})
61
+ res = get(path, params: params)
62
+ JSON.parse(res.body.to_s)
63
+ rescue HTTPError
64
+ nil
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Commands
5
+ module Database
6
+ include Mixins::Database
7
+
8
+ def self.included(thor)
9
+ thor.class_eval do
10
+ desc "migrate", "Migrate DB schemas"
11
+ method_option :verbose, type: :boolean, default: true
12
+ #
13
+ # @param [String] direction
14
+ #
15
+ #
16
+ def migrate(direction = "up")
17
+ verbose = options["verbose"]
18
+ ActiveRecord::Migration.verbose = verbose
19
+
20
+ with_db_connection do
21
+ Mihari::Database.migrate(direction.to_sym)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,20 +4,41 @@ require "pathname"
4
4
 
5
5
  module Mihari
6
6
  module Commands
7
- module Initializer
7
+ module Rule
8
8
  def self.included(thor)
9
9
  thor.class_eval do
10
- desc "init", "Initialize a new rule"
11
- method_option :path, type: :string, default: "./rule.yml"
12
- def init
13
- path = options["path"]
10
+ desc "validate [PATH]", "Validate a rule file"
11
+ #
12
+ # Validate format of a rule
13
+ #
14
+ # @param [String] path
15
+ #
16
+ def validate(path)
17
+ rule = Structs::Rule.from_path_or_id(path)
14
18
 
19
+ begin
20
+ rule.validate!
21
+ Mihari.logger.info "Valid format. The input is parsed as the following:"
22
+ Mihari.logger.info rule.data.to_yaml
23
+ rescue RuleValidationError
24
+ nil
25
+ end
26
+ end
27
+
28
+ desc "init [PATH]", "Initialize a new rule file"
29
+ #
30
+ # Initialize a new rule file
31
+ #
32
+ # @param [String] path
33
+ #
34
+ #
35
+ def init(path = "./rule.yml")
15
36
  warning = "#{path} exists. Do you want to overwrite it? (y/n)"
16
37
  return if Pathname(path).exist? && !(yes? warning)
17
38
 
18
39
  initialize_rule path
19
40
 
20
- Mihari.logger.info "A new rule is initialized as #{path}."
41
+ Mihari.logger.info "A new rule is initialized: #{path}."
21
42
  end
22
43
 
23
44
  no_commands do
@@ -10,6 +10,11 @@ module Mihari
10
10
  thor.class_eval do
11
11
  desc "search [PATH]", "Search by a rule"
12
12
  method_option :force_overwrite, type: :boolean, aliases: "-f", desc: "Force an overwrite the rule"
13
+ #
14
+ # Search by a rule
15
+ #
16
+ # @param [String] path_or_id
17
+ #
13
18
  def search(path_or_id)
14
19
  with_db_connection do
15
20
  rule = Structs::Rule.from_path_or_id path_or_id
@@ -9,10 +9,6 @@ def env
9
9
  ENV["APP_ENV"] || ENV["RACK_ENV"]
10
10
  end
11
11
 
12
- def test_env?
13
- env == "test"
14
- end
15
-
16
12
  def development_env?
17
13
  env == "development"
18
14
  end
@@ -121,22 +117,24 @@ def adapter
121
117
  "sqlite3"
122
118
  end
123
119
 
120
+ #
121
+ # @return [Array<ActiveRecord::Migration>] schemas
122
+ #
123
+ def schemas
124
+ [V5Schema]
125
+ end
126
+
124
127
  module Mihari
125
128
  class Database
126
129
  class << self
127
- include Memist::Memoizable
128
-
129
130
  #
130
131
  # DB migraration
131
132
  #
132
133
  # @param [Symbol] direction
133
134
  #
134
135
  def migrate(direction)
135
- ActiveRecord::Migration.verbose = false
136
-
137
- [V5Schema].each { |schema| schema.migrate direction }
136
+ schemas.each { |schema| schema.migrate direction }
138
137
  end
139
- memoize :migrate unless test_env?
140
138
 
141
139
  #
142
140
  # Establish DB connection
@@ -153,10 +151,7 @@ module Mihari
153
151
  database: Mihari.config.database_url.path[1..]
154
152
  )
155
153
  end
156
-
157
154
  ActiveRecord::Base.logger = Logger.new($stdout) if development_env?
158
-
159
- migrate :up
160
155
  rescue StandardError => e
161
156
  Mihari.logger.error e
162
157
  end
@@ -169,15 +164,6 @@ module Mihari
169
164
 
170
165
  ActiveRecord::Base.clear_active_connections!
171
166
  end
172
-
173
- #
174
- # Destory DB
175
- #
176
- def destroy!
177
- return unless ActiveRecord::Base.connected?
178
-
179
- migrate :down
180
- end
181
167
  end
182
168
  end
183
169
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "misp"
4
-
5
3
  module Mihari
6
4
  module Emitters
7
5
  class MISP < Base
@@ -16,11 +14,6 @@ module Mihari
16
14
 
17
15
  @url = kwargs[:url] || Mihari.config.misp_url
18
16
  @api_key = kwargs[:api_key] || Mihari.config.misp_api_key
19
-
20
- ::MISP.configure do |config|
21
- config.api_endpoint = url
22
- config.api_key = api_key
23
- end
24
17
  end
25
18
 
26
19
  # @return [Boolean]
@@ -50,17 +43,13 @@ module Mihari
50
43
  def emit(rule:, artifacts:, **_options)
51
44
  return if artifacts.empty?
52
45
 
53
- event = ::MISP::Event.new(info: rule.title)
54
-
55
- artifacts.each do |artifact|
56
- event.attributes << build_attribute(artifact)
57
- end
58
-
59
- rule.tags.each do |tag|
60
- event.add_tag name: tag
61
- end
62
-
63
- event.create
46
+ client.create_event({
47
+ Event: {
48
+ info: rule.title
49
+ },
50
+ Attribute: artifacts.map { |artifact| build_attribute(artifact) },
51
+ Tag: rule.tags.map { |tag| { name: tag } }
52
+ })
64
53
  end
65
54
 
66
55
  private
@@ -69,15 +58,19 @@ module Mihari
69
58
  %w[misp_url misp_api_key]
70
59
  end
71
60
 
61
+ def client
62
+ @client ||= Clients::MISP.new(url, api_key: api_key)
63
+ end
64
+
72
65
  #
73
66
  # Build a MISP attribute
74
67
  #
75
68
  # @param [Mihari::Artifact] artifact
76
69
  #
77
- # @return [::MISP::Attribute]
70
+ # @return [Hash]
78
71
  #
79
72
  def build_attribute(artifact)
80
- ::MISP::Attribute.new(value: artifact.data, type: to_misp_type(type: artifact.data_type, value: artifact.data))
73
+ { value: artifact.data, type: to_misp_type(type: artifact.data_type, value: artifact.data) }
81
74
  end
82
75
 
83
76
  #
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "hachi"
4
-
5
3
  module Mihari
6
4
  module Emitters
7
5
  class TheHive < Base
@@ -50,7 +48,7 @@ module Mihari
50
48
  return if artifacts.empty?
51
49
 
52
50
  payload = payload(rule: rule, artifacts: artifacts)
53
- api.alert.create(**payload)
51
+ client.alert(payload)
54
52
  end
55
53
 
56
54
  #
@@ -79,8 +77,8 @@ module Mihari
79
77
  %w[thehive_url thehive_api_key]
80
78
  end
81
79
 
82
- def api
83
- @api ||= Hachi::API.new(api_endpoint: url, api_key: api_key, api_version: normalized_api_version)
80
+ def client
81
+ @client ||= Clients::TheHive.new(url, api_key: api_key, api_version: normalized_api_version)
84
82
  end
85
83
 
86
84
  #
@@ -77,13 +77,13 @@ module Mihari
77
77
  payload_ = payload_as_string(artifacts: artifacts, rule: rule)
78
78
  payload = JSON.parse(payload_)
79
79
 
80
- client = Mihari::HTTP.new(url, headers: headers, payload: payload)
80
+ client = Mihari::HTTP.new(url, headers: headers)
81
81
 
82
82
  case method
83
83
  when "GET"
84
84
  res = client.get
85
85
  when "POST"
86
- res = client.post
86
+ res = client.post(json: payload)
87
87
  end
88
88
 
89
89
  res
@@ -6,25 +6,28 @@ require "insensitive_hash"
6
6
  module Mihari
7
7
  module Feed
8
8
  class Reader
9
- attr_reader :uri, :http_request_headers, :http_request_method, :http_request_payload
9
+ attr_reader :url, :headers, :params, :json, :data, :method
10
10
 
11
- def initialize(uri, http_request_headers: {}, http_request_method: "GET", http_request_payload_type: nil, http_request_payload: {})
12
- @uri = Addressable::URI.parse(uri)
13
- @http_request_headers = http_request_headers.insensitive
14
- @http_request_method = http_request_method
15
- @http_request_payload = http_request_payload
11
+ def initialize(url, headers: {}, method: "GET", params: nil, json: nil, data: nil)
12
+ @url = Addressable::URI.parse(url)
13
+ @headers = headers.insensitive
14
+ @method = method
16
15
 
17
- http_request_headers["content-type"] = http_request_payload_type if http_request_payload_type
16
+ @params = params
17
+ @json = json
18
+ @data = data
19
+
20
+ headers["content-type"] = "application/json" unless json.nil?
18
21
  end
19
22
 
20
23
  def read
21
- return read_file(uri.path) if uri.scheme == "file"
24
+ return read_file(url.path) if url.scheme == "file"
22
25
 
23
26
  res = nil
24
- client = HTTP.new(uri, headers: http_request_headers, payload: http_request_payload)
27
+ client = HTTP.new(url, headers: headers)
25
28
 
26
- res = client.get if http_request_method == "GET"
27
- res = client.post if http_request_method == "POST"
29
+ res = client.get(params: params) if method == "GET"
30
+ res = client.post(params: params, json: json, data: data) if method == "POST"
28
31
 
29
32
  return [] if res.nil?
30
33
 
data/lib/mihari/http.rb CHANGED
@@ -4,54 +4,62 @@ require "insensitive_hash"
4
4
 
5
5
  module Mihari
6
6
  class HTTP
7
- attr_reader :url, :headers, :payload
7
+ # @return [String]
8
+ attr_reader :url
8
9
 
9
- def initialize(url, headers: {}, payload: {})
10
+ # @return [Hash]
11
+ attr_reader :headers
12
+
13
+ def initialize(url, headers: {})
10
14
  @url = url.is_a?(URI) ? url : URI(url.to_s)
11
15
  @headers = headers.insensitive
12
- @payload = payload
13
16
  end
14
17
 
15
18
  #
16
19
  # Make a GET request
17
20
  #
21
+ # @param [Hash, nil] params
22
+ #
18
23
  # @return [Net::HTTPResponse]
19
24
  #
20
- def get
25
+ def get(params: nil)
21
26
  new_url = url.deep_dup
22
- new_url.query = Addressable::URI.form_encode(payload) unless payload.empty?
27
+ new_url.query = Addressable::URI.form_encode(params) unless (params || {}).empty?
23
28
 
24
29
  get = Net::HTTP::Get.new(new_url)
25
30
  request get
26
31
  end
27
32
 
28
33
  #
29
- # Make a POST request
34
+ # Make a POST requesti
35
+ #
36
+ # @param [Hash, nil] params
37
+ # @param [Hash, nil] json
38
+ # @param [Hash, nil] data
30
39
  #
31
40
  # @return [Net::HTTPResponse]
32
41
  #
33
- def post
34
- post = Net::HTTP::Post.new(url)
35
-
36
- case content_type
37
- when "application/json"
38
- post.body = JSON.generate(payload)
39
- when "application/x-www-form-urlencoded"
40
- post.set_form_data(payload)
41
- end
42
+ def post(params: nil, json: nil, data: nil)
43
+ new_url = url.deep_dup
44
+ new_url.query = Addressable::URI.form_encode(params) unless (params || {}).empty?
45
+
46
+ post = Net::HTTP::Post.new(new_url)
47
+
48
+ post.body = JSON.generate(json) if json
49
+ post.set_form_data(data) if data
42
50
 
43
51
  request post
44
52
  end
45
53
 
46
54
  class << self
47
- def get(url, headers: {}, params: {})
48
- client = new(url, headers: headers, payload: params)
49
- client.get
55
+ def get(url, headers: {}, params: nil)
56
+ client = new(url, headers: headers)
57
+ client.get(params: params)
50
58
  end
51
59
 
52
- def post(url, headers: {}, payload: {})
53
- client = new(url, headers: headers, payload: payload)
54
- client.post
60
+ def post(url, headers: {}, params: nil, json: nil, data: nil)
61
+ client = new(url, headers: headers)
62
+ client.post(params: params, json: json, data: data)
55
63
  end
56
64
  end
57
65
 
@@ -6,6 +6,8 @@ module Mihari
6
6
  def with_db_connection
7
7
  Mihari::Database.connect
8
8
  yield
9
+ rescue ActiveRecord::StatementInvalid
10
+ Mihari.logger.error("You haven't finished the DB migration! Please run 'mihari db migrate'.")
9
11
  ensure
10
12
  Mihari::Database.close
11
13
  end
@@ -9,7 +9,9 @@ module Mihari
9
9
  Errno::EPIPE,
10
10
  OpenSSL::SSL::SSLError,
11
11
  Timeout::Error,
12
- RetryableError
12
+ RetryableError,
13
+ NetworkError,
14
+ TimeoutError
13
15
  ]
14
16
 
15
17
  #
@@ -82,10 +82,11 @@ module Mihari
82
82
  required(:analyzer).value(Types::String.enum("feed"))
83
83
  required(:query).value(:string)
84
84
  required(:selector).value(:string)
85
- optional(:http_request_method).value(Types::HTTPRequestMethods).default("GET")
86
- optional(:http_request_headers).value(:hash).default({})
87
- optional(:http_request_payload).value(:hash).default({})
88
- optional(:http_request_payload_type).value(Types::HTTPRequestPayloadTypes)
85
+ optional(:method).value(Types::HTTPRequestMethods).default("GET")
86
+ optional(:headers).value(:hash).default({})
87
+ optional(:params).value(:hash)
88
+ optional(:data).value(:hash)
89
+ optional(:json).value(:hash)
89
90
  optional(:options).hash(AnalyzerOptions)
90
91
  end
91
92
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "5.0.1"
4
+ VERSION = "5.1.1"
5
5
  end
data/lib/mihari.rb CHANGED
@@ -212,6 +212,27 @@ require "mihari/emitters/slack"
212
212
  require "mihari/emitters/the_hive"
213
213
  require "mihari/emitters/webhook"
214
214
 
215
+ # Clients
216
+ require "mihari/clients/base"
217
+
218
+ require "mihari/clients/binaryedge"
219
+ require "mihari/clients/censys"
220
+ require "mihari/clients/circl"
221
+ require "mihari/clients/crtsh"
222
+ require "mihari/clients/dnpedia"
223
+ require "mihari/clients/dnstwister"
224
+ require "mihari/clients/greynoise"
225
+ require "mihari/clients/misp"
226
+ require "mihari/clients/onyphe"
227
+ require "mihari/clients/otx"
228
+ require "mihari/clients/passivetotal"
229
+ require "mihari/clients/publsedive"
230
+ require "mihari/clients/shodan"
231
+ require "mihari/clients/the_hive"
232
+ require "mihari/clients/urlscan"
233
+ require "mihari/clients/virustotal"
234
+ require "mihari/clients/zoomeye"
235
+
215
236
  # Analyzers
216
237
  require "mihari/analyzers/base"
217
238
 
data/mihari.gemspec CHANGED
@@ -4,6 +4,11 @@ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "mihari/version"
6
6
 
7
+ def ci_env?
8
+ # CI=true in GitHub Actions
9
+ ENV["CI"]
10
+ end
11
+
7
12
  Gem::Specification.new do |spec|
8
13
  spec.name = "mihari"
9
14
  spec.version = Mihari::VERSION
@@ -30,8 +35,8 @@ Gem::Specification.new do |spec|
30
35
  spec.add_development_dependency "bundler", "~> 2.4"
31
36
  spec.add_development_dependency "coveralls_reborn", "~> 0.27"
32
37
  spec.add_development_dependency "fakefs", "~> 2.4"
38
+ spec.add_development_dependency "fuubar", "~> 2.5"
33
39
  spec.add_development_dependency "mysql2", "~> 0.5"
34
- spec.add_development_dependency "overcommit", "~> 0.60"
35
40
  spec.add_development_dependency "pg", "~> 1.4"
36
41
  spec.add_development_dependency "rack-test", "~> 2.0"
37
42
  spec.add_development_dependency "rake", "~> 13.0"
@@ -40,19 +45,19 @@ Gem::Specification.new do |spec|
40
45
  spec.add_development_dependency "rspec", "~> 3.12"
41
46
  spec.add_development_dependency "simplecov-lcov", "~> 0.8.0"
42
47
  spec.add_development_dependency "standard", "~> 1.24"
43
- spec.add_development_dependency "steep", "~> 1.3"
44
48
  spec.add_development_dependency "timecop", "~> 0.9"
45
49
  spec.add_development_dependency "vcr", "~> 6.1"
46
50
  spec.add_development_dependency "webmock", "~> 3.18"
47
51
 
52
+ unless ci_env?
53
+ spec.add_development_dependency "overcommit", "~> 0.60"
54
+ spec.add_development_dependency "ruby-lsp", "~> 0.4"
55
+ spec.add_development_dependency "steep", "~> 1.3"
56
+ end
57
+
48
58
  spec.add_dependency "activerecord", "7.0.4.2"
49
59
  spec.add_dependency "addressable", "2.8.1"
50
60
  spec.add_dependency "awrence", "2.0.1"
51
- spec.add_dependency "binaryedge", "0.1.0"
52
- spec.add_dependency "censysx", "0.1.1"
53
- spec.add_dependency "crtsh-rb", "0.3.1"
54
- spec.add_dependency "dnpedia", "0.1.0"
55
- spec.add_dependency "dnstwister", "0.1.0"
56
61
  spec.add_dependency "dotenv", "2.8.1"
57
62
  spec.add_dependency "dry-configurable", "1.0.1"
58
63
  spec.add_dependency "dry-container", "0.11.0"
@@ -66,37 +71,26 @@ Gem::Specification.new do |spec|
66
71
  spec.add_dependency "grape-entity", "1.0.0"
67
72
  spec.add_dependency "grape-swagger", "1.5.0"
68
73
  spec.add_dependency "grape-swagger-entity", "0.5.1"
69
- spec.add_dependency "greynoise", "0.1.1"
70
- spec.add_dependency "hachi", "2.0.0"
71
74
  spec.add_dependency "insensitive_hash", "0.3.3"
72
75
  spec.add_dependency "jr-cli", "0.6.0"
73
76
  spec.add_dependency "launchy", "2.5.2"
74
77
  spec.add_dependency "memist", "2.0.2"
75
- spec.add_dependency "misp", "0.1.4"
76
78
  spec.add_dependency "net-ping", "2.0.8"
77
79
  spec.add_dependency "normalize_country", "0.3.2"
78
- spec.add_dependency "onyphe", "2.0.0"
79
80
  spec.add_dependency "parallel", "1.22.1"
80
- spec.add_dependency "passive_circl", "0.1.0"
81
- spec.add_dependency "passivetotalx", "0.1.1"
82
81
  spec.add_dependency "plissken", "2.0.1"
83
82
  spec.add_dependency "public_suffix", "5.0.1"
84
- spec.add_dependency "pulsedive", "0.1.5"
85
83
  spec.add_dependency "puma", "6.0.2"
86
84
  spec.add_dependency "rack", "2.2.4"
87
85
  spec.add_dependency "rack-contrib", "2.3.0"
88
86
  spec.add_dependency "rack-cors", "1.1.1"
89
87
  spec.add_dependency "securitytrails", "1.0.0"
90
88
  spec.add_dependency "semantic_logger", "4.12.0"
91
- spec.add_dependency "sentry-ruby", "5.7.0"
92
- spec.add_dependency "shodanx", "0.2.1"
89
+ spec.add_dependency "sentry-ruby", "5.8.0"
93
90
  spec.add_dependency "slack-notifier", "2.4.0"
94
- spec.add_dependency "sqlite3", "1.6.0"
91
+ spec.add_dependency "sqlite3", "1.6.1"
95
92
  spec.add_dependency "thor", "1.2.1"
96
- spec.add_dependency "urlscan", "0.8.0"
97
93
  spec.add_dependency "uuidtools", "2.2.0"
98
- spec.add_dependency "virustotalx", "1.2.0"
99
94
  spec.add_dependency "whois", "5.1.0"
100
95
  spec.add_dependency "whois-parser", "2.0.0"
101
- spec.add_dependency "zoomeye-rb", "0.2.0"
102
96
  end