mihari 2.4.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/.overcommit.yml +12 -0
- data/README.md +1 -9
- data/build_frontend.sh +5 -0
- data/docker/Dockerfile +1 -1
- data/exe/mihari +1 -1
- data/lib/mihari.rb +89 -15
- data/lib/mihari/analyzers/base.rb +49 -8
- data/lib/mihari/analyzers/basic.rb +1 -2
- data/lib/mihari/analyzers/binaryedge.rb +7 -13
- data/lib/mihari/analyzers/censys.rb +26 -63
- data/lib/mihari/analyzers/circl.rb +20 -17
- data/lib/mihari/analyzers/crtsh.rb +6 -13
- data/lib/mihari/analyzers/dnpedia.rb +6 -12
- data/lib/mihari/analyzers/dnstwister.rb +13 -10
- data/lib/mihari/analyzers/onyphe.rb +6 -12
- data/lib/mihari/analyzers/otx.rb +22 -19
- data/lib/mihari/analyzers/passivetotal.rb +22 -21
- data/lib/mihari/analyzers/pulsedive.rb +16 -13
- data/lib/mihari/analyzers/rule.rb +97 -0
- data/lib/mihari/analyzers/securitytrails.rb +22 -19
- data/lib/mihari/analyzers/shodan.rb +7 -13
- data/lib/mihari/analyzers/spyse.rb +12 -19
- data/lib/mihari/analyzers/urlscan.rb +22 -27
- data/lib/mihari/analyzers/virustotal.rb +25 -22
- data/lib/mihari/analyzers/zoomeye.rb +14 -20
- data/lib/mihari/cli/analyzer.rb +44 -0
- data/lib/mihari/cli/base.rb +27 -0
- data/lib/mihari/cli/init.rb +13 -0
- data/lib/mihari/cli/main.rb +30 -0
- data/lib/mihari/cli/mixins/utils.rb +88 -0
- data/lib/mihari/cli/validator.rb +11 -0
- data/lib/mihari/commands/binaryedge.rb +1 -1
- data/lib/mihari/commands/censys.rb +1 -1
- data/lib/mihari/commands/circl.rb +2 -2
- data/lib/mihari/commands/crtsh.rb +1 -1
- data/lib/mihari/commands/dnpedia.rb +1 -1
- data/lib/mihari/commands/dnstwister.rb +2 -2
- data/lib/mihari/commands/init.rb +46 -0
- data/lib/mihari/commands/json.rb +1 -1
- data/lib/mihari/commands/onyphe.rb +1 -1
- data/lib/mihari/commands/otx.rb +2 -2
- data/lib/mihari/commands/passivetotal.rb +2 -2
- data/lib/mihari/commands/pulsedive.rb +2 -2
- data/lib/mihari/commands/search.rb +77 -0
- data/lib/mihari/commands/securitytrails.rb +2 -2
- data/lib/mihari/commands/shodan.rb +1 -1
- data/lib/mihari/commands/spyse.rb +1 -1
- data/lib/mihari/commands/urlscan.rb +2 -2
- data/lib/mihari/commands/validator.rb +38 -0
- data/lib/mihari/commands/virustotal.rb +2 -2
- data/lib/mihari/commands/zoomeye.rb +1 -1
- data/lib/mihari/constraints.rb +5 -0
- data/lib/mihari/database.rb +13 -2
- data/lib/mihari/emitters/base.rb +2 -2
- data/lib/mihari/emitters/database.rb +1 -1
- data/lib/mihari/emitters/misp.rb +3 -1
- data/lib/mihari/emitters/slack.rb +6 -7
- data/lib/mihari/emitters/the_hive.rb +1 -1
- data/lib/mihari/emitters/webhook.rb +2 -9
- data/lib/mihari/mixins/configurable.rb +38 -0
- data/lib/mihari/mixins/configuration.rb +90 -0
- data/lib/mihari/mixins/hash.rb +20 -0
- data/lib/mihari/mixins/refang.rb +21 -0
- data/lib/mihari/mixins/retriable.rb +27 -0
- data/lib/mihari/mixins/rule.rb +79 -0
- data/lib/mihari/models/alert.rb +28 -1
- data/lib/mihari/models/artifact.rb +11 -1
- data/lib/mihari/notifiers/base.rb +9 -1
- data/lib/mihari/notifiers/exception_notifier.rb +50 -0
- data/lib/mihari/notifiers/slack.rb +29 -0
- data/lib/mihari/schemas/analyzer.rb +25 -0
- data/lib/mihari/schemas/configuration.rb +42 -0
- data/lib/mihari/schemas/macros.rb +17 -0
- data/lib/mihari/schemas/rule.rb +72 -0
- data/lib/mihari/serializers/artifact.rb +1 -1
- data/lib/mihari/status.rb +14 -0
- data/lib/mihari/templates/rule.yml.erb +19 -0
- data/lib/mihari/type_checker.rb +8 -3
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +2 -1
- data/lib/mihari/web/controllers/analyzers_controller.rb +38 -0
- data/lib/mihari/web/controllers/base_controller.rb +1 -1
- data/lib/mihari/web/public/index.html +1 -21
- data/lib/mihari/web/public/redoc-static.html +338 -461
- data/lib/mihari/web/public/static/js/app.365f1907.js +13 -0
- data/lib/mihari/web/public/static/js/app.365f1907.js.map +1 -0
- data/lib/mihari/web/public/static/js/app.ab213f7c.js +12 -0
- data/lib/mihari/web/public/static/js/app.ab213f7c.js.map +1 -0
- data/mihari.gemspec +16 -9
- metadata +135 -58
- data/.rubocop.yml +0 -161
- data/lib/mihari/analyzers/free_text.rb +0 -48
- data/lib/mihari/analyzers/http_hash.rb +0 -100
- data/lib/mihari/analyzers/passive_dns.rb +0 -59
- data/lib/mihari/analyzers/passive_ssl.rb +0 -55
- data/lib/mihari/analyzers/reverse_whois.rb +0 -55
- data/lib/mihari/analyzers/securitytrails_domain_feed.rb +0 -59
- data/lib/mihari/analyzers/ssh_fingerprint.rb +0 -58
- data/lib/mihari/cli.rb +0 -126
- data/lib/mihari/commands/config.rb +0 -27
- data/lib/mihari/commands/free_text.rb +0 -21
- data/lib/mihari/commands/http_hash.rb +0 -25
- data/lib/mihari/commands/passive_dns.rb +0 -21
- data/lib/mihari/commands/passive_ssl.rb +0 -21
- data/lib/mihari/commands/reverse_whois.rb +0 -21
- data/lib/mihari/commands/securitytrails_domain_feed.rb +0 -23
- data/lib/mihari/commands/ssh_fingerprint.rb +0 -21
- data/lib/mihari/config.rb +0 -85
- data/lib/mihari/configurable.rb +0 -21
- data/lib/mihari/html.rb +0 -43
- data/lib/mihari/retriable.rb +0 -17
|
@@ -5,26 +5,29 @@ require "securitytrails"
|
|
|
5
5
|
module Mihari
|
|
6
6
|
module Analyzers
|
|
7
7
|
class SecurityTrails < Base
|
|
8
|
-
|
|
8
|
+
include Mixins::Refang
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
param :query
|
|
11
|
+
option :title, default: proc { "SecurityTrails search" }
|
|
12
|
+
option :description, default: proc { "query = #{query}" }
|
|
13
|
+
option :tags, default: proc { [] }
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
attr_reader :type
|
|
16
|
+
|
|
17
|
+
def initialize(*args, **kwargs)
|
|
18
|
+
super
|
|
15
19
|
|
|
16
|
-
@
|
|
17
|
-
@
|
|
18
|
-
@tags = tags
|
|
20
|
+
@query = refang(query)
|
|
21
|
+
@type = TypeChecker.type(query)
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def artifacts
|
|
22
|
-
|
|
25
|
+
search || []
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
private
|
|
26
29
|
|
|
27
|
-
def
|
|
30
|
+
def configuration_keys
|
|
28
31
|
%w[securitytrails_api_key]
|
|
29
32
|
end
|
|
30
33
|
|
|
@@ -36,20 +39,20 @@ module Mihari
|
|
|
36
39
|
%w[ip domain mail].include? type
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
def
|
|
42
|
+
def search
|
|
40
43
|
case type
|
|
41
44
|
when "domain"
|
|
42
|
-
|
|
45
|
+
domain_search
|
|
43
46
|
when "ip"
|
|
44
|
-
|
|
47
|
+
ip_search
|
|
45
48
|
when "mail"
|
|
46
|
-
|
|
49
|
+
mail_search
|
|
47
50
|
else
|
|
48
51
|
raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
|
|
49
52
|
end
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
def
|
|
55
|
+
def domain_search
|
|
53
56
|
result = api.history.get_all_dns_history(query, type: "a")
|
|
54
57
|
records = result["records"] || []
|
|
55
58
|
records.map do |record|
|
|
@@ -57,16 +60,16 @@ module Mihari
|
|
|
57
60
|
end.flatten.compact.uniq
|
|
58
61
|
end
|
|
59
62
|
|
|
60
|
-
def
|
|
63
|
+
def ip_search
|
|
61
64
|
result = api.domains.search(filter: { ipv4: query })
|
|
62
65
|
records = result["records"] || []
|
|
63
|
-
records.
|
|
66
|
+
records.filter_map { |record| record["hostname"] }.uniq
|
|
64
67
|
end
|
|
65
68
|
|
|
66
|
-
def
|
|
69
|
+
def mail_search
|
|
67
70
|
result = api.domains.search(filter: { whois_email: query })
|
|
68
71
|
records = result["records"] || []
|
|
69
|
-
records.
|
|
72
|
+
records.filter_map { |record| record["hostname"] }.uniq
|
|
70
73
|
end
|
|
71
74
|
end
|
|
72
75
|
end
|
|
@@ -5,16 +5,10 @@ require "shodan"
|
|
|
5
5
|
module Mihari
|
|
6
6
|
module Analyzers
|
|
7
7
|
class Shodan < Base
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@query = query
|
|
14
|
-
@title = title || "Shodan lookup"
|
|
15
|
-
@description = description || "query = #{query}"
|
|
16
|
-
@tags = tags
|
|
17
|
-
end
|
|
8
|
+
param :query
|
|
9
|
+
option :title, default: proc { "Shodan search" }
|
|
10
|
+
option :description, default: proc { "query = #{query}" }
|
|
11
|
+
option :tags, default: proc { [] }
|
|
18
12
|
|
|
19
13
|
def artifacts
|
|
20
14
|
results = search
|
|
@@ -22,9 +16,9 @@ module Mihari
|
|
|
22
16
|
|
|
23
17
|
results.map do |result|
|
|
24
18
|
matches = result["matches"] || []
|
|
25
|
-
matches.
|
|
19
|
+
matches.filter_map do |match|
|
|
26
20
|
match["ip_str"]
|
|
27
|
-
end
|
|
21
|
+
end
|
|
28
22
|
end.flatten.compact.uniq
|
|
29
23
|
end
|
|
30
24
|
|
|
@@ -32,7 +26,7 @@ module Mihari
|
|
|
32
26
|
|
|
33
27
|
PAGE_SIZE = 100
|
|
34
28
|
|
|
35
|
-
def
|
|
29
|
+
def configuration_keys
|
|
36
30
|
%w[shodan_api_key]
|
|
37
31
|
end
|
|
38
32
|
|
|
@@ -6,21 +6,14 @@ require "json"
|
|
|
6
6
|
module Mihari
|
|
7
7
|
module Analyzers
|
|
8
8
|
class Spyse < Base
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@query = query
|
|
15
|
-
|
|
16
|
-
@title = title || "Spyse lookup"
|
|
17
|
-
@description = description || "query = #{query}"
|
|
18
|
-
@tags = tags
|
|
19
|
-
@type = type
|
|
20
|
-
end
|
|
9
|
+
param :query
|
|
10
|
+
option :title, default: proc { "Spyse search" }
|
|
11
|
+
option :description, default: proc { "query = #{query}" }
|
|
12
|
+
option :type, default: proc { "domain" }
|
|
13
|
+
option :tags, default: proc { [] }
|
|
21
14
|
|
|
22
15
|
def artifacts
|
|
23
|
-
|
|
16
|
+
search || []
|
|
24
17
|
end
|
|
25
18
|
|
|
26
19
|
private
|
|
@@ -29,7 +22,7 @@ module Mihari
|
|
|
29
22
|
@search_params ||= JSON.parse(query)
|
|
30
23
|
end
|
|
31
24
|
|
|
32
|
-
def
|
|
25
|
+
def configuration_keys
|
|
33
26
|
%w[spyse_api_key]
|
|
34
27
|
end
|
|
35
28
|
|
|
@@ -41,7 +34,7 @@ module Mihari
|
|
|
41
34
|
%w[ip domain cert].include? type
|
|
42
35
|
end
|
|
43
36
|
|
|
44
|
-
def
|
|
37
|
+
def domain_search
|
|
45
38
|
res = api.domain.search(search_params, limit: 100)
|
|
46
39
|
items = res.dig("data", "items") || []
|
|
47
40
|
items.map do |item|
|
|
@@ -49,7 +42,7 @@ module Mihari
|
|
|
49
42
|
end.uniq.compact
|
|
50
43
|
end
|
|
51
44
|
|
|
52
|
-
def
|
|
45
|
+
def ip_search
|
|
53
46
|
res = api.ip.search(search_params, limit: 100)
|
|
54
47
|
items = res.dig("data", "items") || []
|
|
55
48
|
items.map do |item|
|
|
@@ -57,12 +50,12 @@ module Mihari
|
|
|
57
50
|
end.uniq.compact
|
|
58
51
|
end
|
|
59
52
|
|
|
60
|
-
def
|
|
53
|
+
def search
|
|
61
54
|
case type
|
|
62
55
|
when "domain"
|
|
63
|
-
|
|
56
|
+
domain_search
|
|
64
57
|
when "ip"
|
|
65
|
-
|
|
58
|
+
ip_search
|
|
66
59
|
else
|
|
67
60
|
raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
|
|
68
61
|
end
|
|
@@ -2,30 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
require "urlscan"
|
|
4
4
|
|
|
5
|
+
SUPPORTED_DATA_TYPES = %w[url domain ip].freeze
|
|
6
|
+
|
|
5
7
|
module Mihari
|
|
6
8
|
module Analyzers
|
|
7
9
|
class Urlscan < Base
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@query = query
|
|
21
|
-
@title = title || "urlscan lookup"
|
|
22
|
-
@description = description || "query = #{query}"
|
|
23
|
-
@tags = tags
|
|
24
|
-
|
|
25
|
-
@target_type = target_type
|
|
26
|
-
@use_similarity = use_similarity
|
|
27
|
-
|
|
28
|
-
raise InvalidInputError, "type should be url, domain or ip." unless valid_target_type?
|
|
10
|
+
param :query
|
|
11
|
+
option :title, default: proc { "urlscan search" }
|
|
12
|
+
option :description, default: proc { "query = #{query}" }
|
|
13
|
+
option :tags, default: proc { [] }
|
|
14
|
+
option :allowed_data_types, default: proc { SUPPORTED_DATA_TYPES }
|
|
15
|
+
option :use_similarity, default: proc { false }
|
|
16
|
+
|
|
17
|
+
def initialize(*args, **kwargs)
|
|
18
|
+
super
|
|
19
|
+
|
|
20
|
+
raise InvalidInputError, "allowed_data_types should be any of url, domain and ip." unless valid_alllowed_data_types?
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
def artifacts
|
|
@@ -33,14 +25,17 @@ module Mihari
|
|
|
33
25
|
return [] unless result
|
|
34
26
|
|
|
35
27
|
results = result["results"] || []
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
|
|
29
|
+
allowed_data_types.map do |type|
|
|
30
|
+
results.filter_map do |match|
|
|
31
|
+
match.dig "page", type
|
|
32
|
+
end.uniq
|
|
33
|
+
end.flatten
|
|
39
34
|
end
|
|
40
35
|
|
|
41
36
|
private
|
|
42
37
|
|
|
43
|
-
def
|
|
38
|
+
def configuration_keys
|
|
44
39
|
%w[urlscan_api_key]
|
|
45
40
|
end
|
|
46
41
|
|
|
@@ -54,8 +49,8 @@ module Mihari
|
|
|
54
49
|
api.search(query, size: 10_000)
|
|
55
50
|
end
|
|
56
51
|
|
|
57
|
-
def
|
|
58
|
-
|
|
52
|
+
def valid_alllowed_data_types?
|
|
53
|
+
allowed_data_types.all? { |type| SUPPORTED_DATA_TYPES.include? type }
|
|
59
54
|
end
|
|
60
55
|
end
|
|
61
56
|
end
|
|
@@ -5,26 +5,29 @@ require "virustotal"
|
|
|
5
5
|
module Mihari
|
|
6
6
|
module Analyzers
|
|
7
7
|
class VirusTotal < Base
|
|
8
|
-
|
|
8
|
+
include Mixins::Refang
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
param :query
|
|
11
|
+
option :title, default: proc { "VirusTotal search" }
|
|
12
|
+
option :description, default: proc { "query = #{query}" }
|
|
13
|
+
option :tags, default: proc { [] }
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
@type = TypeChecker.type(indicator)
|
|
15
|
+
attr_reader :type
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
def initialize(*args, **kwargs)
|
|
18
|
+
super
|
|
19
|
+
|
|
20
|
+
@query = refang(query)
|
|
21
|
+
@type = TypeChecker.type(query)
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def artifacts
|
|
22
|
-
|
|
25
|
+
search || []
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
private
|
|
26
29
|
|
|
27
|
-
def
|
|
30
|
+
def configuration_keys
|
|
28
31
|
%w[virustotal_api_key]
|
|
29
32
|
end
|
|
30
33
|
|
|
@@ -36,33 +39,33 @@ module Mihari
|
|
|
36
39
|
%w[ip domain].include? type
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
def
|
|
42
|
+
def search
|
|
40
43
|
case type
|
|
41
44
|
when "domain"
|
|
42
|
-
|
|
45
|
+
domain_search
|
|
43
46
|
when "ip"
|
|
44
|
-
|
|
47
|
+
ip_search
|
|
45
48
|
else
|
|
46
|
-
raise InvalidInputError, "#{
|
|
49
|
+
raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
|
|
50
|
-
def
|
|
51
|
-
res = api.domain.resolutions(
|
|
53
|
+
def domain_search
|
|
54
|
+
res = api.domain.resolutions(query)
|
|
52
55
|
|
|
53
56
|
data = res["data"] || []
|
|
54
|
-
data.
|
|
57
|
+
data.filter_map do |item|
|
|
55
58
|
item.dig("attributes", "ip_address")
|
|
56
|
-
end.
|
|
59
|
+
end.uniq
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
def
|
|
60
|
-
res = api.ip_address.resolutions(
|
|
62
|
+
def ip_search
|
|
63
|
+
res = api.ip_address.resolutions(query)
|
|
61
64
|
|
|
62
65
|
data = res["data"] || []
|
|
63
|
-
data.
|
|
66
|
+
data.filter_map do |item|
|
|
64
67
|
item.dig("attributes", "host_name")
|
|
65
|
-
end.
|
|
68
|
+
end.uniq
|
|
66
69
|
end
|
|
67
70
|
end
|
|
68
71
|
end
|
|
@@ -5,24 +5,18 @@ require "zoomeye"
|
|
|
5
5
|
module Mihari
|
|
6
6
|
module Analyzers
|
|
7
7
|
class ZoomEye < Base
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@query = query
|
|
14
|
-
@title = title || "ZoomEye lookup"
|
|
15
|
-
@description = description || "query = #{query}"
|
|
16
|
-
@tags = tags
|
|
17
|
-
@type = type
|
|
18
|
-
end
|
|
8
|
+
param :query
|
|
9
|
+
option :title, default: proc { "ZoomEye search" }
|
|
10
|
+
option :description, default: proc { "query = #{query}" }
|
|
11
|
+
option :tags, default: proc { [] }
|
|
12
|
+
option :type, default: proc { "host" }
|
|
19
13
|
|
|
20
14
|
def artifacts
|
|
21
15
|
case type
|
|
22
16
|
when "host"
|
|
23
|
-
|
|
17
|
+
host_search
|
|
24
18
|
when "web"
|
|
25
|
-
|
|
19
|
+
web_search
|
|
26
20
|
else
|
|
27
21
|
raise InvalidInputError, "#{type} type is not supported." unless valid_type?
|
|
28
22
|
end
|
|
@@ -36,7 +30,7 @@ module Mihari
|
|
|
36
30
|
%w[host web].include? type
|
|
37
31
|
end
|
|
38
32
|
|
|
39
|
-
def
|
|
33
|
+
def configuration_keys
|
|
40
34
|
%w[zoomeye_api_key]
|
|
41
35
|
end
|
|
42
36
|
|
|
@@ -53,16 +47,16 @@ module Mihari
|
|
|
53
47
|
end.flatten.compact.uniq
|
|
54
48
|
end
|
|
55
49
|
|
|
56
|
-
def
|
|
50
|
+
def _host_search(query, page: 1)
|
|
57
51
|
api.host.search(query, page: page)
|
|
58
52
|
rescue ::ZoomEye::Error => _e
|
|
59
53
|
nil
|
|
60
54
|
end
|
|
61
55
|
|
|
62
|
-
def
|
|
56
|
+
def host_search
|
|
63
57
|
responses = []
|
|
64
58
|
(1..Float::INFINITY).each do |page|
|
|
65
|
-
res =
|
|
59
|
+
res = _host_search(query, page: page)
|
|
66
60
|
break unless res
|
|
67
61
|
|
|
68
62
|
total = res["total"].to_i
|
|
@@ -72,16 +66,16 @@ module Mihari
|
|
|
72
66
|
convert_responses responses.compact
|
|
73
67
|
end
|
|
74
68
|
|
|
75
|
-
def
|
|
69
|
+
def _web_search(query, page: 1)
|
|
76
70
|
api.web.search(query, page: page)
|
|
77
71
|
rescue ::ZoomEye::Error => _e
|
|
78
72
|
nil
|
|
79
73
|
end
|
|
80
74
|
|
|
81
|
-
def
|
|
75
|
+
def web_search
|
|
82
76
|
responses = []
|
|
83
77
|
(1..Float::INFINITY).each do |page|
|
|
84
|
-
res =
|
|
78
|
+
res = _web_search(query, page: page)
|
|
85
79
|
break unless res
|
|
86
80
|
|
|
87
81
|
total = res["total"].to_i
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mihari/commands/binaryedge"
|
|
4
|
+
require "mihari/commands/censys"
|
|
5
|
+
require "mihari/commands/circl"
|
|
6
|
+
require "mihari/commands/crtsh"
|
|
7
|
+
require "mihari/commands/dnpedia"
|
|
8
|
+
require "mihari/commands/dnstwister"
|
|
9
|
+
require "mihari/commands/onyphe"
|
|
10
|
+
require "mihari/commands/otx"
|
|
11
|
+
require "mihari/commands/passivetotal"
|
|
12
|
+
require "mihari/commands/pulsedive"
|
|
13
|
+
require "mihari/commands/securitytrails"
|
|
14
|
+
require "mihari/commands/shodan"
|
|
15
|
+
require "mihari/commands/spyse"
|
|
16
|
+
require "mihari/commands/urlscan"
|
|
17
|
+
require "mihari/commands/virustotal"
|
|
18
|
+
require "mihari/commands/zoomeye"
|
|
19
|
+
|
|
20
|
+
require "mihari/commands/json"
|
|
21
|
+
|
|
22
|
+
module Mihari
|
|
23
|
+
module CLI
|
|
24
|
+
class Analyzer < Base
|
|
25
|
+
include Mihari::Commands::BinaryEdge
|
|
26
|
+
include Mihari::Commands::Censys
|
|
27
|
+
include Mihari::Commands::CIRCL
|
|
28
|
+
include Mihari::Commands::Crtsh
|
|
29
|
+
include Mihari::Commands::DNPedia
|
|
30
|
+
include Mihari::Commands::DNSTwister
|
|
31
|
+
include Mihari::Commands::JSON
|
|
32
|
+
include Mihari::Commands::Onyphe
|
|
33
|
+
include Mihari::Commands::OTX
|
|
34
|
+
include Mihari::Commands::PassiveTotal
|
|
35
|
+
include Mihari::Commands::Pulsedive
|
|
36
|
+
include Mihari::Commands::SecurityTrails
|
|
37
|
+
include Mihari::Commands::Shodan
|
|
38
|
+
include Mihari::Commands::Spyse
|
|
39
|
+
include Mihari::Commands::Urlscan
|
|
40
|
+
include Mihari::Commands::VirusTotal
|
|
41
|
+
include Mihari::Commands::ZoomEye
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|