mihari 5.6.0 → 5.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/binaryedge.md +1 -1
  3. data/docs/analyzers/censys.md +1 -1
  4. data/docs/analyzers/circl.md +1 -1
  5. data/docs/analyzers/crtsh.md +1 -1
  6. data/docs/analyzers/dnstwister.md +1 -1
  7. data/docs/analyzers/greynoise.md +1 -1
  8. data/docs/analyzers/hunterhow.md +1 -1
  9. data/docs/analyzers/index.md +29 -15
  10. data/docs/analyzers/onyphe.md +1 -1
  11. data/docs/analyzers/otx.md +2 -2
  12. data/docs/analyzers/passivetotal.md +2 -2
  13. data/docs/analyzers/pulsedive.md +2 -2
  14. data/docs/analyzers/securitytrails.md +2 -2
  15. data/docs/analyzers/shodan.md +1 -1
  16. data/docs/analyzers/urlscan.md +3 -3
  17. data/docs/analyzers/virustotal.md +2 -2
  18. data/docs/analyzers/virustotal_intelligence.md +4 -4
  19. data/docs/analyzers/zoomeye.md +5 -0
  20. data/docs/enrichers/google_public_dns.md +1 -1
  21. data/docs/enrichers/ipinfo.md +2 -2
  22. data/docs/enrichers/shodan.md +4 -4
  23. data/docs/enrichers/whois.md +1 -1
  24. data/frontend/package-lock.json +176 -179
  25. data/frontend/package.json +9 -9
  26. data/lib/mihari/{base.rb → actor.rb} +16 -2
  27. data/lib/mihari/analyzers/base.rb +5 -10
  28. data/lib/mihari/analyzers/censys.rb +1 -1
  29. data/lib/mihari/analyzers/circl.rb +1 -1
  30. data/lib/mihari/analyzers/crtsh.rb +1 -1
  31. data/lib/mihari/analyzers/dnstwister.rb +1 -1
  32. data/lib/mihari/analyzers/hunterhow.rb +1 -1
  33. data/lib/mihari/analyzers/otx.rb +1 -1
  34. data/lib/mihari/analyzers/passivetotal.rb +2 -2
  35. data/lib/mihari/analyzers/pulsedive.rb +2 -2
  36. data/lib/mihari/analyzers/securitytrails.rb +2 -2
  37. data/lib/mihari/analyzers/urlscan.rb +1 -1
  38. data/lib/mihari/analyzers/virustotal.rb +5 -5
  39. data/lib/mihari/analyzers/zoomeye.rb +3 -3
  40. data/lib/mihari/clients/base.rb +2 -2
  41. data/lib/mihari/clients/binaryedge.rb +3 -5
  42. data/lib/mihari/clients/censys.rb +3 -3
  43. data/lib/mihari/clients/circl.rb +5 -4
  44. data/lib/mihari/clients/crtsh.rb +5 -4
  45. data/lib/mihari/clients/dnstwister.rb +3 -2
  46. data/lib/mihari/clients/greynoise.rb +2 -2
  47. data/lib/mihari/clients/hunterhow.rb +2 -2
  48. data/lib/mihari/clients/misp.rb +1 -1
  49. data/lib/mihari/clients/onyphe.rb +2 -2
  50. data/lib/mihari/clients/otx.rb +4 -3
  51. data/lib/mihari/clients/passivetotal.rb +9 -8
  52. data/lib/mihari/clients/publsedive.rb +4 -3
  53. data/lib/mihari/clients/securitytrails.rb +8 -6
  54. data/lib/mihari/clients/shodan.rb +2 -2
  55. data/lib/mihari/clients/the_hive.rb +1 -1
  56. data/lib/mihari/clients/urlscan.rb +4 -4
  57. data/lib/mihari/clients/virustotal.rb +2 -2
  58. data/lib/mihari/clients/zoomeye.rb +2 -2
  59. data/lib/mihari/commands/rule.rb +2 -11
  60. data/lib/mihari/commands/search.rb +1 -1
  61. data/lib/mihari/emitters/base.rb +13 -24
  62. data/lib/mihari/emitters/database.rb +7 -9
  63. data/lib/mihari/emitters/misp.rb +14 -38
  64. data/lib/mihari/emitters/slack.rb +14 -11
  65. data/lib/mihari/emitters/the_hive.rb +16 -44
  66. data/lib/mihari/emitters/webhook.rb +31 -21
  67. data/lib/mihari/enrichers/base.rb +1 -6
  68. data/lib/mihari/enrichers/whois.rb +1 -1
  69. data/lib/mihari/models/alert.rb +75 -73
  70. data/lib/mihari/models/artifact.rb +182 -180
  71. data/lib/mihari/models/autonomous_system.rb +22 -20
  72. data/lib/mihari/models/cpe.rb +21 -19
  73. data/lib/mihari/models/dns.rb +24 -22
  74. data/lib/mihari/models/geolocation.rb +22 -20
  75. data/lib/mihari/models/port.rb +21 -19
  76. data/lib/mihari/models/reverse_dns.rb +21 -19
  77. data/lib/mihari/models/rule.rb +67 -65
  78. data/lib/mihari/models/tag.rb +5 -3
  79. data/lib/mihari/models/tagging.rb +5 -3
  80. data/lib/mihari/models/whois.rb +18 -16
  81. data/lib/mihari/rule.rb +352 -0
  82. data/lib/mihari/schemas/analyzer.rb +94 -87
  83. data/lib/mihari/schemas/emitter.rb +9 -5
  84. data/lib/mihari/schemas/enricher.rb +8 -4
  85. data/lib/mihari/schemas/mixins.rb +15 -0
  86. data/lib/mihari/schemas/rule.rb +3 -10
  87. data/lib/mihari/services/alert_builder.rb +1 -1
  88. data/lib/mihari/services/alert_proxy.rb +10 -6
  89. data/lib/mihari/services/alert_runner.rb +4 -4
  90. data/lib/mihari/services/rule_builder.rb +3 -3
  91. data/lib/mihari/services/rule_runner.rb +5 -5
  92. data/lib/mihari/structs/binaryedge.rb +1 -1
  93. data/lib/mihari/structs/censys.rb +6 -6
  94. data/lib/mihari/structs/config.rb +1 -1
  95. data/lib/mihari/structs/greynoise.rb +5 -5
  96. data/lib/mihari/structs/hunterhow.rb +3 -3
  97. data/lib/mihari/structs/onyphe.rb +5 -5
  98. data/lib/mihari/structs/shodan.rb +6 -6
  99. data/lib/mihari/structs/urlscan.rb +3 -3
  100. data/lib/mihari/structs/virustotal_intelligence.rb +3 -3
  101. data/lib/mihari/version.rb +1 -1
  102. data/lib/mihari/web/endpoints/alerts.rb +4 -4
  103. data/lib/mihari/web/endpoints/artifacts.rb +6 -6
  104. data/lib/mihari/web/endpoints/rules.rb +10 -17
  105. data/lib/mihari/web/endpoints/tags.rb +2 -2
  106. data/lib/mihari/web/public/assets/{index-9cc489e6.js → index-28d4c79d.js} +48 -48
  107. data/lib/mihari/web/public/index.html +1 -1
  108. data/lib/mihari.rb +6 -8
  109. data/mihari.gemspec +1 -2
  110. data/mkdocs.yml +0 -3
  111. data/requirements.txt +1 -1
  112. metadata +8 -22
  113. data/lib/mihari/analyzers/rule.rb +0 -232
  114. data/lib/mihari/services/rule_proxy.rb +0 -182
@@ -19,8 +19,8 @@
19
19
  "@fortawesome/vue-fontawesome": "^3.0.3",
20
20
  "@vueuse/core": "^10.5.0",
21
21
  "@vueuse/router": "^10.5.0",
22
- "ace-builds": "^1.30.0",
23
- "axios": "^1.5.1",
22
+ "ace-builds": "^1.31.0",
23
+ "axios": "^1.6.0",
24
24
  "bulma": "^0.9.4",
25
25
  "bulma-helpers": "^0.4.3",
26
26
  "dayjs": "^1.11.10",
@@ -30,21 +30,21 @@
30
30
  "ts-dedent": "^2.2.0",
31
31
  "url-parse": "^1.5.10",
32
32
  "uuidv4": "^6.2.13",
33
- "vue": "^3.3.6",
33
+ "vue": "^3.3.7",
34
34
  "vue-concurrency": "4.0.1",
35
35
  "vue-json-pretty": "^2.2.4",
36
36
  "vue-router": "^4.2.5",
37
37
  "vue3-ace-editor": "^2.2.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@redocly/cli": "1.3.0",
40
+ "@redocly/cli": "1.4.0",
41
41
  "@rushstack/eslint-patch": "^1.5.1",
42
42
  "@tsconfig/node20": "^20.1.2",
43
43
  "@types/jsdom": "^21.1.4",
44
- "@types/node": "^20.8.7",
44
+ "@types/node": "^20.8.9",
45
45
  "@types/url-parse": "^1.4.10",
46
- "@typescript-eslint/eslint-plugin": "^6.8.0",
47
- "@typescript-eslint/parser": "^6.8.0",
46
+ "@typescript-eslint/eslint-plugin": "^6.9.0",
47
+ "@typescript-eslint/parser": "^6.9.0",
48
48
  "@vitejs/plugin-vue": "^4.4.0",
49
49
  "@vue/eslint-config-prettier": "^8.0.0",
50
50
  "@vue/eslint-config-typescript": "^12.0.0",
@@ -54,7 +54,7 @@
54
54
  "eslint-config-prettier": "^9.0.0",
55
55
  "eslint-plugin-prettier": "^5.0.1",
56
56
  "eslint-plugin-simple-import-sort": "^10.0.0",
57
- "eslint-plugin-vue": "^9.17.0",
57
+ "eslint-plugin-vue": "^9.18.1",
58
58
  "husky": "^8.0.3",
59
59
  "jsdom": "^22.1.0",
60
60
  "npm-run-all": "^4.1.5",
@@ -62,6 +62,6 @@
62
62
  "typescript": "~5.2.2",
63
63
  "vite": "^4.5.0",
64
64
  "vitest": "^0.34.6",
65
- "vue-tsc": "^1.8.19"
65
+ "vue-tsc": "^1.8.22"
66
66
  }
67
67
  }
@@ -4,7 +4,12 @@ module Mihari
4
4
  #
5
5
  # Base class for Analyzer, Emitter and Enricher
6
6
  #
7
- class Base
7
+ class Actor
8
+ include Dry::Monads[:result, :try]
9
+
10
+ include Mixins::Configurable
11
+ include Mixins::Retriable
12
+
8
13
  # @return [Hash]
9
14
  attr_reader :options
10
15
 
@@ -43,6 +48,15 @@ module Mihari
43
48
  options[:timeout]
44
49
  end
45
50
 
51
+ def validate_configuration!
52
+ return if configured?
53
+
54
+ joined = configuration_keys.join(", ")
55
+ be = (configuration_keys.length > 1) ? "are" : "is"
56
+ message = "#{self.class.class_key} is not configured correctly. #{joined} #{be} missing."
57
+ raise ConfigurationError, message
58
+ end
59
+
46
60
  class << self
47
61
  #
48
62
  # @return [String]
@@ -62,7 +76,7 @@ module Mihari
62
76
  # @return [Array<String>]
63
77
  #
64
78
  def class_keys
65
- ([class_key] + [class_key_aliases]).flatten.compact
79
+ ([class_key] + [class_key_aliases]).flatten.compact.map(&:downcase)
66
80
  end
67
81
  end
68
82
  end
@@ -2,12 +2,7 @@
2
2
 
3
3
  module Mihari
4
4
  module Analyzers
5
- class Base < Mihari::Base
6
- include Dry::Monads[:result, :try]
7
-
8
- include Mixins::Configurable
9
- include Mixins::Retriable
10
-
5
+ class Base < Actor
11
6
  # @return [String]
12
7
  attr_reader :query
13
8
 
@@ -45,7 +40,7 @@ module Mihari
45
40
  Mihari.config.ignore_error
46
41
  end
47
42
 
48
- # @return [Array<String>, Array<Mihari::Artifact>]
43
+ # @return [Array<String>, Array<Mihari::Models::Artifact>]
49
44
  def artifacts
50
45
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
51
46
  end
@@ -55,14 +50,14 @@ module Mihari
55
50
  # - Convert data (string) into an artifact
56
51
  # - Reject an invalid artifact
57
52
  #
58
- # @return [Array<Mihari::Artifact>]
53
+ # @return [Array<Mihari::Models::Artifact>]
59
54
  #
60
55
  def normalized_artifacts
61
56
  retry_on_error(times: retry_times, interval: retry_interval, exponential_backoff: retry_exponential_backoff) do
62
57
  artifacts.compact.sort.map do |artifact|
63
58
  # No need to set data_type manually
64
59
  # It is set automatically in #initialize
65
- artifact = artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact)
60
+ artifact = artifact.is_a?(Models::Artifact) ? artifact : Models::Artifact.new(data: artifact)
66
61
  artifact.source = self.class.class_key
67
62
  artifact
68
63
  end.select(&:valid?).uniq(&:data)
@@ -70,7 +65,7 @@ module Mihari
70
65
  end
71
66
 
72
67
  #
73
- # @return [Dry::Monads::Result::Success<Array<Mihari::Artifact>>, Dry::Monads::Result::Failure]
68
+ # @return [Dry::Monads::Result::Success<Array<Mihari::Models::Artifact>>, Dry::Monads::Result::Failure]
74
69
  #
75
70
  def result
76
71
  Try[StandardError] { normalized_artifacts }.to_result
@@ -24,7 +24,7 @@ module Mihari
24
24
  end
25
25
 
26
26
  #
27
- # @return [Array<Mihari::Artifact>]
27
+ # @return [Array<Mihari::Models::Artifact>]
28
28
  #
29
29
  def artifacts
30
30
  client.search_with_pagination(query, pagination_limit: pagination_limit).map do |res|
@@ -51,7 +51,7 @@ module Mihari
51
51
  private
52
52
 
53
53
  def client
54
- @client ||= Clients::CIRCL.new(username: username, password: password)
54
+ @client ||= Clients::CIRCL.new(username: username, password: password, timeout: timeout)
55
55
  end
56
56
 
57
57
  def username?
@@ -28,7 +28,7 @@ module Mihari
28
28
  # @return [Mihari::Clients::Crtsh]
29
29
  #
30
30
  def client
31
- @client ||= Mihari::Clients::Crtsh.new
31
+ @client ||= Mihari::Clients::Crtsh.new(timeout: timeout)
32
32
  end
33
33
  end
34
34
  end
@@ -39,7 +39,7 @@ module Mihari
39
39
  end
40
40
 
41
41
  def client
42
- @client ||= Clients::DNSTwister.new
42
+ @client ||= Clients::DNSTwister.new(timeout: timeout)
43
43
  end
44
44
 
45
45
  #
@@ -27,7 +27,7 @@ module Mihari
27
27
  end
28
28
 
29
29
  #
30
- # @return [Array<Mihari::Artifact>]
30
+ # @return [Array<Mihari::Models::Artifact>]
31
31
  #
32
32
  def artifacts
33
33
  client.search_with_pagination(
@@ -42,7 +42,7 @@ module Mihari
42
42
  private
43
43
 
44
44
  def client
45
- @client ||= Mihari::Clients::OTX.new(api_key: api_key)
45
+ @client ||= Mihari::Clients::OTX.new(api_key: api_key, timeout: timeout)
46
46
  end
47
47
 
48
48
  #
@@ -54,7 +54,7 @@ module Mihari
54
54
  #
55
55
  # @return [Array<String>, nil]
56
56
  #
57
- def key_aliases
57
+ def class_key_aliases
58
58
  ["pt"]
59
59
  end
60
60
  end
@@ -62,7 +62,7 @@ module Mihari
62
62
  private
63
63
 
64
64
  def client
65
- @client ||= Clients::PassiveTotal.new(username: username, api_key: api_key)
65
+ @client ||= Clients::PassiveTotal.new(username: username, api_key: api_key, timeout: timeout)
66
66
  end
67
67
 
68
68
  #
@@ -35,7 +35,7 @@ module Mihari
35
35
  nil
36
36
  else
37
37
  data = property["value"]
38
- Artifact.new(data: data, metadata: property)
38
+ Models::Artifact.new(data: data, metadata: property)
39
39
  end
40
40
  end
41
41
  end
@@ -47,7 +47,7 @@ module Mihari
47
47
  private
48
48
 
49
49
  def client
50
- @client ||= Clients::PulseDive.new(api_key: api_key)
50
+ @client ||= Clients::PulseDive.new(api_key: api_key, timeout: timeout)
51
51
  end
52
52
 
53
53
  #
@@ -48,7 +48,7 @@ module Mihari
48
48
  #
49
49
  # @return [Array<String>, nil]
50
50
  #
51
- def key_aliases
51
+ def class_key_aliases
52
52
  ["st"]
53
53
  end
54
54
  end
@@ -56,7 +56,7 @@ module Mihari
56
56
  private
57
57
 
58
58
  def client
59
- @client ||= Clients::SecurityTrails.new(api_key: api_key)
59
+ @client ||= Clients::SecurityTrails.new(api_key: api_key, timeout: timeout)
60
60
  end
61
61
 
62
62
  #
@@ -29,7 +29,7 @@ module Mihari
29
29
  end
30
30
 
31
31
  def artifacts
32
- # @type [Array<Mihari::Artifact>]
32
+ # @type [Array<Mihari::Models::Artifact>]
33
33
  artifacts = client.search_with_pagination(query, pagination_limit: pagination_limit).map(&:artifacts).flatten
34
34
 
35
35
  artifacts.select do |artifact|
@@ -43,7 +43,7 @@ module Mihari
43
43
  #
44
44
  # @return [Array<String>, nil]
45
45
  #
46
- def key_aliases
46
+ def class_key_aliases
47
47
  ["vt"]
48
48
  end
49
49
  end
@@ -66,7 +66,7 @@ module Mihari
66
66
  #
67
67
  # Domain search
68
68
  #
69
- # @return [Array<Mihari::Artifact>]
69
+ # @return [Array<Mihari::Models::Artifact>]
70
70
  #
71
71
  def domain_search
72
72
  res = client.domain_search(query)
@@ -74,14 +74,14 @@ module Mihari
74
74
  data = res["data"] || []
75
75
  data.filter_map do |item|
76
76
  data = item.dig("attributes", "ip_address")
77
- data.nil? ? nil : Artifact.new(data: data, metadata: item)
77
+ data.nil? ? nil : Models::Artifact.new(data: data, metadata: item)
78
78
  end
79
79
  end
80
80
 
81
81
  #
82
82
  # IP search
83
83
  #
84
- # @return [Array<Mihari::Artifact>]
84
+ # @return [Array<Mihari::Models::Artifact>]
85
85
  #
86
86
  def ip_search
87
87
  res = client.ip_search(query)
@@ -89,7 +89,7 @@ module Mihari
89
89
  data = res["data"] || []
90
90
  data.filter_map do |item|
91
91
  data = item.dig("attributes", "host_name")
92
- Artifact.new(data: data, metadata: item)
92
+ Models::Artifact.new(data: data, metadata: item)
93
93
  end.uniq
94
94
  end
95
95
  end
@@ -65,7 +65,7 @@ module Mihari
65
65
  #
66
66
  # @param [Hash] response
67
67
  #
68
- # @return [Array<Mihari::Artifact>]
68
+ # @return [Array<Mihari::Models::Artifact>]
69
69
  #
70
70
  def convert(res)
71
71
  matches = res["matches"] || []
@@ -73,9 +73,9 @@ module Mihari
73
73
  data = match["ip"]
74
74
 
75
75
  if data.is_a?(Array)
76
- data.map { |d| Artifact.new(data: d, metadata: match) }
76
+ data.map { |d| Models::Artifact.new(data: d, metadata: match) }
77
77
  else
78
- Artifact.new(data: data, metadata: match)
78
+ Models::Artifact.new(data: data, metadata: match)
79
79
  end
80
80
  end.flatten
81
81
  end
@@ -18,10 +18,10 @@ module Mihari
18
18
  #
19
19
  # @param [String] base_url
20
20
  # @param [Hash] headers
21
- # @param [Integer] interval
21
+ # @param [Integer] pagination_interval
22
22
  # @param [Integer, nil] timeout
23
23
  #
24
- def initialize(base_url, headers: {}, pagination_interval: 0, timeout: nil)
24
+ def initialize(base_url, headers: {}, pagination_interval: Mihari.config.pagination_interval, timeout: nil)
25
25
  @base_url = base_url
26
26
  @headers = headers || {}
27
27
  @pagination_interval = pagination_interval
@@ -7,21 +7,19 @@ module Mihari
7
7
  # @param [String] base_url
8
8
  # @param [String, nil] api_key
9
9
  # @param [Hash] headers
10
- # @param [Integer] pagnation_interval
11
10
  # @param [Integer, nil] timeout
11
+ # @param [Integer] pagination_interval
12
12
  #
13
13
  def initialize(
14
14
  base_url = "https://api.binaryedge.io/v2",
15
15
  api_key:,
16
16
  headers: {},
17
- pagination_interval: 0,
17
+ pagination_interval: Mihari.config.pagination_interval,
18
18
  timeout: nil
19
19
  )
20
- raise(ArgumentError, "'api_key' argument is required") unless api_key
21
-
22
20
  headers["x-key"] = api_key
23
21
 
24
- super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
22
+ super(base_url, headers: headers, timeout: timeout, pagination_interval: pagination_interval)
25
23
  end
26
24
 
27
25
  #
@@ -18,11 +18,11 @@ module Mihari
18
18
  id:,
19
19
  secret:,
20
20
  headers: {},
21
- pagination_interval: 0,
21
+ pagination_interval: Mihari.config.pagination_interval,
22
22
  timeout: nil
23
23
  )
24
- raise(ArgumentError, "'id' argument is required") if id.nil?
25
- raise(ArgumentError, "'secret' argument is required") if secret.nil?
24
+ raise(ArgumentError, "id is required") if id.nil?
25
+ raise(ArgumentError, "secret is required") if secret.nil?
26
26
 
27
27
  headers["authorization"] = "Basic #{Base64.strict_encode64("#{id}:#{secret}")}"
28
28
 
@@ -10,14 +10,15 @@ module Mihari
10
10
  # @param [String, nil] username
11
11
  # @param [String, nil] password
12
12
  # @param [Hash] headers
13
+ # @param [Integer, nil] timeout
13
14
  #
14
- def initialize(base_url = "https://www.circl.lu", username:, password:, headers: {})
15
- raise(ArgumentError, "'username' argument is required") if username.nil?
16
- raise(ArgumentError, "'password' argument is required") if password.nil?
15
+ def initialize(base_url = "https://www.circl.lu", username:, password:, headers: {}, timeout: nil)
16
+ raise(ArgumentError, "username is required") if username.nil?
17
+ raise(ArgumentError, "password is required") if password.nil?
17
18
 
18
19
  headers["authorization"] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
19
20
 
20
- super(base_url, headers: headers)
21
+ super(base_url, headers: headers, timeout: timeout)
21
22
  end
22
23
 
23
24
  #
@@ -6,9 +6,10 @@ module Mihari
6
6
  #
7
7
  # @param [String] base_url
8
8
  # @param [Hash] headers
9
+ # @param [Integer, nil] timeout
9
10
  #
10
- def initialize(base_url = "https://crt.sh", headers: {})
11
- super(base_url, headers: headers)
11
+ def initialize(base_url = "https://crt.sh", headers: {}, timeout: nil)
12
+ super(base_url, headers: headers, timeout: timeout)
12
13
  end
13
14
 
14
15
  #
@@ -18,7 +19,7 @@ module Mihari
18
19
  # @param [String, nil] match "=", "ILIKE", "LIKE", "single", "any" or nil
19
20
  # @param [String, nil] exclude "expired" or nil
20
21
  #
21
- # @return [Array<Mihari::Artifact>]
22
+ # @return [Array<Mihari::Models::Artifact>]
22
23
  #
23
24
  def search(identity, match: nil, exclude: nil)
24
25
  params = { identity: identity, match: match, exclude: exclude, output: "json" }.compact
@@ -28,7 +29,7 @@ module Mihari
28
29
 
29
30
  parsed.map do |result|
30
31
  values = result["name_value"].to_s.lines.map(&:chomp)
31
- values.map { |value| Artifact.new(data: value, metadata: result) }
32
+ values.map { |value| Models::Artifact.new(data: value, metadata: result) }
32
33
  end.flatten
33
34
  end
34
35
  end
@@ -6,9 +6,10 @@ module Mihari
6
6
  #
7
7
  # @param [String] base_url
8
8
  # @param [Hash] headers
9
+ # @param [Integer, nil] timeout
9
10
  #
10
- def initialize(base_url = "https://dnstwister.report", headers: {})
11
- super(base_url, headers: headers)
11
+ def initialize(base_url = "https://dnstwister.report", headers: {}, timeout: nil)
12
+ super(base_url, headers: headers, timeout: timeout)
12
13
  end
13
14
 
14
15
  #
@@ -16,10 +16,10 @@ module Mihari
16
16
  base_url = "https://api.greynoise.io",
17
17
  api_key:,
18
18
  headers: {},
19
- pagination_interval: 0,
19
+ pagination_interval: Mihari.config.pagination_interval,
20
20
  timeout: nil
21
21
  )
22
- raise(ArgumentError, "'api_key' argument is required") unless api_key
22
+ raise(ArgumentError, "api_key is required") unless api_key
23
23
 
24
24
  headers["key"] = api_key
25
25
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
@@ -21,10 +21,10 @@ module Mihari
21
21
  base_url = "https://api.hunter.how/",
22
22
  api_key:,
23
23
  headers: {},
24
- pagination_interval: 0,
24
+ pagination_interval: Mihari.config.pagination_interval,
25
25
  timeout: nil
26
26
  )
27
- raise(ArgumentError, "'api_key' argument is required") unless api_key
27
+ raise(ArgumentError, "api_key is required") unless api_key
28
28
 
29
29
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
30
30
 
@@ -10,7 +10,7 @@ module Mihari
10
10
  # @param [Integer, nil] timeout
11
11
  #
12
12
  def initialize(base_url, api_key:, headers: {}, timeout: nil)
13
- raise(ArgumentError, "'api_key' argument is required") unless api_key
13
+ raise(ArgumentError, "api_key is required") unless api_key
14
14
 
15
15
  headers["authorization"] = api_key
16
16
  headers["accept"] = "application/json"
@@ -19,10 +19,10 @@ module Mihari
19
19
  base_url = "https://www.onyphe.io",
20
20
  api_key:,
21
21
  headers: {},
22
- pagination_interval: 0,
22
+ pagination_interval: Mihari.config.pagination_interval,
23
23
  timeout: nil
24
24
  )
25
- raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
25
+ raise(ArgumentError, "api_key is required") if api_key.nil?
26
26
 
27
27
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
28
28
 
@@ -7,12 +7,13 @@ module Mihari
7
7
  # @param [String] base_url
8
8
  # @param [String, nil] api_key
9
9
  # @param [Hash] headers
10
+ # @param [Integer, nil] timeout
10
11
  #
11
- def initialize(base_url = "https://otx.alienvault.com", api_key:, headers: {})
12
- raise(ArgumentError, "'api_key' argument is required") unless api_key
12
+ def initialize(base_url = "https://otx.alienvault.com", api_key:, headers: {}, timeout: nil)
13
+ raise(ArgumentError, "api_key is required") unless api_key
13
14
 
14
15
  headers["x-otx-api-key"] = api_key
15
- super(base_url, headers: headers)
16
+ super(base_url, headers: headers, timeout: timeout)
16
17
  end
17
18
 
18
19
  #
@@ -10,14 +10,15 @@ module Mihari
10
10
  # @param [String, nil] username
11
11
  # @param [String, nil] api_key
12
12
  # @param [Hash] headers
13
+ # @param [Integer, nil] timeout
13
14
  #
14
- def initialize(base_url = "https://api.passivetotal.org", username:, api_key:, headers: {})
15
- raise(ArgumentError, "'username' argument is required") if username.nil?
16
- raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
15
+ def initialize(base_url = "https://api.passivetotal.org", username:, api_key:, headers: {}, timeout: nil)
16
+ raise(ArgumentError, "username is required") if username.nil?
17
+ raise(ArgumentError, "api_key is required") if api_key.nil?
17
18
 
18
19
  headers["authorization"] = "Basic #{Base64.strict_encode64("#{username}:#{api_key}")}"
19
20
 
20
- super(base_url, headers: headers)
21
+ super(base_url, headers: headers, timeout: timeout)
21
22
  end
22
23
 
23
24
  #
@@ -38,7 +39,7 @@ module Mihari
38
39
  #
39
40
  # @param [String] query
40
41
  #
41
- # @return [Array<Mihari::Artifact>]
42
+ # @return [Array<Mihari::Models::Artifact>]
42
43
  #
43
44
  def reverse_whois_search(query)
44
45
  params = {
@@ -49,7 +50,7 @@ module Mihari
49
50
  results = res["results"] || []
50
51
  results.map do |result|
51
52
  data = result["domain"]
52
- Artifact.new(data: data, metadata: result)
53
+ Models::Artifact.new(data: data, metadata: result)
53
54
  end.flatten
54
55
  end
55
56
 
@@ -58,7 +59,7 @@ module Mihari
58
59
  #
59
60
  # @param [String] query
60
61
  #
61
- # @return [Array<Mihari::Artifact>]
62
+ # @return [Array<Mihari::Models::Artifact>]
62
63
  #
63
64
  def ssl_search(query)
64
65
  params = { query: query }
@@ -66,7 +67,7 @@ module Mihari
66
67
  results = res["results"] || []
67
68
  results.map do |result|
68
69
  data = result["ipAddresses"]
69
- data.map { |d| Artifact.new(data: d, metadata: result) }
70
+ data.map { |d| Models::Artifact.new(data: d, metadata: result) }
70
71
  end.flatten
71
72
  end
72
73
 
@@ -10,13 +10,14 @@ module Mihari
10
10
  # @param [String] base_url
11
11
  # @param [String, nil] api_key
12
12
  # @param [Hash] headers
13
+ # @param [Integer, nil] timeout
13
14
  #
14
- def initialize(base_url = "https://pulsedive.com", api_key:, headers: {})
15
- super(base_url, headers: headers)
15
+ def initialize(base_url = "https://pulsedive.com", api_key:, headers: {}, timeout: nil)
16
+ raise(ArgumentError, "api_key is required") unless api_key
16
17
 
17
18
  @api_key = api_key
18
19
 
19
- raise(ArgumentError, "'api_key' argument is required") unless api_key
20
+ super(base_url, headers: headers, timeout: timeout)
20
21
  end
21
22
 
22
23
  #
@@ -7,12 +7,14 @@ module Mihari
7
7
  # @param [String] base_url
8
8
  # @param [String, nil] api_key
9
9
  # @param [Hash] headers
10
+ # @param [Integer, nil] timeout
10
11
  #
11
- def initialize(base_url = "https://api.securitytrails.com", api_key:, headers: {})
12
- raise(ArgumentError, "'api_key' argument is required") unless api_key
12
+ def initialize(base_url = "https://api.securitytrails.com", api_key:, headers: {}, timeout: nil)
13
+ raise(ArgumentError, "api_key is required") unless api_key
13
14
 
14
15
  headers["apikey"] = api_key
15
- super(base_url, headers: headers)
16
+
17
+ super(base_url, headers: headers, timeout: timeout)
16
18
  end
17
19
 
18
20
  #
@@ -34,13 +36,13 @@ module Mihari
34
36
  #
35
37
  # @param [String] query
36
38
  #
37
- # @return [Array<Mihari::Artifact>]
39
+ # @return [Array<Mihari::Models::Artifact>]
38
40
  #
39
41
  def ip_search(query)
40
42
  records = search_by_ip(query)
41
43
  records.filter_map do |record|
42
44
  data = record["hostname"]
43
- Artifact.new(data: data, metadata: record)
45
+ Models::Artifact.new(data: data, metadata: record)
44
46
  end
45
47
  end
46
48
 
@@ -55,7 +57,7 @@ module Mihari
55
57
  records = search_by_mail(query)
56
58
  records.filter_map do |record|
57
59
  data = record["hostname"]
58
- Artifact.new(data: data, metadata: record)
60
+ Models::Artifact.new(data: data, metadata: record)
59
61
  end
60
62
  end
61
63
 
@@ -19,10 +19,10 @@ module Mihari
19
19
  base_url = "https://api.shodan.io",
20
20
  api_key:,
21
21
  headers: {},
22
- pagination_interval: 0,
22
+ pagination_interval: Mihari.config.pagination_interval,
23
23
  timeout: nil
24
24
  )
25
- raise(ArgumentError, "'api_key' argument is required") unless api_key
25
+ raise(ArgumentError, "api_key is required") unless api_key
26
26
 
27
27
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
28
28