mihari 5.4.9 → 5.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/binaryedge.md +2 -2
  3. data/docs/analyzers/censys.md +3 -3
  4. data/docs/analyzers/circl.md +3 -3
  5. data/docs/analyzers/crtsh.md +2 -2
  6. data/docs/analyzers/dnstwister.md +1 -1
  7. data/docs/analyzers/feed.md +7 -7
  8. data/docs/analyzers/greynoise.md +2 -2
  9. data/docs/analyzers/hunterhow.md +4 -4
  10. data/docs/analyzers/index.md +13 -8
  11. data/docs/analyzers/onyphe.md +2 -2
  12. data/docs/analyzers/otx.md +2 -2
  13. data/docs/analyzers/passivetotal.md +7 -3
  14. data/docs/analyzers/pulsedive.md +2 -2
  15. data/docs/analyzers/securitytrails.md +6 -2
  16. data/docs/analyzers/shodan.md +2 -2
  17. data/docs/analyzers/urlscan.md +2 -2
  18. data/docs/analyzers/virustotal.md +6 -2
  19. data/docs/analyzers/virustotal_intelligence.md +6 -2
  20. data/docs/analyzers/zoomeye.md +3 -3
  21. data/docs/emitters/hive.md +4 -4
  22. data/docs/emitters/index.md +29 -0
  23. data/docs/emitters/misp.md +2 -2
  24. data/docs/emitters/slack.md +2 -7
  25. data/docs/emitters/webhook.md +4 -4
  26. data/docs/enrichers/index.md +29 -0
  27. data/docs/enrichers/ipinfo.md +7 -0
  28. data/docs/index.md +0 -2
  29. data/docs/installation.md +1 -1
  30. data/docs/rule.md +12 -15
  31. data/docs/usage.md +5 -2
  32. data/frontend/package-lock.json +294 -2772
  33. data/frontend/package.json +10 -10
  34. data/frontend/src/components/ErrorMessage.vue +0 -1
  35. data/frontend/src/components/alert/Alerts.vue +0 -1
  36. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
  37. data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
  38. data/frontend/src/components/alert/Form.vue +1 -3
  39. data/frontend/src/components/artifact/Artifact.vue +0 -17
  40. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
  41. data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
  42. data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
  43. data/frontend/src/components/rule/EditRule.vue +0 -3
  44. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
  45. data/frontend/src/components/rule/Form.vue +1 -3
  46. data/frontend/src/components/rule/NewRule.vue +0 -3
  47. data/frontend/src/components/rule/Rule.vue +1 -7
  48. data/frontend/src/components/rule/RuleWrapper.vue +0 -2
  49. data/frontend/src/components/rule/RulesWrapper.vue +0 -6
  50. data/frontend/src/swagger.yaml +254 -254
  51. data/lib/mihari/analyzers/base.rb +7 -37
  52. data/lib/mihari/analyzers/binaryedge.rb +5 -1
  53. data/lib/mihari/analyzers/censys.rb +6 -1
  54. data/lib/mihari/analyzers/greynoise.rb +5 -1
  55. data/lib/mihari/analyzers/hunterhow.rb +5 -1
  56. data/lib/mihari/analyzers/onyphe.rb +5 -1
  57. data/lib/mihari/analyzers/passivetotal.rb +9 -0
  58. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  59. data/lib/mihari/analyzers/rule.rb +55 -54
  60. data/lib/mihari/analyzers/securitytrails.rb +9 -0
  61. data/lib/mihari/analyzers/shodan.rb +5 -1
  62. data/lib/mihari/analyzers/urlscan.rb +5 -1
  63. data/lib/mihari/analyzers/virustotal.rb +11 -2
  64. data/lib/mihari/analyzers/virustotal_intelligence.rb +21 -1
  65. data/lib/mihari/analyzers/zoomeye.rb +7 -3
  66. data/lib/mihari/base.rb +69 -0
  67. data/lib/mihari/cli/main.rb +36 -0
  68. data/lib/mihari/clients/base.rb +7 -7
  69. data/lib/mihari/clients/binaryedge.rb +10 -4
  70. data/lib/mihari/clients/censys.rb +11 -4
  71. data/lib/mihari/clients/greynoise.rb +10 -4
  72. data/lib/mihari/clients/hunterhow.rb +10 -4
  73. data/lib/mihari/clients/misp.rb +3 -2
  74. data/lib/mihari/clients/onyphe.rb +10 -4
  75. data/lib/mihari/clients/shodan.rb +10 -4
  76. data/lib/mihari/clients/the_hive.rb +3 -2
  77. data/lib/mihari/clients/urlscan.rb +9 -3
  78. data/lib/mihari/clients/virustotal.rb +10 -4
  79. data/lib/mihari/clients/zoomeye.rb +11 -5
  80. data/lib/mihari/commands/alert.rb +6 -33
  81. data/lib/mihari/commands/rule.rb +7 -12
  82. data/lib/mihari/commands/search.rb +10 -38
  83. data/lib/mihari/config.rb +8 -0
  84. data/lib/mihari/constants.rb +3 -3
  85. data/lib/mihari/emitters/base.rb +22 -15
  86. data/lib/mihari/emitters/database.rb +1 -1
  87. data/lib/mihari/emitters/misp.rb +7 -6
  88. data/lib/mihari/emitters/slack.rb +24 -6
  89. data/lib/mihari/emitters/the_hive.rb +8 -7
  90. data/lib/mihari/emitters/webhook.rb +31 -29
  91. data/lib/mihari/enrichers/base.rb +25 -19
  92. data/lib/mihari/enrichers/google_public_dns.rb +38 -38
  93. data/lib/mihari/enrichers/ipinfo.rb +32 -34
  94. data/lib/mihari/enrichers/shodan.rb +18 -26
  95. data/lib/mihari/enrichers/whois.rb +121 -111
  96. data/lib/mihari/mixins/retriable.rb +4 -2
  97. data/lib/mihari/models/artifact.rb +37 -23
  98. data/lib/mihari/models/autonomous_system.rb +3 -2
  99. data/lib/mihari/models/cpe.rb +3 -2
  100. data/lib/mihari/models/dns.rb +3 -2
  101. data/lib/mihari/models/geolocation.rb +3 -2
  102. data/lib/mihari/models/port.rb +3 -2
  103. data/lib/mihari/models/reverse_dns.rb +3 -2
  104. data/lib/mihari/models/whois.rb +4 -3
  105. data/lib/mihari/schemas/analyzer.rb +24 -23
  106. data/lib/mihari/schemas/emitter.rb +32 -25
  107. data/lib/mihari/schemas/enricher.rb +21 -2
  108. data/lib/mihari/schemas/options.rb +27 -0
  109. data/lib/mihari/schemas/rule.rb +8 -4
  110. data/lib/mihari/services/alert_runner.rb +1 -1
  111. data/lib/mihari/services/rule_runner.rb +1 -11
  112. data/lib/mihari/types.rb +1 -14
  113. data/lib/mihari/version.rb +1 -1
  114. data/lib/mihari/web/endpoints/ip_addresses.rb +1 -1
  115. data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
  116. data/lib/mihari/web/public/assets/index-9cc489e6.js +1749 -0
  117. data/lib/mihari/web/public/index.html +2 -2
  118. data/lib/mihari/web/public/redoc-static.html +400 -400
  119. data/lib/mihari.rb +67 -37
  120. data/mihari.gemspec +3 -2
  121. data/mkdocs.yml +8 -6
  122. data/requirements.txt +1 -1
  123. metadata +24 -8
  124. data/lib/mihari/web/public/assets/index-a92abd57.js +0 -1740
@@ -5,122 +5,132 @@ require "whois-parser"
5
5
  module Mihari
6
6
  module Enrichers
7
7
  class Whois < Base
8
- # @type [Hash]
9
- @memo = {}
8
+ # @return [Hash]
9
+ attr_accessor :memo
10
10
 
11
- # @return [Boolean]
12
- def valid?
13
- true
11
+ #
12
+ # @param [Hash, nil] options
13
+ #
14
+ def initialize(options: nil)
15
+ super(options: options)
16
+
17
+ @memo = {}
18
+ end
19
+
20
+ #
21
+ # Query IAIA Whois API
22
+ #
23
+ # @param [String] name
24
+ #
25
+ # @return [Mihari::WhoisRecord, nil]
26
+ #
27
+ def query(domain)
28
+ domain = PublicSuffix.domain(domain)
29
+
30
+ # check memo
31
+ return memo[domain].dup if memo.key?(domain)
32
+
33
+ record = whois.lookup(domain)
34
+ parser = record.parser
35
+ return nil if parser.available?
36
+
37
+ whois_record = WhoisRecord.new(
38
+ domain: domain,
39
+ created_on: get_created_on(parser),
40
+ updated_on: get_updated_on(parser),
41
+ expires_on: get_expires_on(parser),
42
+ registrar: get_registrar(parser),
43
+ contacts: get_contacts(parser)
44
+ )
45
+
46
+ # set memo
47
+ memo[domain] = whois_record
48
+
49
+ whois_record
14
50
  end
15
51
 
16
- class << self
17
- include Dry::Monads[:result]
18
-
19
- #
20
- # Query IAIA Whois API
21
- #
22
- # @param [String] name
23
- #
24
- # @return [Mihari::WhoisRecord, nil]
25
- #
26
- def query(domain)
27
- domain = PublicSuffix.domain(domain)
28
-
29
- # check memo
30
- if @memo.key?(domain)
31
- whois_record = @memo[domain]
32
- # return clone of the record
33
- return whois_record.dup
52
+ def reset_cache
53
+ @memo = {}
54
+ end
55
+
56
+ private
57
+
58
+ #
59
+ # @return [::Whois::Client]
60
+ #
61
+ def whois
62
+ @whois ||= [].tap do |out|
63
+ out << if timeout.nil?
64
+ ::Whois::Client.new
65
+ else
66
+ ::Whois::Client.new(timeout: timeout)
34
67
  end
68
+ end.last
69
+ end
70
+
71
+ #
72
+ # Get created_on
73
+ #
74
+ # @param [::Whois::Parser:] parser
75
+ #
76
+ # @return [Date, nil]
77
+ #
78
+ def get_created_on(parser)
79
+ parser.created_on
80
+ rescue ::Whois::AttributeNotImplemented
81
+ nil
82
+ end
83
+
84
+ #
85
+ # Get updated_on
86
+ #
87
+ # @param [::Whois::Parser:] parser
88
+ #
89
+ # @return [Date, nil]
90
+ #
91
+ def get_updated_on(parser)
92
+ parser.updated_on
93
+ rescue ::Whois::AttributeNotImplemented
94
+ nil
95
+ end
96
+
97
+ #
98
+ # Get expires_on
99
+ #
100
+ # @param [::Whois::Parser:] parser
101
+ #
102
+ # @return [Date, nil]
103
+ #
104
+ def get_expires_on(parser)
105
+ parser.expires_on
106
+ rescue ::Whois::AttributeNotImplemented
107
+ nil
108
+ end
109
+
110
+ #
111
+ # Get registrar
112
+ #
113
+ # @param [::Whois::Parser:] parser
114
+ #
115
+ # @return [Hash, nil]
116
+ #
117
+ def get_registrar(parser)
118
+ parser.registrar&.to_h
119
+ rescue ::Whois::AttributeNotImplemented
120
+ nil
121
+ end
35
122
 
36
- record = ::Whois.whois(domain)
37
- parser = record.parser
38
-
39
- return nil if parser.available?
40
-
41
- whois_record = WhoisRecord.new(
42
- domain: domain,
43
- created_on: get_created_on(parser),
44
- updated_on: get_updated_on(parser),
45
- expires_on: get_expires_on(parser),
46
- registrar: get_registrar(parser),
47
- contacts: get_contacts(parser)
48
- )
49
- # set memo
50
- @memo[domain] = whois_record
51
- whois_record
52
- end
53
-
54
- def reset_cache
55
- @memo = {}
56
- end
57
-
58
- private
59
-
60
- #
61
- # Get created_on
62
- #
63
- # @param [::Whois::Parser:] parser
64
- #
65
- # @return [Date, nil]
66
- #
67
- def get_created_on(parser)
68
- parser.created_on
69
- rescue ::Whois::AttributeNotImplemented
70
- nil
71
- end
72
-
73
- #
74
- # Get updated_on
75
- #
76
- # @param [::Whois::Parser:] parser
77
- #
78
- # @return [Date, nil]
79
- #
80
- def get_updated_on(parser)
81
- parser.updated_on
82
- rescue ::Whois::AttributeNotImplemented
83
- nil
84
- end
85
-
86
- #
87
- # Get expires_on
88
- #
89
- # @param [::Whois::Parser:] parser
90
- #
91
- # @return [Date, nil]
92
- #
93
- def get_expires_on(parser)
94
- parser.expires_on
95
- rescue ::Whois::AttributeNotImplemented
96
- nil
97
- end
98
-
99
- #
100
- # Get registrar
101
- #
102
- # @param [::Whois::Parser:] parser
103
- #
104
- # @return [Hash, nil]
105
- #
106
- def get_registrar(parser)
107
- parser.registrar&.to_h
108
- rescue ::Whois::AttributeNotImplemented
109
- nil
110
- end
111
-
112
- #
113
- # Get contacts
114
- #
115
- # @param [::Whois::Parser:] parser
116
- #
117
- # @return [Array[Hash], nil]
118
- #
119
- def get_contacts(parser)
120
- parser.contacts.map(&:to_h)
121
- rescue ::Whois::AttributeNotImplemented
122
- nil
123
- end
123
+ #
124
+ # Get contacts
125
+ #
126
+ # @param [::Whois::Parser:] parser
127
+ #
128
+ # @return [Array[Hash], nil]
129
+ #
130
+ def get_contacts(parser)
131
+ parser.contacts.map(&:to_h)
132
+ rescue ::Whois::AttributeNotImplemented
133
+ nil
124
134
  end
125
135
  end
126
136
  end
@@ -19,15 +19,17 @@ module Mihari
19
19
  #
20
20
  # @param [Integer] times
21
21
  # @param [Integer] interval
22
+ # @param [Boolean] exponential_backoff
22
23
  # @param [Array<StandardError>] on
23
24
  #
24
- def retry_on_error(times: 3, interval: 5, on: DEFAULT_ON)
25
+ def retry_on_error(times: 3, interval: 5, exponential_backoff: true, on: DEFAULT_ON)
25
26
  try = 0
26
27
  begin
27
28
  try += 1
28
29
  yield
29
30
  rescue *on => e
30
- sleep interval
31
+ sleep_seconds = exponential_backoff ? interval * (2**(try - 1)) : interval
32
+ sleep sleep_seconds
31
33
  retry if try < times
32
34
  raise e
33
35
  end
@@ -73,64 +73,78 @@ module Mihari
73
73
  #
74
74
  # Enrich(add) whois record
75
75
  #
76
- def enrich_whois
76
+ # @param [Mihari::Enrichers::Whois] enricher
77
+ #
78
+ def enrich_whois(enricher = Enrichers::Whois.new)
77
79
  return unless can_enrich_whois?
78
80
 
79
- self.whois_record = WhoisRecord.build_by_domain(normalize_as_domain(data))
81
+ self.whois_record = WhoisRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
80
82
  end
81
83
 
82
84
  #
83
85
  # Enrich(add) DNS records
84
86
  #
85
- def enrich_dns
87
+ # @param [Mihari::Enrichers::GooglePublicDNS] enricher
88
+ #
89
+ def enrich_dns(enricher = Enrichers::GooglePublicDNS.new)
86
90
  return unless can_enrich_dns?
87
91
 
88
- self.dns_records = DnsRecord.build_by_domain(normalize_as_domain(data))
92
+ self.dns_records = DnsRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
89
93
  end
90
94
 
91
95
  #
92
96
  # Enrich(add) reverse DNS names
93
97
  #
94
- def enrich_reverse_dns
98
+ # @param [Mihari::Enrichers::Shodan] enricher
99
+ #
100
+ def enrich_reverse_dns(enricher = Enrichers::Shodan.new)
95
101
  return unless can_enrich_revese_dns?
96
102
 
97
- self.reverse_dns_names = ReverseDnsName.build_by_ip(data)
103
+ self.reverse_dns_names = ReverseDnsName.build_by_ip(data, enricher: enricher)
98
104
  end
99
105
 
100
106
  #
101
107
  # Enrich(add) geolocation
102
108
  #
103
- def enrich_geolocation
109
+ # @param [Mihari::Enrichers::IPInfo] enricher
110
+ #
111
+ def enrich_geolocation(enricher = Enrichers::IPInfo.new)
104
112
  return unless can_enrich_geolocation?
105
113
 
106
- self.geolocation = Geolocation.build_by_ip(data)
114
+ self.geolocation = Geolocation.build_by_ip(data, enricher: enricher)
107
115
  end
108
116
 
109
117
  #
110
118
  # Enrich AS
111
119
  #
112
- def enrich_autonomous_system
120
+ # @param [Mihari::Enrichers::IPInfo] enricher
121
+ #
122
+ def enrich_autonomous_system(enricher = Enrichers::IPInfo.new)
113
123
  return unless can_enrich_autonomous_system?
114
124
 
115
- self.autonomous_system = AutonomousSystem.build_by_ip(data)
125
+ self.autonomous_system = AutonomousSystem.build_by_ip(data, enricher: enricher)
116
126
  end
117
127
 
118
128
  #
119
129
  # Enrich ports
120
130
  #
121
- def enrich_ports
131
+ # @param [Mihari::Enrichers::Shodan] enricher
132
+ #
133
+ def enrich_ports(enricher = Enrichers::Shodan.new)
122
134
  return unless can_enrich_ports?
123
135
 
124
- self.ports = Port.build_by_ip(data)
136
+ self.ports = Port.build_by_ip(data, enricher: enricher)
125
137
  end
126
138
 
127
139
  #
128
140
  # Enrich CPEs
129
141
  #
130
- def enrich_cpes
142
+ # @param [Mihari::Enrichers::Shodan] enricher
143
+ #
144
+ def enrich_cpes(enricher = Enrichers::Shodan.new)
131
145
  return unless can_enrich_cpes?
132
146
 
133
- self.cpes = CPE.build_by_ip(data)
147
+ self.cpes = CPE.build_by_ip(data, enricher: enricher)
134
148
  end
135
149
 
136
150
  #
@@ -147,32 +161,32 @@ module Mihari
147
161
  end
148
162
 
149
163
  ENRICH_METHODS_BY_ENRICHER = {
150
- whois: [
151
- :enrich_whois
164
+ Enrichers::Whois => %i[
165
+ enrich_whois
152
166
  ],
153
- ipinfo: %i[
167
+ Enrichers::IPInfo => %i[
154
168
  enrich_autonomous_system
155
169
  enrich_geolocation
156
170
  ],
157
- shodan: %i[
171
+ Enrichers::Shodan => %i[
158
172
  enrich_ports
159
173
  enrich_cpes
160
174
  enrich_reverse_dns
161
175
  ],
162
- google_public_dns: [
163
- :enrich_dns
176
+ Enrichers::GooglePublicDNS => %i[
177
+ enrich_dns
164
178
  ]
165
179
  }.freeze
166
180
 
167
181
  #
168
182
  # Enrich by name of enricher
169
183
  #
170
- # @param [String] enricher
184
+ # @param [Mihari::Enrichers::Base] enricher
171
185
  #
172
186
  def enrich_by_enricher(enricher)
173
- methods = ENRICH_METHODS_BY_ENRICHER[enricher.downcase.to_sym] || []
187
+ methods = ENRICH_METHODS_BY_ENRICHER[enricher.class] || []
174
188
  methods.each do |method|
175
- send(method) if respond_to?(method)
189
+ send(method, enricher) if respond_to?(method)
176
190
  end
177
191
  end
178
192
 
@@ -11,11 +11,12 @@ module Mihari
11
11
  # Build AS
12
12
  #
13
13
  # @param [String] ip
14
+ # @param [Mihari::Enrichers::IPInfo] enricher
14
15
  #
15
16
  # @return [Mihari::AutonomousSystem, nil]
16
17
  #
17
- def build_by_ip(ip)
18
- result = Enrichers::IPInfo.query_result(ip).bind do |res|
18
+ def build_by_ip(ip, enricher: Enrichers::IPInfo.new)
19
+ result = enricher.query_result(ip).bind do |res|
19
20
  value = res&.asn
20
21
  if value.nil?
21
22
  Success nil
@@ -11,11 +11,12 @@ module Mihari
11
11
  # Build CPEs
12
12
  #
13
13
  # @param [String] ip
14
+ # @param [Mihari::Enrichers::Shodan] enricher
14
15
  #
15
16
  # @return [Array<Mihari::CPE>]
16
17
  #
17
- def build_by_ip(ip)
18
- result = Enrichers::Shodan.query_result(ip).bind do |res|
18
+ def build_by_ip(ip, enricher: Enrichers::Shodan.new)
19
+ result = enricher.query_result(ip).bind do |res|
19
20
  if res.nil?
20
21
  Success []
21
22
  else
@@ -11,11 +11,12 @@ module Mihari
11
11
  # Build DNS records
12
12
  #
13
13
  # @param [String] domain
14
+ # @param [Mihari::Enrichers::Shodan] enricher
14
15
  #
15
16
  # @return [Array<Mihari::DnsRecord>]
16
17
  #
17
- def build_by_domain(domain)
18
- result = Enrichers::GooglePublicDNS.query_result(domain).bind do |responses|
18
+ def build_by_domain(domain, enricher: Enrichers::GooglePublicDNS.new)
19
+ result = enricher.query_result(domain).bind do |responses|
19
20
  Success(
20
21
  responses.map do |res|
21
22
  res.answers.map do |answer|
@@ -13,11 +13,12 @@ module Mihari
13
13
  # Build Geolocation
14
14
  #
15
15
  # @param [String] ip
16
+ # @param [Mihari::Enrichers::IPinfo] enricher
16
17
  #
17
18
  # @return [Mihari::Geolocation, nil]
18
19
  #
19
- def build_by_ip(ip)
20
- result = Enrichers::IPInfo.query_result(ip).bind do |res|
20
+ def build_by_ip(ip, enricher: Enrichers::IPInfo.new)
21
+ result = enricher.query_result(ip).bind do |res|
21
22
  value = res&.country_code
22
23
  if value.nil?
23
24
  Success nil
@@ -11,11 +11,12 @@ module Mihari
11
11
  # Build ports
12
12
  #
13
13
  # @param [String] ip
14
+ # @param [Mihari::Enrichers::Shodan] enricher
14
15
  #
15
16
  # @return [Array<Mihari::Port>]
16
17
  #
17
- def build_by_ip(ip)
18
- result = Enrichers::Shodan.query_result(ip).bind do |res|
18
+ def build_by_ip(ip, enricher: Enrichers::Shodan.new)
19
+ result = enricher.query_result(ip).bind do |res|
19
20
  if res.nil?
20
21
  Success []
21
22
  else
@@ -11,11 +11,12 @@ module Mihari
11
11
  # Build reverse DNS names
12
12
  #
13
13
  # @param [String] ip
14
+ # @param [Mihari::Enrichers::Shodan] enricher
14
15
  #
15
16
  # @return [Array<Mihari::ReverseDnsName>]
16
17
  #
17
- def build_by_ip(ip)
18
- result = Enrichers::Shodan.query_result(ip).bind do |res|
18
+ def build_by_ip(ip, enricher: Enrichers::Shodan.new)
19
+ result = enricher.query_result(ip).bind do |res|
19
20
  if res.nil?
20
21
  Success []
21
22
  else
@@ -12,12 +12,13 @@ module Mihari
12
12
  #
13
13
  # Build whois record
14
14
  #
15
- # @param [Stinrg] domain
15
+ # @param [String] domain
16
+ # @param [Mihari::Enrichers::Whois] enricher
16
17
  #
17
18
  # @return [WhoisRecord, nil]
18
19
  #
19
- def build_by_domain(domain)
20
- result = Enrichers::Whois.query_result(domain)
20
+ def build_by_domain(domain, enricher: Enrichers::Whois.new)
21
+ result = enricher.query_result(domain)
21
22
  result.value_or nil
22
23
  end
23
24
  end
@@ -2,36 +2,31 @@
2
2
 
3
3
  module Mihari
4
4
  module Schemas
5
- AnalyzerOptions = Dry::Schema.Params do
6
- optional(:interval).value(:integer)
7
- optional(:pagination_limit).value(:integer).default(Mihari.config.pagination_limit)
8
- optional(:retry_times).value(:integer).default(Mihari.config.retry_times)
9
- optional(:retry_interval).value(:integer).default(Mihari.config.retry_interval)
10
- optional(:ignore_error).value(:bool).default(Mihari.config.ignore_error)
11
- optional(:timeout).value(:integer)
12
- end
13
-
14
- AnalyzerWithoutAPIKey = Dry::Schema.Params do
15
- required(:analyzer).value(Types::String.enum("dnstwister"))
16
- required(:query).value(:string)
17
- optional(:options).hash(AnalyzerOptions)
18
- end
19
-
20
- AnalyzerWithAPIKey = Dry::Schema.Params do
5
+ AnalyzerAPIKeyPagination = Dry::Schema.Params do
21
6
  required(:analyzer).value(
22
7
  Types::String.enum(
23
8
  "binaryedge",
24
9
  "greynoise",
25
10
  "onyphe",
11
+ "shodan",
12
+ "urlscan",
13
+ "virustotal_intelligence",
14
+ "vt_intel"
15
+ )
16
+ )
17
+ required(:query).value(:string)
18
+ optional(:api_key).value(:string)
19
+ optional(:options).hash(AnalyzerPaginationOptions)
20
+ end
21
+
22
+ AnalyzerAPIKey = Dry::Schema.Params do
23
+ required(:analyzer).value(
24
+ Types::String.enum(
26
25
  "otx",
27
26
  "pulsedive",
28
27
  "securitytrails",
29
- "shodan",
30
28
  "st",
31
- "urlscan",
32
- "virustotal_intelligence",
33
29
  "virustotal",
34
- "vt_intel",
35
30
  "vt"
36
31
  )
37
32
  )
@@ -40,12 +35,18 @@ module Mihari
40
35
  optional(:options).hash(AnalyzerOptions)
41
36
  end
42
37
 
38
+ DNSTwister = Dry::Schema.Params do
39
+ required(:analyzer).value(Types::String.enum("dnstwister"))
40
+ required(:query).value(:string)
41
+ optional(:options).hash(AnalyzerOptions)
42
+ end
43
+
43
44
  Censys = Dry::Schema.Params do
44
45
  required(:analyzer).value(Types::String.enum("censys"))
45
46
  required(:query).value(:string)
46
47
  optional(:id).value(:string)
47
48
  optional(:secret).value(:string)
48
- optional(:options).hash(AnalyzerOptions)
49
+ optional(:options).hash(AnalyzerPaginationOptions)
49
50
  end
50
51
 
51
52
  CIRCL = Dry::Schema.Params do
@@ -68,7 +69,7 @@ module Mihari
68
69
  required(:analyzer).value(Types::String.enum("zoomeye"))
69
70
  required(:query).value(:string)
70
71
  required(:type).value(Types::String.enum("host", "web"))
71
- optional(:options).hash(AnalyzerOptions)
72
+ optional(:options).hash(AnalyzerPaginationOptions)
72
73
  end
73
74
 
74
75
  Crtsh = Dry::Schema.Params do
@@ -84,7 +85,7 @@ module Mihari
84
85
  required(:start_time).value(:date)
85
86
  required(:end_time).value(:date)
86
87
  optional(:api_key).value(:string)
87
- optional(:options).hash(AnalyzerOptions)
88
+ optional(:options).hash(AnalyzerPaginationOptions)
88
89
  end
89
90
 
90
91
  Feed = Dry::Schema.Params do
@@ -2,35 +2,42 @@
2
2
 
3
3
  module Mihari
4
4
  module Schemas
5
- Database = Dry::Schema.Params do
6
- required(:emitter).value(Types::String.enum("database"))
7
- end
5
+ module Emitters
6
+ Database = Dry::Schema.Params do
7
+ required(:emitter).value(Types::String.enum("database"))
8
+ optional(:options).hash(Options)
9
+ end
8
10
 
9
- MISP = Dry::Schema.Params do
10
- required(:emitter).value(Types::String.enum("misp"))
11
- optional(:url).value(:string)
12
- optional(:api_key).value(:string)
13
- end
11
+ MISP = Dry::Schema.Params do
12
+ required(:emitter).value(Types::String.enum("misp"))
13
+ optional(:url).value(:string)
14
+ optional(:api_key).value(:string)
15
+ optional(:options).hash(Options)
16
+ end
14
17
 
15
- TheHive = Dry::Schema.Params do
16
- required(:emitter).value(Types::String.enum("the_hive"))
17
- optional(:url).value(:string)
18
- optional(:api_key).value(:string)
19
- optional(:api_version).value(Types::String.enum("v4", "v5")).default("v4")
20
- end
18
+ TheHive = Dry::Schema.Params do
19
+ required(:emitter).value(Types::String.enum("thehive"))
20
+ optional(:url).value(:string)
21
+ optional(:api_key).value(:string)
22
+ optional(:api_version).value(Types::String.enum("v4", "v5")).default("v4")
23
+ optional(:options).hash(Options)
24
+ end
21
25
 
22
- Slack = Dry::Schema.Params do
23
- required(:emitter).value(Types::String.enum("slack"))
24
- optional(:webhook_url).value(:string)
25
- optional(:channel).value(:string)
26
- end
26
+ Slack = Dry::Schema.Params do
27
+ required(:emitter).value(Types::String.enum("slack"))
28
+ optional(:webhook_url).value(:string)
29
+ optional(:channel).value(:string)
30
+ optional(:options).hash(Options)
31
+ end
27
32
 
28
- Webhook = Dry::Schema.Params do
29
- required(:emitter).value(Types::String.enum("webhook"))
30
- required(:url).value(:string)
31
- optional(:method).value(Types::HTTPRequestMethods).default("POST")
32
- optional(:headers).value(:hash).default({})
33
- optional(:template).value(:string)
33
+ Webhook = Dry::Schema.Params do
34
+ required(:emitter).value(Types::String.enum("webhook"))
35
+ required(:url).value(:string)
36
+ optional(:method).value(Types::HTTPRequestMethods).default("POST")
37
+ optional(:headers).value(:hash).default({})
38
+ optional(:template).value(:string)
39
+ optional(:options).hash(Options)
40
+ end
34
41
  end
35
42
  end
36
43
  end