mihari 3.10.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/docker/Dockerfile +1 -1
  4. data/lib/mihari/analyzers/base.rb +7 -7
  5. data/lib/mihari/analyzers/binaryedge.rb +8 -5
  6. data/lib/mihari/analyzers/censys.rb +6 -3
  7. data/lib/mihari/analyzers/circl.rb +0 -3
  8. data/lib/mihari/analyzers/crtsh.rb +7 -5
  9. data/lib/mihari/analyzers/dnpedia.rb +4 -4
  10. data/lib/mihari/analyzers/dnstwister.rb +1 -4
  11. data/lib/mihari/analyzers/feed.rb +36 -0
  12. data/lib/mihari/analyzers/greynoise.rb +1 -3
  13. data/lib/mihari/analyzers/onyphe.rb +6 -3
  14. data/lib/mihari/analyzers/otx.rb +0 -3
  15. data/lib/mihari/analyzers/passivetotal.rb +8 -9
  16. data/lib/mihari/analyzers/pulsedive.rb +7 -5
  17. data/lib/mihari/analyzers/rule.rb +11 -5
  18. data/lib/mihari/analyzers/securitytrails.rb +10 -7
  19. data/lib/mihari/analyzers/shodan.rb +15 -8
  20. data/lib/mihari/analyzers/spyse.rb +10 -11
  21. data/lib/mihari/analyzers/urlscan.rb +39 -16
  22. data/lib/mihari/analyzers/virustotal.rb +8 -9
  23. data/lib/mihari/analyzers/virustotal_intelligence.rb +9 -5
  24. data/lib/mihari/analyzers/zoomeye.rb +12 -5
  25. data/lib/mihari/cli/base.rb +0 -5
  26. data/lib/mihari/cli/init.rb +0 -2
  27. data/lib/mihari/cli/main.rb +4 -6
  28. data/lib/mihari/cli/mixins/utils.rb +2 -18
  29. data/lib/mihari/commands/init.rb +0 -18
  30. data/lib/mihari/commands/search.rb +20 -15
  31. data/lib/mihari/commands/validator.rb +7 -19
  32. data/lib/mihari/commands/web.rb +0 -3
  33. data/lib/mihari/database.rb +71 -19
  34. data/lib/mihari/emitters/misp.rb +0 -1
  35. data/lib/mihari/emitters/slack.rb +3 -4
  36. data/lib/mihari/emitters/stdout.rb +0 -2
  37. data/lib/mihari/emitters/the_hive.rb +0 -1
  38. data/lib/mihari/emitters/webhook.rb +1 -5
  39. data/lib/mihari/enrichers/ipinfo.rb +2 -2
  40. data/lib/mihari/errors.rb +6 -0
  41. data/lib/mihari/feed/parser.rb +34 -0
  42. data/lib/mihari/feed/reader.rb +127 -0
  43. data/lib/mihari/mixins/autonomous_system.rb +2 -0
  44. data/lib/mihari/mixins/database.rb +14 -0
  45. data/lib/mihari/mixins/disallowed_data_value.rb +2 -3
  46. data/lib/mihari/mixins/rule.rb +36 -31
  47. data/lib/mihari/models/alert.rb +7 -8
  48. data/lib/mihari/models/artifact.rb +1 -7
  49. data/lib/mihari/models/autonomous_system.rb +0 -2
  50. data/lib/mihari/models/dns.rb +2 -5
  51. data/lib/mihari/models/geolocation.rb +0 -1
  52. data/lib/mihari/models/reverse_dns.rb +0 -3
  53. data/lib/mihari/models/rule.rb +73 -0
  54. data/lib/mihari/models/tag.rb +0 -2
  55. data/lib/mihari/models/tagging.rb +0 -2
  56. data/lib/mihari/models/whois.rb +0 -2
  57. data/lib/mihari/notifiers/exception_notifier.rb +0 -2
  58. data/lib/mihari/schemas/analyzer.rb +0 -5
  59. data/lib/mihari/schemas/macros.rb +0 -2
  60. data/lib/mihari/schemas/rule.rb +21 -7
  61. data/lib/mihari/status.rb +2 -2
  62. data/lib/mihari/structs/alert.rb +2 -3
  63. data/lib/mihari/structs/censys.rb +4 -3
  64. data/lib/mihari/structs/greynoise.rb +4 -3
  65. data/lib/mihari/structs/ipinfo.rb +1 -2
  66. data/lib/mihari/structs/onyphe.rb +6 -5
  67. data/lib/mihari/structs/rule.rb +121 -0
  68. data/lib/mihari/structs/shodan.rb +8 -7
  69. data/lib/mihari/structs/urlscan.rb +50 -0
  70. data/lib/mihari/structs/virustotal_intelligence.rb +4 -3
  71. data/lib/mihari/type_checker.rb +2 -6
  72. data/lib/mihari/types.rb +8 -1
  73. data/lib/mihari/version.rb +1 -1
  74. data/lib/mihari/web/api.rb +6 -0
  75. data/lib/mihari/web/app.rb +5 -7
  76. data/lib/mihari/web/endpoints/alerts.rb +7 -3
  77. data/lib/mihari/web/endpoints/artifacts.rb +6 -3
  78. data/lib/mihari/web/endpoints/command.rb +2 -1
  79. data/lib/mihari/web/endpoints/configs.rb +2 -1
  80. data/lib/mihari/web/endpoints/ip_addresses.rb +2 -1
  81. data/lib/mihari/web/endpoints/rules.rb +140 -0
  82. data/lib/mihari/web/endpoints/sources.rb +2 -1
  83. data/lib/mihari/web/endpoints/tags.rb +4 -2
  84. data/lib/mihari/web/entities/artifact.rb +4 -2
  85. data/lib/mihari/web/entities/rule.rb +35 -0
  86. data/lib/mihari/web/entities/whois.rb +1 -1
  87. data/lib/mihari/web/middleware/connection_adapter.rb +19 -0
  88. data/lib/mihari/web/public/index.html +1 -1
  89. data/lib/mihari/web/public/redoc-static.html +196 -184
  90. data/lib/mihari/web/public/static/js/app.49ab738a.js +21 -0
  91. data/lib/mihari/web/public/static/js/app.49ab738a.js.map +1 -0
  92. data/lib/mihari/web/public/static/js/app.5dc97aae.js +21 -0
  93. data/lib/mihari/web/public/static/js/app.5dc97aae.js.map +1 -0
  94. data/lib/mihari/web/public/static/js/app.f2b8890f.js +21 -0
  95. data/lib/mihari/web/public/static/js/app.f2b8890f.js.map +1 -0
  96. data/lib/mihari/web/public/static/js/app.fbc19869.js +21 -0
  97. data/lib/mihari/web/public/static/js/app.fbc19869.js.map +1 -0
  98. data/lib/mihari.rb +42 -34
  99. data/mihari.gemspec +21 -23
  100. data/sig/lib/mihari/analyzers/binaryedge.rbs +2 -3
  101. data/sig/lib/mihari/analyzers/censys.rbs +2 -3
  102. data/sig/lib/mihari/analyzers/circl.rbs +1 -3
  103. data/sig/lib/mihari/analyzers/crtsh.rbs +1 -3
  104. data/sig/lib/mihari/analyzers/dnpedia.rbs +1 -4
  105. data/sig/lib/mihari/analyzers/dnstwister.rbs +1 -3
  106. data/sig/lib/mihari/analyzers/feed.rbs +20 -0
  107. data/sig/lib/mihari/analyzers/onyphe.rbs +2 -3
  108. data/sig/lib/mihari/analyzers/otx.rbs +1 -3
  109. data/sig/lib/mihari/analyzers/passivetotal.rbs +3 -5
  110. data/sig/lib/mihari/analyzers/pulsedive.rbs +2 -4
  111. data/sig/lib/mihari/analyzers/securitytrails.rbs +3 -5
  112. data/sig/lib/mihari/analyzers/shodan.rbs +2 -3
  113. data/sig/lib/mihari/analyzers/spyse.rbs +4 -6
  114. data/sig/lib/mihari/analyzers/urlscan.rbs +6 -5
  115. data/sig/lib/mihari/analyzers/virustotal.rbs +4 -6
  116. data/sig/lib/mihari/analyzers/virustotal_intelligence.rbs +2 -3
  117. data/sig/lib/mihari/analyzers/zoomeye.rbs +4 -4
  118. data/sig/lib/mihari/commands/init.rbs +0 -2
  119. data/sig/lib/mihari/commands/validator.rbs +0 -2
  120. data/sig/lib/mihari/emitters/slack.rbs +0 -1
  121. data/sig/lib/mihari/feed/parser.rbs +11 -0
  122. data/sig/lib/mihari/feed/reader.rbs +56 -0
  123. data/sig/lib/mihari/mixins/disallowed_data_value.rbs +0 -2
  124. data/sig/lib/mihari/mixins/rule.rbs +5 -12
  125. data/sig/lib/mihari/models/alert.rbs +1 -1
  126. data/sig/lib/mihari/models/artifact.rbs +2 -0
  127. data/sig/lib/mihari/models/rule.rbs +14 -0
  128. data/sig/lib/mihari/structs/alert.rbs +1 -1
  129. data/sig/lib/mihari/structs/greynoise.rbs +3 -3
  130. data/sig/lib/mihari/structs/rule.rbs +56 -0
  131. data/sig/lib/mihari/structs/shodan.rbs +2 -2
  132. data/sig/lib/mihari/structs/urlscan.rbs +28 -0
  133. data/sig/lib/mihari/types.rbs +4 -0
  134. data/sig/lib/mihari.rbs +0 -2
  135. metadata +102 -147
  136. data/lib/mihari/cli/analyzer.rb +0 -52
  137. data/lib/mihari/commands/binaryedge.rb +0 -21
  138. data/lib/mihari/commands/censys.rb +0 -22
  139. data/lib/mihari/commands/circl.rb +0 -21
  140. data/lib/mihari/commands/crtsh.rb +0 -22
  141. data/lib/mihari/commands/dnpedia.rb +0 -21
  142. data/lib/mihari/commands/dnstwister.rb +0 -21
  143. data/lib/mihari/commands/greynoise.rb +0 -21
  144. data/lib/mihari/commands/json.rb +0 -42
  145. data/lib/mihari/commands/onyphe.rb +0 -21
  146. data/lib/mihari/commands/otx.rb +0 -21
  147. data/lib/mihari/commands/passivetotal.rb +0 -22
  148. data/lib/mihari/commands/pulsedive.rb +0 -21
  149. data/lib/mihari/commands/securitytrails.rb +0 -22
  150. data/lib/mihari/commands/shodan.rb +0 -21
  151. data/lib/mihari/commands/spyse.rb +0 -22
  152. data/lib/mihari/commands/urlscan.rb +0 -23
  153. data/lib/mihari/commands/virustotal.rb +0 -22
  154. data/lib/mihari/commands/virustotal_intelligence.rb +0 -22
  155. data/lib/mihari/commands/zoomeye.rb +0 -22
  156. data/lib/mihari/mixins/configuration.rb +0 -100
  157. data/lib/mihari/mixins/hash.rb +0 -20
  158. data/lib/mihari/schemas/configuration.rb +0 -44
  159. data/lib/mihari/web/public/grape.rb +0 -73
  160. data/sig/lib/mihari/cli/analyzer.rbs +0 -39
  161. data/sig/lib/mihari/commands/binaryedge.rbs +0 -7
  162. data/sig/lib/mihari/commands/censys.rbs +0 -7
  163. data/sig/lib/mihari/commands/circl.rbs +0 -7
  164. data/sig/lib/mihari/commands/crtsh.rbs +0 -7
  165. data/sig/lib/mihari/commands/dnpedia.rbs +0 -7
  166. data/sig/lib/mihari/commands/dnstwister.rbs +0 -7
  167. data/sig/lib/mihari/commands/onyphe.rbs +0 -7
  168. data/sig/lib/mihari/commands/otx.rbs +0 -7
  169. data/sig/lib/mihari/commands/passivetotal.rbs +0 -7
  170. data/sig/lib/mihari/commands/pulsedive.rbs +0 -7
  171. data/sig/lib/mihari/commands/securitytrails.rbs +0 -7
  172. data/sig/lib/mihari/commands/shodan.rbs +0 -7
  173. data/sig/lib/mihari/commands/spyse.rbs +0 -7
  174. data/sig/lib/mihari/commands/urlscan.rbs +0 -7
  175. data/sig/lib/mihari/commands/virustotal.rbs +0 -7
  176. data/sig/lib/mihari/commands/zoomeye.rbs +0 -7
@@ -1,52 +0,0 @@
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/greynoise"
10
- require "mihari/commands/onyphe"
11
- require "mihari/commands/otx"
12
- require "mihari/commands/passivetotal"
13
- require "mihari/commands/pulsedive"
14
- require "mihari/commands/securitytrails"
15
- require "mihari/commands/shodan"
16
- require "mihari/commands/spyse"
17
- require "mihari/commands/urlscan"
18
- require "mihari/commands/virustotal_intelligence"
19
- require "mihari/commands/virustotal"
20
- require "mihari/commands/zoomeye"
21
-
22
- require "mihari/commands/json"
23
-
24
- module Mihari
25
- module CLI
26
- class Analyzer < Base
27
- class_option :ignore_old_artifacts, type: :boolean, default: false, desc: "Whether to ignore old artifacts from checking or not."
28
- class_option :ignore_threshold, type: :numeric, default: 0, desc: "Number of days to define whether an artifact is old or not."
29
- class_option :config, type: :string, desc: "Path to the config file"
30
-
31
- include Mihari::Commands::BinaryEdge
32
- include Mihari::Commands::Censys
33
- include Mihari::Commands::CIRCL
34
- include Mihari::Commands::Crtsh
35
- include Mihari::Commands::DNPedia
36
- include Mihari::Commands::DNSTwister
37
- include Mihari::Commands::GreyNoise
38
- include Mihari::Commands::JSON
39
- include Mihari::Commands::Onyphe
40
- include Mihari::Commands::OTX
41
- include Mihari::Commands::PassiveTotal
42
- include Mihari::Commands::Pulsedive
43
- include Mihari::Commands::SecurityTrails
44
- include Mihari::Commands::Shodan
45
- include Mihari::Commands::Spyse
46
- include Mihari::Commands::Urlscan
47
- include Mihari::Commands::VirusTotal
48
- include Mihari::Commands::VirusTotalIntelligence
49
- include Mihari::Commands::ZoomEye
50
- end
51
- end
52
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module BinaryEdge
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "binaryedge [QUERY]", "BinaryEdge host search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def binaryedge(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::BinaryEdge, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Censys
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "censys [QUERY]", "Censys IPv4 search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- method_option :type, type: :string, desc: "type to search (ipv4 / websites / certificates)", default: "ipv4"
13
- def censys(query)
14
- with_error_handling do
15
- run_analyzer Analyzers::Censys, query: query, options: options
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module CIRCL
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "circl [DOMAIN|SHA1]", "CIRCL passive DNS/SSL search by a domain or SHA1 certificate fingerprint"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def circl(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::CIRCL, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Crtsh
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "crtsh [QUERY]", "crt.sh search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- method_option :exclude_expired, type: :boolean, desc: "exclude expired certificates"
13
- def crtsh(query)
14
- with_error_handling do
15
- run_analyzer Analyzers::Crtsh, query: query, options: options
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module DNPedia
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "dnpedia [QUERY]", "DNPedia domain search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def dnpedia(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::DNPedia, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module DNSTwister
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "dnstwister [DOMAIN]", "dnstwister search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def dnstwister(domain)
13
- with_error_handling do
14
- run_analyzer Analyzers::DNSTwister, query: domain, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module GreyNoise
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "greynoise [QUERY]", "GreyNoise search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def greynoise(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::GreyNoise, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module JSON
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "import_from_json", "Give a JSON input via STDIN"
9
- def import_from_json(input = nil)
10
- with_error_handling do
11
- json = input || $stdin.gets.chomp
12
- raise ArgumentError, "Input not found: please give an input in a JSON format" unless json
13
-
14
- json = parse_as_json(json)
15
- raise ArgumentError, "Invalid input format: an input JSON data should have title, description and artifacts key" unless required_alert_keys?(json)
16
-
17
- title = json["title"]
18
- description = json["description"]
19
- artifacts = json["artifacts"]
20
- tags = json["tags"] || []
21
-
22
- basic = Analyzers::Basic.new(title: title, description: description, artifacts: artifacts, source: "json", tags: tags)
23
-
24
- basic.ignore_old_artifacts = options["ignore_old_artifacts"] || false
25
- basic.ignore_threshold = options["ignore_threshold"] || 0
26
-
27
- basic.run
28
- end
29
- end
30
-
31
- no_commands do
32
- def parse_as_json(input)
33
- ::JSON.parse input
34
- rescue ::JSON::ParserError => _e
35
- nil
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Onyphe
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "onyphe [QUERY]", "Onyphe datascan search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def onyphe(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::Onyphe, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module OTX
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "otx [IP|DOMAIN]", "OTX search by an IP or domain"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def otx(domain)
13
- with_error_handling do
14
- run_analyzer Analyzers::OTX, query: domain, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module PassiveTotal
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "passivetotal [IP|DOMAIN|EMAIL|SHA1]", "PassiveTotal search by an ip, domain, email or SHA1 certificate fingerprint"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def passivetotal(indicator)
13
- with_error_handling do
14
- run_analyzer Analyzers::PassiveTotal, query: indicator, options: options
15
- end
16
- end
17
- map "pt" => :passivetotal
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Pulsedive
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "pulsedive [IP|DOMAIN]", "Pulsedive search by an ip or domain"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def pulsedive(indiactor)
13
- with_error_handling do
14
- run_analyzer Analyzers::Pulsedive, query: indiactor, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module SecurityTrails
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "securitytrails [IP|DOMAIN|EMAIL]", "SecurityTrails search by an ip, domain or email"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def securitytrails(indiactor)
13
- with_error_handling do
14
- run_analyzer Analyzers::SecurityTrails, query: indiactor, options: options
15
- end
16
- end
17
- map "st" => :securitytrails
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Shodan
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "shodan [QUERY]", "Shodan host search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def shodan(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::Shodan, query: query, options: options
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Spyse
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "spyse [QUERY]", "Spyse search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- method_option :type, type: :string, desc: "type to search (ip or domain)", default: "doamin"
13
- def spyse(query)
14
- with_error_handling do
15
- run_analyzer Analyzers::Spyse, query: query, options: options
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Urlscan
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "urlscan [QUERY]", "urlscan search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- method_option :target_type, type: :string, default: "url", desc: "target type to fetch from search results (target type should be 'url', 'domain' or 'ip')"
13
- method_option :use_similarity, type: :boolean, default: false, desc: "use similarity API or not"
14
- def urlscan(query)
15
- with_error_handling do
16
- run_analyzer Analyzers::Urlscan, query: query, options: options
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module VirusTotal
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "virustotal [IP|DOMAIN]", "VirusTotal resolutions search by an ip or domain"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def virustotal(indiactor)
13
- with_error_handling do
14
- run_analyzer Analyzers::VirusTotal, query: indiactor, options: options
15
- end
16
- end
17
- map "vt" => :virustotal
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module VirusTotalIntelligence
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "virustotal_intelligence [QUERY]", "VirusTotal Intelligence search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- def virustotal_intelligence(query)
13
- with_error_handling do
14
- run_analyzer Analyzers::VirusTotalIntelligence, query: query, options: options
15
- end
16
- end
17
- map "vt_intel" => :virustotal_intelligence
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module ZoomEye
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "zoomeye [QUERY]", "ZoomEye search"
9
- method_option :title, type: :string, desc: "title"
10
- method_option :description, type: :string, desc: "description"
11
- method_option :tags, type: :array, desc: "tags"
12
- method_option :type, type: :string, desc: "type to search(host / web)", default: "host"
13
- def zoomeye(query)
14
- with_error_handling do
15
- run_analyzer Analyzers::ZoomEye, query: query, options: options
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "colorize"
4
- require "yaml"
5
-
6
- module Mihari
7
- module Mixins
8
- module Configuration
9
- #
10
- # Load config file into hash
11
- #
12
- # @param [String] path Path to YAML file
13
- #
14
- # @return [Hash]
15
- #
16
- def load_config(path)
17
- data = _load_config(path)
18
- data.transform_keys(&:downcase)
19
- end
20
-
21
- #
22
- # Validate config schema
23
- #
24
- # @param [Hash] config
25
- #
26
- def validate_config(config)
27
- error_message = "Failed to parse the input as a config!"
28
-
29
- contract = Schemas::ConfigurationContract.new
30
- result = contract.call(config)
31
- unless result.errors.empty?
32
- puts error_message.colorize(:red)
33
- show_validation_errors result.errors
34
- raise ArgumentError, "Invalid config schema"
35
- end
36
-
37
- # check keys
38
- # TODO: check keys with dry-schema
39
- valid_keys = Mihari.config.values.keys
40
- config.each_key do |key|
41
- unless valid_keys.include?(key)
42
- puts error_message.colorize(:red)
43
- raise ArgumentError, "#{key} is not a valid key."
44
- end
45
- end
46
- end
47
-
48
- #
49
- # Returns a template for config
50
- #
51
- # @return [String] A template for config
52
- #
53
- def config_template
54
- config = Mihari.config.values.keys.map do |key|
55
- [key.to_s, nil]
56
- end.to_h
57
-
58
- YAML.dump(config)
59
- end
60
-
61
- #
62
- # Create (blank) config file
63
- #
64
- # @param [String] filename
65
- # @param [Dry::Files] files
66
- # @param [String] template
67
- #
68
- # @return [nil]
69
- #
70
- def initialize_config_yaml(filename, files = Dry::Files.new, template: config_template)
71
- files.write(filename, template)
72
- end
73
-
74
- private
75
-
76
- def show_validation_errors(errors)
77
- errors.messages.each do |message|
78
- path = message.path.map(&:to_s).join
79
- puts "- #{path} #{message.text}".colorize(:red)
80
- end
81
- end
82
-
83
- #
84
- # Load configuration file
85
- #
86
- # @param [String] path
87
- #
88
- # @return [Hash]
89
- #
90
- def _load_config(path)
91
- unless Pathname(path).exist?
92
- puts "#{path} does not exist".colorize(:red)
93
- raise FileNotFoundError
94
- end
95
-
96
- YAML.safe_load(File.read(path), symbolize_names: true)
97
- end
98
- end
99
- end
100
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "cymbal"
4
-
5
- module Mihari
6
- module Mixins
7
- module Hash
8
- #
9
- # Symbolize hash keys
10
- #
11
- # @param [Hash] hash
12
- #
13
- # @return [Hash]
14
- #
15
- def symbolize_hash(hash)
16
- Cymbal.symbolize hash
17
- end
18
- end
19
- end
20
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dry/schema"
4
- require "dry/validation"
5
-
6
- require "mihari/schemas/macros"
7
-
8
- module Mihari
9
- module Schemas
10
- Configuration = Dry::Schema.Params do
11
- optional(:binaryedge_api_key).value(:string)
12
- optional(:censys_id).value(:string)
13
- optional(:censys_secret).value(:string)
14
- optional(:circl_passive_password).value(:string)
15
- optional(:circl_passive_username).value(:string)
16
- optional(:database).value(:string)
17
- optional(:greynoise_api_key).value(:string)
18
- optional(:ipinfo_api_key).value(:string)
19
- optional(:misp_api_endpoint).value(:string)
20
- optional(:misp_api_key).value(:string)
21
- optional(:onyphe_api_key).value(:string)
22
- optional(:otx_api_key).value(:string)
23
- optional(:passivetotal_api_key).value(:string)
24
- optional(:passivetotal_username).value(:string)
25
- optional(:pulsedive_api_key).value(:string)
26
- optional(:securitytrails_api_key).value(:string)
27
- optional(:shodan_api_key).value(:string)
28
- optional(:slack_channel).value(:string)
29
- optional(:slack_webhook_url).value(:string)
30
- optional(:spyse_api_key).value(:string)
31
- optional(:thehive_api_endpoint).value(:string)
32
- optional(:thehive_api_key).value(:string)
33
- optional(:urlscan_api_key).value(:string)
34
- optional(:virustotal_api_key).value(:string)
35
- optional(:webhook_url).value(:string)
36
- optional(:webhook_use_json_body).value(:bool)
37
- optional(:zoomeye_api_key).value(:string)
38
- end
39
-
40
- class ConfigurationContract < Dry::Validation::Contract
41
- params(Configuration)
42
- end
43
- end
44
- end