mihari 4.9.0 → 4.11.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mihari/analyzers/base.rb +14 -2
  3. data/lib/mihari/analyzers/circl.rb +1 -1
  4. data/lib/mihari/commands/search.rb +1 -1
  5. data/lib/mihari/emitters/misp.rb +23 -12
  6. data/lib/mihari/emitters/slack.rb +2 -2
  7. data/lib/mihari/emitters/the_hive.rb +35 -17
  8. data/lib/mihari/schemas/emitter.rb +2 -0
  9. data/lib/mihari/version.rb +1 -1
  10. data/lib/mihari/web/public/assets/fa-brands-400.3fe890d0.woff2 +0 -0
  11. data/lib/mihari/web/public/{static/fonts/fa-brands-400.f5defc2e.ttf → assets/fa-brands-400.c7ae37d3.ttf} +0 -0
  12. data/lib/mihari/web/public/{static/fonts/fa-regular-400.3edb9004.ttf → assets/fa-regular-400.fdc1f753.ttf} +0 -0
  13. data/lib/mihari/web/public/assets/fa-regular-400.fe69d948.woff2 +0 -0
  14. data/lib/mihari/web/public/assets/fa-solid-900.6d53c706.ttf +0 -0
  15. data/lib/mihari/web/public/assets/fa-solid-900.d27bc752.woff2 +0 -0
  16. data/lib/mihari/web/public/assets/fa-v4compatibility.4d73f280.ttf +0 -0
  17. data/lib/mihari/web/public/assets/fa-v4compatibility.7d1c2ce5.woff2 +0 -0
  18. data/lib/mihari/web/public/assets/index.d3a61a69.js +68 -0
  19. data/lib/mihari/web/public/assets/index.e1e67d84.css +5 -0
  20. data/lib/mihari/web/public/{static/favicon.ico → favicon.ico} +0 -0
  21. data/lib/mihari/web/public/index.html +23 -1
  22. data/lib/mihari/web/public/redoc-static.html +8 -8
  23. data/lib/mihari.rb +4 -4
  24. data/mihari.gemspec +13 -14
  25. data/sig/lib/mihari/emitters/misp.rbs +3 -3
  26. data/sig/lib/mihari/emitters/the_hive.rbs +3 -3
  27. data/sig/lib/mihari.rbs +2 -2
  28. metadata +39 -57
  29. data/lib/mihari/web/public/static/css/app.2a5d3d21.css +0 -1
  30. data/lib/mihari/web/public/static/css/chunk-vendors.380724be.css +0 -7
  31. data/lib/mihari/web/public/static/fonts/fa-brands-400.86c7e1fa.woff2 +0 -0
  32. data/lib/mihari/web/public/static/fonts/fa-regular-400.e0550912.woff2 +0 -0
  33. data/lib/mihari/web/public/static/fonts/fa-solid-900.64d5644d.woff2 +0 -0
  34. data/lib/mihari/web/public/static/fonts/fa-solid-900.f418d876.ttf +0 -0
  35. data/lib/mihari/web/public/static/fonts/fa-v4compatibility.7e7e1dad.ttf +0 -0
  36. data/lib/mihari/web/public/static/js/app.6413bf4f.js +0 -2
  37. data/lib/mihari/web/public/static/js/app.6413bf4f.js.map +0 -1
  38. data/lib/mihari/web/public/static/js/chunk-vendors.723e02cf.js +0 -31
  39. data/lib/mihari/web/public/static/js/chunk-vendors.723e02cf.js.map +0 -1
  40. data/sig/lib/mihari/analyzers/spyse.rbs +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85756e55047ef3bde95c50c1ac3c474adbd29828bf1f95618f3aac85638a1752
4
- data.tar.gz: babe64cf74a96f659057b06ac3b5864b6faa2c3ec9b7e3f0f9b57bce7dd635a8
3
+ metadata.gz: eda042a7f3e0c70bb86a1008d24556b2daf4264142e01936e4bdab3da275ff39
4
+ data.tar.gz: a5e3711ecb0fb982ce6280fbed12261d753e2224966e3961ac2cfe2b83e0e15d
5
5
  SHA512:
6
- metadata.gz: 5c15c65a8952c1fbcf695feba8add8a7fc962eaac9ca426a18dd510663573dc9fe6b27472ca0edcd1ff9fb86b68a49ce8c459e3a7d90eabe9dbbe1e4506181d8
7
- data.tar.gz: aceb04f0f6e78af7f0df2293d78a4d4d20bcf1827e70d45e3f425e38b128c5f9194dbdac608b29b44852af77b626ccbdd03583e7170d5330a2b584c7cbdca55b
6
+ metadata.gz: f33e198db0d4964eb15372b30ef6733aaf3efe51b31640e62e33da2412089e30f618ea9509cc86d57a6e38ae65eac1dd5c7f3fab9c2dc1d5793d005bdcb95862
7
+ data.tar.gz: d7824b329d6117c2539e62044374b989538e4d22fd7641eb63b11db3b766ef52943f3559cb6a43be440b60f55609a763e316661e69196d6749486c8027cad5b2
@@ -72,10 +72,22 @@ module Mihari
72
72
  #
73
73
  # @param [Mihari::Emitters::Base] emitter
74
74
  #
75
- # @return [nil]
75
+ # @return [Mihari::Alert, nil]
76
76
  #
77
77
  def run_emitter(emitter)
78
- emitter.run(title: title, description: description, artifacts: enriched_artifacts, source: source, tags: tags)
78
+ return if enriched_artifacts.empty?
79
+
80
+ alert_or_something = emitter.run(
81
+ title: title,
82
+ description: description,
83
+ artifacts: enriched_artifacts,
84
+ source: source,
85
+ tags: tags
86
+ )
87
+
88
+ Mihari.logger.info "Emission by #{emitter.class} is succedded"
89
+
90
+ alert_or_something
79
91
  rescue StandardError => e
80
92
  Mihari.logger.info "Emission by #{emitter.class} is failed: #{e}"
81
93
  end
@@ -71,7 +71,7 @@ module Mihari
71
71
  results = api.dns.query(@query)
72
72
  results.filter_map do |result|
73
73
  type = result["rrtype"]
74
- type == "A" ? result["rdata"] : nil
74
+ (type == "A") ? result["rdata"] : nil
75
75
  end.uniq
76
76
  end
77
77
 
@@ -44,7 +44,7 @@ module Mihari
44
44
  data = Mihari::Entities::Alert.represent(alert)
45
45
  puts JSON.pretty_generate(data.as_json)
46
46
  else
47
- Mihari.logger.info "There is no new artifact"
47
+ Mihari.logger.info "No new alert created in the database"
48
48
  end
49
49
 
50
50
  # record a rule
@@ -6,7 +6,7 @@ module Mihari
6
6
  module Emitters
7
7
  class MISP < Base
8
8
  # @return [String, nil]
9
- attr_reader :api_endpoint
9
+ attr_reader :url
10
10
 
11
11
  # @return [String, nil]
12
12
  attr_reader :api_key
@@ -14,18 +14,29 @@ module Mihari
14
14
  def initialize(*args, **kwargs)
15
15
  super(*args, **kwargs)
16
16
 
17
- @api_endpoint = kwargs[:api_endpoint] || Mihari.config.misp_api_endpoint
17
+ @url = kwargs[:url] || kwargs[:api_endpoint] || Mihari.config.misp_url
18
18
  @api_key = kwargs[:api_key] || Mihari.config.misp_api_key
19
19
 
20
20
  ::MISP.configure do |config|
21
- config.api_endpoint = api_endpoint
21
+ config.api_endpoint = url
22
22
  config.api_key = api_key
23
23
  end
24
24
  end
25
25
 
26
26
  # @return [Boolean]
27
27
  def valid?
28
- api_endpoint? && api_key? && ping?
28
+ unless url? && api_key?
29
+ Mihari.logger.info("MISP URL is not set") unless url?
30
+ Mihari.logger.info("MISP API key is not set") unless api_key?
31
+ return false
32
+ end
33
+
34
+ unless ping?
35
+ Mihari.logger.info("MISP URL (#{url}) is not reachable")
36
+ return false
37
+ end
38
+
39
+ true
29
40
  end
30
41
 
31
42
  def emit(title:, artifacts:, tags: [], **_options)
@@ -47,7 +58,7 @@ module Mihari
47
58
  private
48
59
 
49
60
  def configuration_keys
50
- %w[misp_api_endpoint misp_api_key]
61
+ %w[misp_url misp_api_key]
51
62
  end
52
63
 
53
64
  #
@@ -103,12 +114,12 @@ module Mihari
103
114
  end
104
115
 
105
116
  #
106
- # Check whether an API endpoint is set or not
117
+ # Check whether a URL is set or not
107
118
  #
108
119
  # @return [Boolean]
109
120
  #
110
- def api_endpoint?
111
- !api_endpoint.nil? && !api_endpoint.empty?
121
+ def url?
122
+ !url.nil? && !url.empty?
112
123
  end
113
124
 
114
125
  #
@@ -121,15 +132,15 @@ module Mihari
121
132
  end
122
133
 
123
134
  #
124
- # Check whether an API endpoint is reachable or not
135
+ # Check whether a URL is reachable or not
125
136
  #
126
137
  # @return [Boolean]
127
138
  #
128
139
  def ping?
129
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
130
- url = "#{base_url}/users/login"
140
+ base_url = url.end_with?("/") ? url[0..-2] : url
141
+ login_url = "#{base_url}/users/login"
131
142
 
132
- http = Net::Ping::HTTP.new(url)
143
+ http = Net::Ping::HTTP.new(login_url)
133
144
  http.ping?
134
145
  end
135
146
  end
@@ -87,13 +87,13 @@ module Mihari
87
87
 
88
88
  # @return [String, nil]
89
89
  def _censys_link
90
- data_type == "ip" ? "https://search.censys.io/hosts/#{data}" : nil
90
+ (data_type == "ip") ? "https://search.censys.io/hosts/#{data}" : nil
91
91
  end
92
92
  memoize :_censys_link
93
93
 
94
94
  # @return [String, nil]
95
95
  def _shodan_link
96
- data_type == "ip" ? "https://www.shodan.io/host/#{data}" : nil
96
+ (data_type == "ip") ? "https://www.shodan.io/host/#{data}" : nil
97
97
  end
98
98
  memoize :_shodan_link
99
99
 
@@ -6,7 +6,7 @@ module Mihari
6
6
  module Emitters
7
7
  class TheHive < Base
8
8
  # @return [String, nil]
9
- attr_reader :api_endpoint
9
+ attr_reader :url
10
10
 
11
11
  # @return [String, nil]
12
12
  attr_reader :api_key
@@ -17,14 +17,25 @@ module Mihari
17
17
  def initialize(*args, **kwargs)
18
18
  super(*args, **kwargs)
19
19
 
20
- @api_endpoint = kwargs[:api_endpoint] || Mihari.config.thehive_api_endpoint
20
+ @url = kwargs[:url] || kwargs[:api_endpoint] || Mihari.config.thehive_url
21
21
  @api_key = kwargs[:api_key] || Mihari.config.thehive_api_key
22
22
  @api_version = kwargs[:api_version] || Mihari.config.thehive_api_version
23
23
  end
24
24
 
25
25
  # @return [Boolean]
26
26
  def valid?
27
- api_endpont? && api_key? && ping?
27
+ unless url? && api_key?
28
+ Mihari.logger.info("TheHive URL is not set") unless url?
29
+ Mihari.logger.info("TheHive API key is not set") unless api_key?
30
+ return false
31
+ end
32
+
33
+ unless ping?
34
+ Mihari.logger.info("TheHive URL (#{url}) is not reachable")
35
+ return false
36
+ end
37
+
38
+ true
28
39
  end
29
40
 
30
41
  def emit(title:, description:, artifacts:, tags: [], **_options)
@@ -57,20 +68,20 @@ module Mihari
57
68
  private
58
69
 
59
70
  def configuration_keys
60
- %w[thehive_api_endpoint thehive_api_key]
71
+ %w[thehive_url thehive_api_key]
61
72
  end
62
73
 
63
74
  def api
64
- @api ||= Hachi::API.new(api_endpoint: api_endpoint, api_key: api_key, api_version: normalized_api_version)
75
+ @api ||= Hachi::API.new(api_endpoint: url, api_key: api_key, api_version: normalized_api_version)
65
76
  end
66
77
 
67
78
  #
68
- # Check whether an API endpoint is set or not
79
+ # Check whether a URL is set or not
69
80
  #
70
81
  # @return [Boolean]
71
82
  #
72
- def api_endpont?
73
- !api_endpoint.nil?
83
+ def url?
84
+ !url.nil?
74
85
  end
75
86
 
76
87
  #
@@ -83,7 +94,10 @@ module Mihari
83
94
  end
84
95
 
85
96
  def payload(title:, description:, artifacts:, tags: [])
86
- return v4_payload(title: title, description: description, artifacts: artifacts, tags: tags) if normalized_api_version.nil?
97
+ if normalized_api_version.nil?
98
+ return v4_payload(title: title, description: description, artifacts: artifacts,
99
+ tags: tags)
100
+ end
87
101
 
88
102
  v5_payload(title: title, description: description, artifacts: artifacts, tags: tags)
89
103
  end
@@ -92,7 +106,9 @@ module Mihari
92
106
  {
93
107
  title: title,
94
108
  description: description,
95
- artifacts: artifacts.map { |artifact| { data: artifact.data, data_type: artifact.data_type, message: description } },
109
+ artifacts: artifacts.map do |artifact|
110
+ { data: artifact.data, data_type: artifact.data_type, message: description }
111
+ end,
96
112
  tags: tags,
97
113
  type: "external",
98
114
  source: "mihari"
@@ -103,7 +119,9 @@ module Mihari
103
119
  {
104
120
  title: title,
105
121
  description: description,
106
- observables: artifacts.map { |artifact| { data: artifact.data, data_type: artifact.data_type, message: description } },
122
+ observables: artifacts.map do |artifact|
123
+ { data: artifact.data, data_type: artifact.data_type, message: description }
124
+ end,
107
125
  tags: tags,
108
126
  type: "external",
109
127
  source: "mihari",
@@ -112,23 +130,23 @@ module Mihari
112
130
  end
113
131
 
114
132
  #
115
- # Check whether an API endpoint is reachable or not
133
+ # Check whether a URL is reachable or not
116
134
  #
117
135
  # @return [Boolean]
118
136
  #
119
137
  def ping?
120
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
138
+ base_url = url.end_with?("/") ? url[0..-2] : url
121
139
 
122
140
  if normalized_api_version.nil?
123
141
  # for v4
124
- base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
125
- url = "#{base_url}/index.html"
142
+ base_url = url.end_with?("/") ? url[0..-2] : url
143
+ public_url = "#{base_url}/index.html"
126
144
  else
127
145
  # for v5
128
- url = "#{base_url}/api/v1/status/public"
146
+ public_url = "#{base_url}/api/v1/status/public"
129
147
  end
130
148
 
131
- http = Net::Ping::HTTP.new(url)
149
+ http = Net::Ping::HTTP.new(public_url)
132
150
 
133
151
  # use GET for v5
134
152
  http.get_request = true if normalized_api_version
@@ -9,12 +9,14 @@ module Mihari
9
9
  MISP = Dry::Schema.Params do
10
10
  required(:emitter).value(Types::String.enum("misp"))
11
11
  optional(:api_endpoint).value(:string)
12
+ optional(:url).value(:string)
12
13
  optional(:api_key).value(:string)
13
14
  end
14
15
 
15
16
  TheHive = Dry::Schema.Params do
16
17
  required(:emitter).value(Types::String.enum("the_hive"))
17
18
  optional(:api_endpoint).value(:string)
19
+ optional(:url).value(:string)
18
20
  optional(:api_key).value(:string)
19
21
  optional(:api_version).value(Types::String.enum("v4", "v5")).default("v4")
20
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "4.9.0"
4
+ VERSION = "4.11.0"
5
5
  end