mihari 5.4.9 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/docs/analyzers/binaryedge.md +2 -2
- data/docs/analyzers/censys.md +3 -3
- data/docs/analyzers/circl.md +3 -3
- data/docs/analyzers/crtsh.md +2 -2
- data/docs/analyzers/dnstwister.md +1 -1
- data/docs/analyzers/feed.md +7 -7
- data/docs/analyzers/greynoise.md +2 -2
- data/docs/analyzers/hunterhow.md +4 -4
- data/docs/analyzers/index.md +13 -8
- data/docs/analyzers/onyphe.md +2 -2
- data/docs/analyzers/otx.md +2 -2
- data/docs/analyzers/passivetotal.md +3 -3
- data/docs/analyzers/pulsedive.md +2 -2
- data/docs/analyzers/securitytrails.md +2 -2
- data/docs/analyzers/shodan.md +2 -2
- data/docs/analyzers/urlscan.md +2 -2
- data/docs/analyzers/virustotal.md +2 -2
- data/docs/analyzers/virustotal_intelligence.md +2 -2
- data/docs/analyzers/zoomeye.md +3 -3
- data/docs/emitters/hive.md +3 -3
- data/docs/emitters/index.md +29 -0
- data/docs/emitters/misp.md +2 -2
- data/docs/emitters/slack.md +2 -2
- data/docs/emitters/webhook.md +4 -4
- data/docs/enrichers/index.md +29 -0
- data/docs/enrichers/ipinfo.md +7 -0
- data/docs/index.md +0 -2
- data/docs/installation.md +1 -1
- data/docs/rule.md +11 -11
- data/frontend/package-lock.json +294 -2772
- data/frontend/package.json +10 -10
- data/lib/mihari/analyzers/base.rb +15 -8
- data/lib/mihari/analyzers/binaryedge.rb +5 -1
- data/lib/mihari/analyzers/censys.rb +6 -1
- data/lib/mihari/analyzers/greynoise.rb +5 -1
- data/lib/mihari/analyzers/hunterhow.rb +5 -1
- data/lib/mihari/analyzers/onyphe.rb +5 -1
- data/lib/mihari/analyzers/rule.rb +43 -7
- data/lib/mihari/analyzers/shodan.rb +5 -1
- data/lib/mihari/analyzers/urlscan.rb +5 -1
- data/lib/mihari/analyzers/virustotal_intelligence.rb +5 -1
- data/lib/mihari/analyzers/zoomeye.rb +5 -1
- data/lib/mihari/clients/base.rb +7 -7
- data/lib/mihari/clients/binaryedge.rb +10 -4
- data/lib/mihari/clients/censys.rb +11 -4
- data/lib/mihari/clients/greynoise.rb +10 -4
- data/lib/mihari/clients/hunterhow.rb +10 -4
- data/lib/mihari/clients/misp.rb +3 -2
- data/lib/mihari/clients/onyphe.rb +10 -4
- data/lib/mihari/clients/shodan.rb +10 -4
- data/lib/mihari/clients/the_hive.rb +3 -2
- data/lib/mihari/clients/urlscan.rb +9 -3
- data/lib/mihari/clients/virustotal.rb +10 -4
- data/lib/mihari/clients/zoomeye.rb +11 -5
- data/lib/mihari/config.rb +8 -0
- data/lib/mihari/emitters/base.rb +49 -12
- data/lib/mihari/emitters/misp.rb +7 -6
- data/lib/mihari/emitters/slack.rb +24 -6
- data/lib/mihari/emitters/the_hive.rb +8 -7
- data/lib/mihari/emitters/webhook.rb +31 -29
- data/lib/mihari/enrichers/base.rb +53 -16
- data/lib/mihari/enrichers/google_public_dns.rb +33 -42
- data/lib/mihari/enrichers/ipinfo.rb +32 -34
- data/lib/mihari/enrichers/shodan.rb +18 -26
- data/lib/mihari/enrichers/whois.rb +121 -111
- data/lib/mihari/mixins/retriable.rb +4 -2
- data/lib/mihari/models/artifact.rb +37 -23
- data/lib/mihari/models/autonomous_system.rb +3 -2
- data/lib/mihari/models/cpe.rb +3 -2
- data/lib/mihari/models/dns.rb +3 -2
- data/lib/mihari/models/geolocation.rb +3 -2
- data/lib/mihari/models/port.rb +3 -2
- data/lib/mihari/models/reverse_dns.rb +3 -2
- data/lib/mihari/models/whois.rb +4 -3
- data/lib/mihari/schemas/analyzer.rb +2 -1
- data/lib/mihari/schemas/emitter.rb +39 -25
- data/lib/mihari/schemas/enricher.rb +28 -2
- data/lib/mihari/schemas/rule.rb +6 -2
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/endpoints/ip_addresses.rb +1 -1
- data/lib/mihari/web/public/assets/index-b5d817a3.js +1749 -0
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari/web/public/redoc-static.html +400 -400
- data/mihari.gemspec +2 -2
- data/mkdocs.yml +8 -6
- data/requirements.txt +1 -1
- metadata +7 -7
- data/lib/mihari/web/public/assets/index-a92abd57.js +0 -1740
data/frontend/package.json
CHANGED
@@ -19,7 +19,7 @@
|
|
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.
|
22
|
+
"ace-builds": "^1.30.0",
|
23
23
|
"axios": "^1.5.1",
|
24
24
|
"bulma": "^0.9.4",
|
25
25
|
"bulma-helpers": "^0.4.3",
|
@@ -30,27 +30,27 @@
|
|
30
30
|
"ts-dedent": "^2.2.0",
|
31
31
|
"url-parse": "^1.5.10",
|
32
32
|
"uuidv4": "^6.2.13",
|
33
|
-
"vue": "^3.3.
|
33
|
+
"vue": "^3.3.6",
|
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.
|
40
|
+
"@redocly/cli": "1.3.0",
|
41
41
|
"@rushstack/eslint-patch": "^1.5.1",
|
42
42
|
"@tsconfig/node20": "^20.1.2",
|
43
|
-
"@types/jsdom": "^21.1.
|
44
|
-
"@types/node": "^20.8.
|
45
|
-
"@types/url-parse": "^1.4.
|
46
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
47
|
-
"@typescript-eslint/parser": "^6.
|
43
|
+
"@types/jsdom": "^21.1.4",
|
44
|
+
"@types/node": "^20.8.7",
|
45
|
+
"@types/url-parse": "^1.4.10",
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
47
|
+
"@typescript-eslint/parser": "^6.8.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",
|
51
51
|
"@vue/test-utils": "2.4.1",
|
52
52
|
"@vue/tsconfig": "^0.4.0",
|
53
|
-
"eslint": "^8.
|
53
|
+
"eslint": "^8.52.0",
|
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",
|
@@ -60,7 +60,7 @@
|
|
60
60
|
"npm-run-all": "^4.1.5",
|
61
61
|
"prettier": "^3.0.3",
|
62
62
|
"typescript": "~5.2.2",
|
63
|
-
"vite": "^4.
|
63
|
+
"vite": "^4.5.0",
|
64
64
|
"vitest": "^0.34.6",
|
65
65
|
"vue-tsc": "^1.8.19"
|
66
66
|
}
|
@@ -24,17 +24,17 @@ module Mihari
|
|
24
24
|
end
|
25
25
|
|
26
26
|
#
|
27
|
-
# @return [Integer
|
27
|
+
# @return [Integer]
|
28
28
|
#
|
29
|
-
def
|
30
|
-
options[:
|
29
|
+
def retry_interval
|
30
|
+
options[:retry_interval] || Mihari.config.retry_interval
|
31
31
|
end
|
32
32
|
|
33
33
|
#
|
34
|
-
# @return [
|
34
|
+
# @return [Boolean]
|
35
35
|
#
|
36
|
-
def
|
37
|
-
options[:
|
36
|
+
def retry_exponential_backoff
|
37
|
+
options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
|
38
38
|
end
|
39
39
|
|
40
40
|
#
|
@@ -44,6 +44,13 @@ module Mihari
|
|
44
44
|
options[:retry_times] || Mihari.config.retry_times
|
45
45
|
end
|
46
46
|
|
47
|
+
#
|
48
|
+
# @return [Integer]
|
49
|
+
#
|
50
|
+
def pagination_interval
|
51
|
+
options[:pagination_interval] || Mihari.config.pagination_interval
|
52
|
+
end
|
53
|
+
|
47
54
|
#
|
48
55
|
# @return [Integer]
|
49
56
|
#
|
@@ -81,7 +88,7 @@ module Mihari
|
|
81
88
|
# @return [Array<Mihari::Artifact>]
|
82
89
|
#
|
83
90
|
def normalized_artifacts
|
84
|
-
retry_on_error(times: retry_times, interval: retry_interval) do
|
91
|
+
retry_on_error(times: retry_times, interval: retry_interval, exponential_backoff: retry_exponential_backoff) do
|
85
92
|
artifacts.compact.sort.map do |artifact|
|
86
93
|
# No need to set data_type manually
|
87
94
|
# It is set automatically in #initialize
|
@@ -104,7 +111,7 @@ module Mihari
|
|
104
111
|
self.class.to_s.split("::").last
|
105
112
|
end
|
106
113
|
|
107
|
-
|
114
|
+
alias_method :source, :class_name
|
108
115
|
|
109
116
|
class << self
|
110
117
|
#
|
@@ -32,7 +32,11 @@ module Mihari
|
|
32
32
|
# @return [Mihari::Clients::BinaryEdge]
|
33
33
|
#
|
34
34
|
def client
|
35
|
-
@client ||= Clients::BinaryEdge.new(
|
35
|
+
@client ||= Clients::BinaryEdge.new(
|
36
|
+
api_key: api_key,
|
37
|
+
pagination_interval: pagination_interval,
|
38
|
+
timeout: timeout
|
39
|
+
)
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -52,7 +52,12 @@ module Mihari
|
|
52
52
|
# @return [Mihari::Clients::Censys]
|
53
53
|
#
|
54
54
|
def client
|
55
|
-
@client ||= Clients::Censys.new(
|
55
|
+
@client ||= Clients::Censys.new(
|
56
|
+
id: id,
|
57
|
+
secret: secret,
|
58
|
+
pagination_interval: pagination_interval,
|
59
|
+
timeout: timeout
|
60
|
+
)
|
56
61
|
end
|
57
62
|
|
58
63
|
#
|
@@ -31,7 +31,11 @@ module Mihari
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def client
|
34
|
-
@client ||= Clients::GreyNoise.new(
|
34
|
+
@client ||= Clients::GreyNoise.new(
|
35
|
+
api_key: api_key,
|
36
|
+
pagination_interval: pagination_interval,
|
37
|
+
timeout: timeout
|
38
|
+
)
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
@@ -46,7 +46,11 @@ module Mihari
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def client
|
49
|
-
@client ||= Clients::HunterHow.new(
|
49
|
+
@client ||= Clients::HunterHow.new(
|
50
|
+
api_key: api_key,
|
51
|
+
pagination_interval: pagination_interval,
|
52
|
+
timeout: timeout
|
53
|
+
)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
end
|
@@ -33,7 +33,11 @@ module Mihari
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def client
|
36
|
-
@client ||= Clients::Onyphe.new(
|
36
|
+
@client ||= Clients::Onyphe.new(
|
37
|
+
api_key: api_key,
|
38
|
+
pagination_interval: pagination_interval,
|
39
|
+
timeout: timeout
|
40
|
+
)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -35,17 +35,24 @@ module Mihari
|
|
35
35
|
"webhook" => Emitters::Webhook
|
36
36
|
}.freeze
|
37
37
|
|
38
|
+
ENRICHER_TO_CLASS = {
|
39
|
+
"whois" => Enrichers::Whois,
|
40
|
+
"ipinfo" => Enrichers::IPInfo,
|
41
|
+
"shodan" => Enrichers::Shodan,
|
42
|
+
"google_public_dns" => Enrichers::GooglePublicDNS
|
43
|
+
}.freeze
|
44
|
+
|
38
45
|
class Rule
|
39
46
|
include Mixins::FalsePositive
|
40
47
|
|
41
|
-
# @return [Mihari::Services::
|
48
|
+
# @return [Mihari::Services::RuleProxy]
|
42
49
|
attr_reader :rule
|
43
50
|
|
44
51
|
# @return [Time]
|
45
52
|
attr_reader :base_time
|
46
53
|
|
47
54
|
#
|
48
|
-
# @param [Mihari::Services::
|
55
|
+
# @param [Mihari::Services::RuleProxy] rule
|
49
56
|
#
|
50
57
|
def initialize(rule)
|
51
58
|
@rule = rule
|
@@ -106,7 +113,7 @@ module Mihari
|
|
106
113
|
#
|
107
114
|
def enriched_artifacts
|
108
115
|
@enriched_artifacts ||= Parallel.map(unique_artifacts) do |artifact|
|
109
|
-
|
116
|
+
enrichers.each { |enricher| artifact.enrich_by_enricher enricher }
|
110
117
|
artifact
|
111
118
|
end
|
112
119
|
end
|
@@ -193,18 +200,18 @@ module Mihari
|
|
193
200
|
raise ArgumentError, "#{emitter_name} is not supported"
|
194
201
|
end
|
195
202
|
|
196
|
-
#
|
197
|
-
# Deep copied emitters
|
198
203
|
#
|
199
204
|
# @return [Array<Mihari::Emitters::Base>]
|
200
205
|
#
|
201
206
|
def emitters
|
202
207
|
rule.emitters.map(&:deep_dup).map do |params|
|
203
208
|
name = params[:emitter]
|
204
|
-
params
|
209
|
+
options = params[:options]
|
210
|
+
|
211
|
+
%i[emitter options].each { |key| params.delete key }
|
205
212
|
|
206
213
|
klass = get_emitter_class(name)
|
207
|
-
klass.new(artifacts: enriched_artifacts, rule: rule, **params)
|
214
|
+
klass.new(artifacts: enriched_artifacts, rule: rule, options: options, **params)
|
208
215
|
end
|
209
216
|
end
|
210
217
|
|
@@ -215,6 +222,35 @@ module Mihari
|
|
215
222
|
emitters.select(&:valid?)
|
216
223
|
end
|
217
224
|
|
225
|
+
#
|
226
|
+
# Get enricher class
|
227
|
+
#
|
228
|
+
# @param [String] enricher_name
|
229
|
+
#
|
230
|
+
# @return [Class<Mihari::Enrichers::Base>] enricher class
|
231
|
+
#
|
232
|
+
def get_enricher_class(enricher_name)
|
233
|
+
enricher = ENRICHER_TO_CLASS[enricher_name]
|
234
|
+
return enricher if enricher
|
235
|
+
|
236
|
+
raise ArgumentError, "#{enricher_name} is not supported"
|
237
|
+
end
|
238
|
+
|
239
|
+
#
|
240
|
+
# @return [Array<Mihari::Enrichers::Base>] enrichers
|
241
|
+
#
|
242
|
+
def enrichers
|
243
|
+
@enrichers ||= rule.enrichers.map(&:deep_dup).map do |params|
|
244
|
+
name = params[:enricher]
|
245
|
+
options = params[:options]
|
246
|
+
|
247
|
+
%i[enricher options].each { |key| params.delete key }
|
248
|
+
|
249
|
+
klass = get_enricher_class(name)
|
250
|
+
klass.new(options: options, **params)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
218
254
|
#
|
219
255
|
# Validate configuration of analyzers
|
220
256
|
#
|
@@ -34,7 +34,11 @@ module Mihari
|
|
34
34
|
# @return [Clients::Shodan]
|
35
35
|
#
|
36
36
|
def client
|
37
|
-
@client ||= Clients::Shodan.new(
|
37
|
+
@client ||= Clients::Shodan.new(
|
38
|
+
api_key: api_key,
|
39
|
+
pagination_interval: pagination_interval,
|
40
|
+
timeout: timeout
|
41
|
+
)
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -44,7 +44,11 @@ module Mihari
|
|
44
44
|
private
|
45
45
|
|
46
46
|
def client
|
47
|
-
@client ||= Clients::UrlScan.new(
|
47
|
+
@client ||= Clients::UrlScan.new(
|
48
|
+
api_key: api_key,
|
49
|
+
pagination_interval: pagination_interval,
|
50
|
+
timeout: timeout
|
51
|
+
)
|
48
52
|
end
|
49
53
|
|
50
54
|
#
|
@@ -33,7 +33,11 @@ module Mihari
|
|
33
33
|
# @return [::VirusTotal::API]
|
34
34
|
#
|
35
35
|
def client
|
36
|
-
@client = Clients::VirusTotal.new(
|
36
|
+
@client = Clients::VirusTotal.new(
|
37
|
+
api_key: api_key,
|
38
|
+
pagination_interval: pagination_interval,
|
39
|
+
timeout: timeout
|
40
|
+
)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -53,7 +53,11 @@ module Mihari
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def client
|
56
|
-
@client ||= Clients::ZoomEye.new(
|
56
|
+
@client ||= Clients::ZoomEye.new(
|
57
|
+
api_key: api_key,
|
58
|
+
pagination_interval: pagination_interval,
|
59
|
+
timeout: timeout
|
60
|
+
)
|
57
61
|
end
|
58
62
|
|
59
63
|
#
|
data/lib/mihari/clients/base.rb
CHANGED
@@ -9,8 +9,8 @@ module Mihari
|
|
9
9
|
# @return [Hash]
|
10
10
|
attr_reader :headers
|
11
11
|
|
12
|
-
# @return [Integer
|
13
|
-
attr_reader :
|
12
|
+
# @return [Integer]
|
13
|
+
attr_reader :pagination_interval
|
14
14
|
|
15
15
|
# @return [Integer, nil]
|
16
16
|
attr_reader :timeout
|
@@ -18,20 +18,20 @@ module Mihari
|
|
18
18
|
#
|
19
19
|
# @param [String] base_url
|
20
20
|
# @param [Hash] headers
|
21
|
-
# @param [Integer
|
21
|
+
# @param [Integer] interval
|
22
22
|
# @param [Integer, nil] timeout
|
23
23
|
#
|
24
|
-
def initialize(base_url, headers: {},
|
24
|
+
def initialize(base_url, headers: {}, pagination_interval: 0, timeout: nil)
|
25
25
|
@base_url = base_url
|
26
26
|
@headers = headers || {}
|
27
|
-
@
|
27
|
+
@pagination_interval = pagination_interval
|
28
28
|
@timeout = timeout
|
29
29
|
end
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def
|
34
|
-
sleep
|
33
|
+
def sleep_pagination_interval
|
34
|
+
sleep pagination_interval
|
35
35
|
end
|
36
36
|
|
37
37
|
#
|
@@ -7,15 +7,21 @@ module Mihari
|
|
7
7
|
# @param [String] base_url
|
8
8
|
# @param [String, nil] api_key
|
9
9
|
# @param [Hash] headers
|
10
|
-
# @param [Integer
|
10
|
+
# @param [Integer] pagnation_interval
|
11
11
|
# @param [Integer, nil] timeout
|
12
12
|
#
|
13
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
base_url = "https://api.binaryedge.io/v2",
|
15
|
+
api_key:,
|
16
|
+
headers: {},
|
17
|
+
pagination_interval: 0,
|
18
|
+
timeout: nil
|
19
|
+
)
|
14
20
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
15
21
|
|
16
22
|
headers["x-key"] = api_key
|
17
23
|
|
18
|
-
super(base_url, headers: headers,
|
24
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
19
25
|
end
|
20
26
|
|
21
27
|
#
|
@@ -52,7 +58,7 @@ module Mihari
|
|
52
58
|
|
53
59
|
break if res.events.length < res.pagesize
|
54
60
|
|
55
|
-
|
61
|
+
sleep_pagination_interval
|
56
62
|
end
|
57
63
|
end
|
58
64
|
end
|
@@ -10,16 +10,23 @@ module Mihari
|
|
10
10
|
# @param [String, nil] id
|
11
11
|
# @param [String, nil] secret
|
12
12
|
# @param [Hash] headers
|
13
|
-
# @param [Integer
|
13
|
+
# @param [Integer] pagination_interval
|
14
14
|
# @param [Integer, nil] timeout
|
15
15
|
#
|
16
|
-
def initialize(
|
16
|
+
def initialize(
|
17
|
+
base_url = "https://search.censys.io",
|
18
|
+
id:,
|
19
|
+
secret:,
|
20
|
+
headers: {},
|
21
|
+
pagination_interval: 0,
|
22
|
+
timeout: nil
|
23
|
+
)
|
17
24
|
raise(ArgumentError, "'id' argument is required") if id.nil?
|
18
25
|
raise(ArgumentError, "'secret' argument is required") if secret.nil?
|
19
26
|
|
20
27
|
headers["authorization"] = "Basic #{Base64.strict_encode64("#{id}:#{secret}")}"
|
21
28
|
|
22
|
-
super(base_url, headers: headers,
|
29
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
23
30
|
end
|
24
31
|
|
25
32
|
#
|
@@ -64,7 +71,7 @@ module Mihari
|
|
64
71
|
# So it needs to check both cases
|
65
72
|
break if cursor.nil? || cursor.empty?
|
66
73
|
|
67
|
-
|
74
|
+
sleep_pagination_interval
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
@@ -9,14 +9,20 @@ module Mihari
|
|
9
9
|
# @param [String] base_url
|
10
10
|
# @param [String, nil] api_key
|
11
11
|
# @param [Hash] headers
|
12
|
-
# @param [Integer
|
12
|
+
# @param [Integer] pagination_interval
|
13
13
|
# @param [Integer, nil] timeout
|
14
14
|
#
|
15
|
-
def initialize(
|
15
|
+
def initialize(
|
16
|
+
base_url = "https://api.greynoise.io",
|
17
|
+
api_key:,
|
18
|
+
headers: {},
|
19
|
+
pagination_interval: 0,
|
20
|
+
timeout: nil
|
21
|
+
)
|
16
22
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
17
23
|
|
18
24
|
headers["key"] = api_key
|
19
|
-
super(base_url, headers: headers,
|
25
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
20
26
|
end
|
21
27
|
|
22
28
|
#
|
@@ -53,7 +59,7 @@ module Mihari
|
|
53
59
|
scroll = res.scroll
|
54
60
|
break if scroll.nil?
|
55
61
|
|
56
|
-
|
62
|
+
sleep_pagination_interval
|
57
63
|
end
|
58
64
|
end
|
59
65
|
end
|
@@ -14,13 +14,19 @@ module Mihari
|
|
14
14
|
# @param [String] base_url
|
15
15
|
# @param [String, nil] api_key
|
16
16
|
# @param [Hash] headers
|
17
|
-
# @param [Integer
|
17
|
+
# @param [Integer] pagination_interval
|
18
18
|
# @param [Integer, nil] timeout
|
19
19
|
#
|
20
|
-
def initialize(
|
20
|
+
def initialize(
|
21
|
+
base_url = "https://api.hunter.how/",
|
22
|
+
api_key:,
|
23
|
+
headers: {},
|
24
|
+
pagination_interval: 0,
|
25
|
+
timeout: nil
|
26
|
+
)
|
21
27
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
22
28
|
|
23
|
-
super(base_url, headers: headers,
|
29
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
24
30
|
|
25
31
|
@api_key = api_key
|
26
32
|
end
|
@@ -77,7 +83,7 @@ module Mihari
|
|
77
83
|
|
78
84
|
break if res.data.list.length < page_size
|
79
85
|
|
80
|
-
|
86
|
+
sleep_pagination_interval
|
81
87
|
end
|
82
88
|
end
|
83
89
|
end
|
data/lib/mihari/clients/misp.rb
CHANGED
@@ -7,14 +7,15 @@ 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, api_key:, headers: {})
|
12
|
+
def initialize(base_url, api_key:, headers: {}, timeout: nil)
|
12
13
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
13
14
|
|
14
15
|
headers["authorization"] = api_key
|
15
16
|
headers["accept"] = "application/json"
|
16
17
|
|
17
|
-
super(base_url, headers: headers)
|
18
|
+
super(base_url, headers: headers, timeout: timeout)
|
18
19
|
end
|
19
20
|
|
20
21
|
#
|
@@ -12,13 +12,19 @@ module Mihari
|
|
12
12
|
# @param [String] base_url
|
13
13
|
# @param [String, nil] api_key
|
14
14
|
# @param [Hash] headers
|
15
|
-
# @param [Integer
|
15
|
+
# @param [Integer] pagination_interval
|
16
16
|
# @param [Integer, nil] timeout
|
17
17
|
#
|
18
|
-
def initialize(
|
18
|
+
def initialize(
|
19
|
+
base_url = "https://www.onyphe.io",
|
20
|
+
api_key:,
|
21
|
+
headers: {},
|
22
|
+
pagination_interval: 0,
|
23
|
+
timeout: nil
|
24
|
+
)
|
19
25
|
raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
|
20
26
|
|
21
|
-
super(base_url, headers: headers,
|
27
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
22
28
|
|
23
29
|
@api_key = api_key
|
24
30
|
end
|
@@ -50,7 +56,7 @@ module Mihari
|
|
50
56
|
|
51
57
|
break if res.total <= page * PAGE_SIZE
|
52
58
|
|
53
|
-
|
59
|
+
sleep_pagination_interval
|
54
60
|
end
|
55
61
|
end
|
56
62
|
end
|
@@ -12,13 +12,19 @@ module Mihari
|
|
12
12
|
# @param [String] base_url
|
13
13
|
# @param [String, nil] api_key
|
14
14
|
# @param [Hash] headers
|
15
|
-
# @param [Integer
|
15
|
+
# @param [Integer] pagination_interval
|
16
16
|
# @param [Integer, nil] timeout
|
17
17
|
#
|
18
|
-
def initialize(
|
18
|
+
def initialize(
|
19
|
+
base_url = "https://api.shodan.io",
|
20
|
+
api_key:,
|
21
|
+
headers: {},
|
22
|
+
pagination_interval: 0,
|
23
|
+
timeout: nil
|
24
|
+
)
|
19
25
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
20
26
|
|
21
|
-
super(base_url, headers: headers,
|
27
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
22
28
|
|
23
29
|
@api_key = api_key
|
24
30
|
end
|
@@ -57,7 +63,7 @@ module Mihari
|
|
57
63
|
|
58
64
|
break if res.total <= page * PAGE_SIZE
|
59
65
|
|
60
|
-
|
66
|
+
sleep_pagination_interval
|
61
67
|
rescue JSON::ParserError
|
62
68
|
# ignore JSON::ParserError
|
63
69
|
# ref. https://github.com/ninoseki/mihari/issues/197
|
@@ -8,14 +8,15 @@ module Mihari
|
|
8
8
|
# @param [String, nil] api_key
|
9
9
|
# @param [String, nil] api_version
|
10
10
|
# @param [Hash] headers
|
11
|
+
# @param [Integer, nil] timeout
|
11
12
|
#
|
12
|
-
def initialize(base_url, api_key:, api_version:, headers: {})
|
13
|
+
def initialize(base_url, api_key:, api_version:, headers: {}, timeout: nil)
|
13
14
|
raise(ArgumentError, "'api_key' argument is required") unless api_key
|
14
15
|
|
15
16
|
base_url += "/#{api_version}" unless api_version.nil?
|
16
17
|
headers["authorization"] = "Bearer #{api_key}"
|
17
18
|
|
18
|
-
super(base_url, headers: headers)
|
19
|
+
super(base_url, headers: headers, timeout: timeout)
|
19
20
|
end
|
20
21
|
|
21
22
|
#
|
@@ -10,12 +10,18 @@ module Mihari
|
|
10
10
|
# @param [Interval, nil] interval
|
11
11
|
# @param [Interval, nil] timeout
|
12
12
|
#
|
13
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
base_url = "https://urlscan.io",
|
15
|
+
api_key:,
|
16
|
+
headers: {},
|
17
|
+
pagination_interval: 0,
|
18
|
+
timeout: nil
|
19
|
+
)
|
14
20
|
raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
|
15
21
|
|
16
22
|
headers["api-key"] = api_key
|
17
23
|
|
18
|
-
super(base_url, headers: headers,
|
24
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
19
25
|
end
|
20
26
|
|
21
27
|
#
|
@@ -51,7 +57,7 @@ module Mihari
|
|
51
57
|
|
52
58
|
search_after = res.results.last.sort.join(",")
|
53
59
|
|
54
|
-
|
60
|
+
sleep_pagination_interval
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
@@ -7,15 +7,21 @@ module Mihari
|
|
7
7
|
# @param [String] base_url
|
8
8
|
# @param [String, nil] api_key
|
9
9
|
# @param [Hash] headers
|
10
|
-
# @param [Integer
|
10
|
+
# @param [Integer] pagination_interval
|
11
11
|
# @param [Integer, nil] timeout
|
12
12
|
#
|
13
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
base_url = "https://www.virustotal.com",
|
15
|
+
api_key:,
|
16
|
+
headers: {},
|
17
|
+
pagination_interval: 0,
|
18
|
+
timeout: nil
|
19
|
+
)
|
14
20
|
raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
|
15
21
|
|
16
22
|
headers["x-apikey"] = api_key
|
17
23
|
|
18
|
-
super(base_url, headers: headers,
|
24
|
+
super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
|
19
25
|
end
|
20
26
|
|
21
27
|
#
|
@@ -66,7 +72,7 @@ module Mihari
|
|
66
72
|
cursor = res.meta.cursor
|
67
73
|
break if cursor.nil?
|
68
74
|
|
69
|
-
|
75
|
+
sleep_pagination_interval
|
70
76
|
end
|
71
77
|
end
|
72
78
|
end
|