mihari 1.3.2 → 2.0.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/.github/workflows/test.yml +68 -0
- data/README.md +20 -270
- data/Rakefile +1 -0
- data/build_frontend.sh +14 -0
- data/docker/Dockerfile +3 -2
- data/{screenshots → images}/alert.png +0 -0
- data/{screenshots → images}/eyecatch.png +0 -0
- data/images/logo.png +0 -0
- data/{screenshots → images}/misp.png +0 -0
- data/{screenshots → images}/slack.png +0 -0
- data/images/web_alerts.png +0 -0
- data/images/web_config.png +0 -0
- data/lib/mihari.rb +2 -2
- data/lib/mihari/analyzers/base.rb +1 -1
- data/lib/mihari/analyzers/basic.rb +3 -4
- data/lib/mihari/analyzers/binaryedge.rb +4 -7
- data/lib/mihari/analyzers/censys.rb +3 -7
- data/lib/mihari/analyzers/circl.rb +3 -5
- data/lib/mihari/analyzers/crtsh.rb +2 -6
- data/lib/mihari/analyzers/dnpedia.rb +3 -6
- data/lib/mihari/analyzers/dnstwister.rb +4 -9
- data/lib/mihari/analyzers/free_text.rb +2 -6
- data/lib/mihari/analyzers/http_hash.rb +3 -11
- data/lib/mihari/analyzers/onyphe.rb +3 -6
- data/lib/mihari/analyzers/otx.rb +4 -9
- data/lib/mihari/analyzers/passive_dns.rb +4 -9
- data/lib/mihari/analyzers/passive_ssl.rb +4 -9
- data/lib/mihari/analyzers/passivetotal.rb +9 -14
- data/lib/mihari/analyzers/pulsedive.rb +7 -12
- data/lib/mihari/analyzers/reverse_whois.rb +4 -9
- data/lib/mihari/analyzers/securitytrails.rb +12 -17
- data/lib/mihari/analyzers/securitytrails_domain_feed.rb +3 -7
- data/lib/mihari/analyzers/shodan.rb +9 -8
- data/lib/mihari/analyzers/spyse.rb +6 -11
- data/lib/mihari/analyzers/ssh_fingerprint.rb +2 -6
- data/lib/mihari/analyzers/urlscan.rb +21 -9
- data/lib/mihari/analyzers/virustotal.rb +6 -11
- data/lib/mihari/analyzers/zoomeye.rb +7 -11
- data/lib/mihari/cli.rb +20 -28
- data/lib/mihari/config.rb +1 -25
- data/lib/mihari/configurable.rb +4 -5
- data/lib/mihari/database.rb +7 -1
- data/lib/mihari/emitters/misp.rb +4 -2
- data/lib/mihari/emitters/slack.rb +18 -7
- data/lib/mihari/emitters/the_hive.rb +2 -2
- data/lib/mihari/errors.rb +2 -0
- data/lib/mihari/models/alert.rb +51 -0
- data/lib/mihari/models/artifact.rb +1 -1
- data/lib/mihari/notifiers/exception_notifier.rb +5 -5
- data/lib/mihari/serializers/alert.rb +1 -1
- data/lib/mihari/serializers/artifact.rb +1 -1
- data/lib/mihari/serializers/tag.rb +1 -1
- data/lib/mihari/status.rb +10 -10
- data/lib/mihari/type_checker.rb +4 -4
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +126 -0
- data/lib/mihari/web/public/index.html +21 -0
- data/lib/mihari/web/public/static/favicon.ico +0 -0
- data/lib/mihari/web/public/static/fonts/fa-brands-400.099a9556.woff +0 -0
- data/lib/mihari/web/public/static/fonts/fa-brands-400.30cc681d.eot +0 -0
- data/lib/mihari/web/public/static/fonts/fa-brands-400.3b89dd10.ttf +0 -0
- data/lib/mihari/web/public/static/fonts/fa-brands-400.f7307680.woff2 +0 -0
- data/lib/mihari/web/public/static/fonts/fa-regular-400.1f77739c.ttf +0 -0
- data/lib/mihari/web/public/static/fonts/fa-regular-400.7124eb50.woff +0 -0
- data/lib/mihari/web/public/static/fonts/fa-regular-400.7630483d.eot +0 -0
- data/lib/mihari/web/public/static/fonts/fa-regular-400.f0f82301.woff2 +0 -0
- data/lib/mihari/web/public/static/fonts/fa-solid-900.1042e8ca.eot +0 -0
- data/lib/mihari/web/public/static/fonts/fa-solid-900.605ed792.ttf +0 -0
- data/lib/mihari/web/public/static/fonts/fa-solid-900.9fe5a17c.woff +0 -0
- data/lib/mihari/web/public/static/fonts/fa-solid-900.e8a427e1.woff2 +0 -0
- data/lib/mihari/web/public/static/img/fa-brands-400.ba7ed552.svg +3717 -0
- data/lib/mihari/web/public/static/img/fa-regular-400.0bb42845.svg +801 -0
- data/lib/mihari/web/public/static/img/fa-solid-900.376c1f97.svg +5034 -0
- data/lib/mihari/web/public/static/js/app.58b32d15.js +12 -0
- data/lib/mihari/web/public/static/js/app.58b32d15.js.map +1 -0
- data/mihari.gemspec +30 -25
- metadata +163 -56
- data/.travis.yml +0 -13
- data/lib/mihari/alert_viewer.rb +0 -23
data/lib/mihari/cli.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "thor"
|
4
3
|
require "json"
|
4
|
+
require "rack/builder"
|
5
|
+
require "rack/handler/webrick"
|
6
|
+
require "thor"
|
5
7
|
|
6
8
|
module Mihari
|
7
9
|
class CLI < Thor
|
@@ -46,7 +48,10 @@ module Mihari
|
|
46
48
|
method_option :title, type: :string, desc: "title"
|
47
49
|
method_option :description, type: :string, desc: "description"
|
48
50
|
method_option :tags, type: :array, desc: "tags"
|
51
|
+
method_option :filter, type: :string, desc: "filter for urlscan pro search"
|
49
52
|
method_option :target_type, type: :string, default: "url", desc: "target type to fetch from lookup results (target type should be 'url', 'domain' or 'ip')"
|
53
|
+
method_option :use_pro, type: :boolean, default: false, desc: "use pro search API or not"
|
54
|
+
method_option :use_similarity, type: :boolean, default: false, desc: "use similarity API or not"
|
50
55
|
def urlscan(query)
|
51
56
|
with_error_handling do
|
52
57
|
run_analyzer Analyzers::Urlscan, query: query, options: options
|
@@ -256,44 +261,31 @@ module Mihari
|
|
256
261
|
desc "import_from_json", "Give a JSON input via STDIN"
|
257
262
|
def import_from_json(input = nil)
|
258
263
|
with_error_handling do
|
259
|
-
json = input ||
|
264
|
+
json = input || $stdin.gets.chomp
|
260
265
|
raise ArgumentError, "Input not found: please give an input in a JSON format" unless json
|
261
266
|
|
262
267
|
json = parse_as_json(json)
|
263
268
|
raise ArgumentError, "Invalid input format: an input JSON data should have title, description and artifacts key" unless valid_json?(json)
|
264
269
|
|
265
|
-
title = json
|
266
|
-
description = json
|
267
|
-
artifacts = json
|
268
|
-
tags = json
|
270
|
+
title = json["title"]
|
271
|
+
description = json["description"]
|
272
|
+
artifacts = json["artifacts"]
|
273
|
+
tags = json["tags"] || []
|
269
274
|
|
270
275
|
basic = Analyzers::Basic.new(title: title, description: description, artifacts: artifacts, source: "json", tags: tags)
|
271
276
|
basic.run
|
272
277
|
end
|
273
278
|
end
|
274
279
|
|
275
|
-
desc "
|
276
|
-
method_option :
|
277
|
-
method_option :
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
with_error_handling do
|
282
|
-
load_configuration
|
280
|
+
desc "web", "Launch the web app"
|
281
|
+
method_option :port, type: :numeric, default: 9292
|
282
|
+
method_option :host, type: :string, default: "localhost"
|
283
|
+
def web
|
284
|
+
port = options["port"].to_i || 9292
|
285
|
+
host = options["host"] || "localhost"
|
283
286
|
|
284
|
-
|
285
|
-
|
286
|
-
puts JSON.pretty_generate(alerts)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
desc "status", "Show the current configuration status"
|
291
|
-
def status
|
292
|
-
with_error_handling do
|
293
|
-
load_configuration
|
294
|
-
|
295
|
-
puts JSON.pretty_generate(Status.check)
|
296
|
-
end
|
287
|
+
load_configuration
|
288
|
+
Mihari::App.run!(port: port, host: host)
|
297
289
|
end
|
298
290
|
|
299
291
|
no_commands do
|
@@ -312,7 +304,7 @@ module Mihari
|
|
312
304
|
|
313
305
|
# @return [true, false]
|
314
306
|
def valid_json?(json)
|
315
|
-
%w
|
307
|
+
%w[title description artifacts].all? { |key| json.key? key }
|
316
308
|
end
|
317
309
|
|
318
310
|
def load_configuration
|
data/lib/mihari/config.rb
CHANGED
@@ -4,31 +4,7 @@ require "yaml"
|
|
4
4
|
|
5
5
|
module Mihari
|
6
6
|
class Config
|
7
|
-
attr_accessor :binaryedge_api_key
|
8
|
-
attr_accessor :censys_id
|
9
|
-
attr_accessor :censys_secret
|
10
|
-
attr_accessor :circl_passive_password
|
11
|
-
attr_accessor :circl_passive_username
|
12
|
-
attr_accessor :misp_api_endpoint
|
13
|
-
attr_accessor :misp_api_key
|
14
|
-
attr_accessor :onyphe_api_key
|
15
|
-
attr_accessor :otx_api_key
|
16
|
-
attr_accessor :passivetotal_api_key
|
17
|
-
attr_accessor :passivetotal_username
|
18
|
-
attr_accessor :pulsedive_api_key
|
19
|
-
attr_accessor :securitytrails_api_key
|
20
|
-
attr_accessor :shodan_api_key
|
21
|
-
attr_accessor :slack_channel
|
22
|
-
attr_accessor :slack_webhook_url
|
23
|
-
attr_accessor :spyse_api_key
|
24
|
-
attr_accessor :thehive_api_endpoint
|
25
|
-
attr_accessor :thehive_api_key
|
26
|
-
attr_accessor :urlscan_api_key
|
27
|
-
attr_accessor :virustotal_api_key
|
28
|
-
attr_accessor :zoomeye_password
|
29
|
-
attr_accessor :zoomeye_username
|
30
|
-
|
31
|
-
attr_accessor :database
|
7
|
+
attr_accessor :binaryedge_api_key, :censys_id, :censys_secret, :circl_passive_password, :circl_passive_username, :misp_api_endpoint, :misp_api_key, :onyphe_api_key, :otx_api_key, :passivetotal_api_key, :passivetotal_username, :pulsedive_api_key, :securitytrails_api_key, :shodan_api_key, :slack_channel, :slack_webhook_url, :spyse_api_key, :thehive_api_endpoint, :thehive_api_key, :urlscan_api_key, :virustotal_api_key, :zoomeye_password, :zoomeye_username, :database
|
32
8
|
|
33
9
|
def initialize
|
34
10
|
load_from_env
|
data/lib/mihari/configurable.rb
CHANGED
@@ -6,13 +6,12 @@ module Mihari
|
|
6
6
|
config_keys.all? { |key| Mihari.config.send(key) }
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def configuration_values
|
10
10
|
return nil if config_keys.empty?
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
"#{names} #{be_verb} #{status}"
|
12
|
+
config_keys.map do |key|
|
13
|
+
{key: key.upcase, value: Mihari.config.send(key)}
|
14
|
+
end
|
16
15
|
end
|
17
16
|
|
18
17
|
def config_keys
|
data/lib/mihari/database.rb
CHANGED
@@ -34,6 +34,7 @@ end
|
|
34
34
|
|
35
35
|
def adapter
|
36
36
|
return "postgresql" if Mihari.config.database.start_with?("postgresql://", "postgres://")
|
37
|
+
return "mysql2" if Mihari.config.database.start_with?("mysql2://")
|
37
38
|
|
38
39
|
"sqlite3"
|
39
40
|
end
|
@@ -43,7 +44,7 @@ module Mihari
|
|
43
44
|
class << self
|
44
45
|
def connect
|
45
46
|
case adapter
|
46
|
-
when "postgresql"
|
47
|
+
when "postgresql", "mysql2"
|
47
48
|
ActiveRecord::Base.establish_connection(Mihari.config.database)
|
48
49
|
else
|
49
50
|
ActiveRecord::Base.establish_connection(
|
@@ -58,6 +59,11 @@ module Mihari
|
|
58
59
|
# Do nothing
|
59
60
|
end
|
60
61
|
|
62
|
+
def close
|
63
|
+
ActiveRecord::Base.clear_active_connections!
|
64
|
+
ActiveRecord::Base.connection.close
|
65
|
+
end
|
66
|
+
|
61
67
|
def destroy!
|
62
68
|
InitialSchema.migrate(:down) if ActiveRecord::Base.connected?
|
63
69
|
end
|
data/lib/mihari/emitters/misp.rb
CHANGED
@@ -7,6 +7,8 @@ module Mihari
|
|
7
7
|
module Emitters
|
8
8
|
class MISP < Base
|
9
9
|
def initialize
|
10
|
+
super()
|
11
|
+
|
10
12
|
::MISP.configure do |config|
|
11
13
|
config.api_endpoint = Mihari.config.misp_api_endpoint
|
12
14
|
config.api_key = Mihari.config.misp_api_key
|
@@ -35,7 +37,7 @@ module Mihari
|
|
35
37
|
private
|
36
38
|
|
37
39
|
def config_keys
|
38
|
-
%w
|
40
|
+
%w[misp_api_endpoint misp_api_key]
|
39
41
|
end
|
40
42
|
|
41
43
|
def build_attribute(artifact)
|
@@ -61,7 +63,7 @@ module Mihari
|
|
61
63
|
ip: "ip-dst",
|
62
64
|
mail: "email-dst",
|
63
65
|
url: "url",
|
64
|
-
domain: "domain"
|
66
|
+
domain: "domain"
|
65
67
|
}
|
66
68
|
return table[type] if table.key?(type)
|
67
69
|
|
@@ -19,25 +19,31 @@ module Mihari
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def actions
|
22
|
-
[vt_link, urlscan_link, censys_link].compact
|
22
|
+
[vt_link, urlscan_link, censys_link, shodan_link].compact
|
23
23
|
end
|
24
24
|
|
25
25
|
def vt_link
|
26
26
|
return nil unless _vt_link
|
27
27
|
|
28
|
-
{
|
28
|
+
{type: "button", text: "VirusTotal", url: _vt_link}
|
29
29
|
end
|
30
30
|
|
31
31
|
def urlscan_link
|
32
32
|
return nil unless _urlscan_link
|
33
33
|
|
34
|
-
{
|
34
|
+
{type: "button", text: "urlscan.io", url: _urlscan_link}
|
35
35
|
end
|
36
36
|
|
37
37
|
def censys_link
|
38
38
|
return nil unless _censys_link
|
39
39
|
|
40
|
-
{
|
40
|
+
{type: "button", text: "Censys", url: _censys_link}
|
41
|
+
end
|
42
|
+
|
43
|
+
def shodan_link
|
44
|
+
return nil unless _shodan_link
|
45
|
+
|
46
|
+
{type: "button", text: "Shodan", url: _shodan_link}
|
41
47
|
end
|
42
48
|
|
43
49
|
# @return [Array]
|
@@ -89,6 +95,11 @@ module Mihari
|
|
89
95
|
end
|
90
96
|
memoize :_censys_link
|
91
97
|
|
98
|
+
def _shodan_link
|
99
|
+
data_type == "ip" ? "https://www.shodan.io/host/#{data}" : nil
|
100
|
+
end
|
101
|
+
memoize :_shodan_link
|
102
|
+
|
92
103
|
# @return [String]
|
93
104
|
def sha256
|
94
105
|
Digest::SHA256.hexdigest data
|
@@ -96,7 +107,7 @@ module Mihari
|
|
96
107
|
|
97
108
|
# @return [String]
|
98
109
|
def defanged_data
|
99
|
-
@defanged_data ||= data.to_s.gsub
|
110
|
+
@defanged_data ||= data.to_s.gsub(/\./, "[.]")
|
100
111
|
end
|
101
112
|
end
|
102
113
|
|
@@ -121,7 +132,7 @@ module Mihari
|
|
121
132
|
[
|
122
133
|
"*#{title}*",
|
123
134
|
"*Desc.*: #{description}",
|
124
|
-
"*Tags*: #{tags.join(
|
135
|
+
"*Tags*: #{tags.join(", ")}"
|
125
136
|
].join("\n")
|
126
137
|
end
|
127
138
|
|
@@ -137,7 +148,7 @@ module Mihari
|
|
137
148
|
private
|
138
149
|
|
139
150
|
def config_keys
|
140
|
-
%w
|
151
|
+
%w[slack_webhook_url]
|
141
152
|
end
|
142
153
|
end
|
143
154
|
end
|
@@ -17,7 +17,7 @@ module Mihari
|
|
17
17
|
api.alert.create(
|
18
18
|
title: title,
|
19
19
|
description: description,
|
20
|
-
artifacts: artifacts.map { |artifact| {
|
20
|
+
artifacts: artifacts.map { |artifact| {data: artifact.data, data_type: artifact.data_type, message: description} },
|
21
21
|
tags: tags,
|
22
22
|
type: "external",
|
23
23
|
source: "mihari"
|
@@ -27,7 +27,7 @@ module Mihari
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def config_keys
|
30
|
-
%w
|
30
|
+
%w[thehive_api_endpoint thehive_api_key]
|
31
31
|
end
|
32
32
|
|
33
33
|
def api
|
data/lib/mihari/errors.rb
CHANGED
data/lib/mihari/models/alert.rb
CHANGED
@@ -1,11 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record"
|
4
|
+
require "active_record/filter"
|
4
5
|
|
5
6
|
module Mihari
|
6
7
|
class Alert < ActiveRecord::Base
|
7
8
|
has_many :taggings, dependent: :destroy
|
8
9
|
has_many :artifacts, dependent: :destroy
|
9
10
|
has_many :tags, through: :taggings
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def search(artifact_data: nil, description: nil, source: nil, tag_name: nil, title: nil, from_at: nil, to_at: nil, limit: 10, page: 1)
|
14
|
+
limit = limit.to_i
|
15
|
+
raise ArgumentError, "limit should be bigger than zero" unless limit.positive?
|
16
|
+
|
17
|
+
page = page.to_i
|
18
|
+
raise ArgumentError, "page should be bigger than zero" unless page.positive?
|
19
|
+
|
20
|
+
offset = (page - 1) * limit
|
21
|
+
|
22
|
+
relation = build_relation(artifact_data: artifact_data, title: title, description: description, source: source, tag_name: tag_name, from_at: from_at, to_at: to_at)
|
23
|
+
# relation = relation.group("alerts.id")
|
24
|
+
|
25
|
+
alerts = relation.limit(limit).offset(offset).order(id: :desc)
|
26
|
+
|
27
|
+
alerts.map do |alert|
|
28
|
+
json = AlertSerializer.new(alert).as_json
|
29
|
+
json[:artifacts] = json[:artifacts] || []
|
30
|
+
json[:tags] = json[:tags] || []
|
31
|
+
json
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def count(artifact_data: nil, description: nil, source: nil, tag_name: nil, title: nil, from_at: nil, to_at: nil)
|
36
|
+
relation = build_relation(artifact_data: artifact_data, title: title, description: description, source: source, tag_name: tag_name, from_at: from_at, to_at: to_at)
|
37
|
+
relation.distinct("alerts.id").count
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def build_relation(artifact_data: nil, title: nil, description: nil, source: nil, tag_name: nil, from_at: nil, to_at: nil)
|
43
|
+
relation = self
|
44
|
+
relation = joins(:tags) if tag_name
|
45
|
+
relation = joins(:artifacts) if artifact_data
|
46
|
+
|
47
|
+
relation = relation.where(artifacts: {data: artifact_data}) if artifact_data
|
48
|
+
relation = relation.where(tags: {name: tag_name}) if tag_name
|
49
|
+
|
50
|
+
relation = relation.where(source: source) if source
|
51
|
+
relation = relation.where(title: title) if title
|
52
|
+
|
53
|
+
relation = relation.filter(description: {like: "%#{description}%"}) if description
|
54
|
+
|
55
|
+
relation = relation.filter(created_at: {gte: from_at}) if from_at
|
56
|
+
relation = relation.filter(created_at: {lte: to_at}) if to_at
|
57
|
+
|
58
|
+
relation
|
59
|
+
end
|
60
|
+
end
|
10
61
|
end
|
11
62
|
end
|
@@ -19,7 +19,7 @@ module Mihari
|
|
19
19
|
def notify(exception)
|
20
20
|
notify_to_stdout exception
|
21
21
|
|
22
|
-
clean_message = exception.message.tr(
|
22
|
+
clean_message = exception.message.tr("`", "'")
|
23
23
|
attachments = to_attachments(exception, clean_message)
|
24
24
|
notify_to_slack(text: clean_message, attachments: attachments) if @slack.valid?
|
25
25
|
end
|
@@ -51,20 +51,20 @@ module Mihari
|
|
51
51
|
|
52
52
|
def to_fields(clean_message, backtrace)
|
53
53
|
fields = [
|
54
|
-
{
|
55
|
-
{
|
54
|
+
{title: "Exception", value: clean_message},
|
55
|
+
{title: "Hostname", value: hostname}
|
56
56
|
]
|
57
57
|
|
58
58
|
if backtrace
|
59
59
|
formatted_backtrace = format_backtrace(backtrace)
|
60
|
-
fields << {
|
60
|
+
fields << {title: "Backtrace", value: formatted_backtrace}
|
61
61
|
end
|
62
62
|
fields
|
63
63
|
end
|
64
64
|
|
65
65
|
def hostname
|
66
66
|
Socket.gethostname
|
67
|
-
rescue
|
67
|
+
rescue => _e
|
68
68
|
"N/A"
|
69
69
|
end
|
70
70
|
|
@@ -4,7 +4,7 @@ require "active_model_serializers"
|
|
4
4
|
|
5
5
|
module Mihari
|
6
6
|
class AlertSerializer < ActiveModel::Serializer
|
7
|
-
attributes :title, :description, :source, :created_at
|
7
|
+
attributes :id, :title, :description, :source, :created_at
|
8
8
|
|
9
9
|
has_many :artifacts
|
10
10
|
has_many :tags, through: :taggings
|
data/lib/mihari/status.rb
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
module Mihari
|
4
4
|
class Status
|
5
5
|
def check
|
6
|
-
statuses.
|
7
|
-
[key, convert(**value)]
|
8
|
-
end.to_h
|
6
|
+
statuses.transform_values { |value| convert(**value) }
|
9
7
|
end
|
10
8
|
|
11
9
|
def self.check
|
@@ -14,16 +12,17 @@ module Mihari
|
|
14
12
|
|
15
13
|
private
|
16
14
|
|
17
|
-
def convert(
|
15
|
+
def convert(is_configured:, values:, type:)
|
18
16
|
{
|
19
|
-
|
20
|
-
|
17
|
+
is_configured: is_configured,
|
18
|
+
values: values,
|
19
|
+
type: type
|
21
20
|
}
|
22
21
|
end
|
23
22
|
|
24
23
|
def statuses
|
25
24
|
(Mihari.analyzers + Mihari.emitters).map do |klass|
|
26
|
-
name = klass.to_s.
|
25
|
+
name = klass.to_s.split("::").last.to_s
|
27
26
|
|
28
27
|
[name, build_status(klass)]
|
29
28
|
end.to_h.compact
|
@@ -33,10 +32,11 @@ module Mihari
|
|
33
32
|
is_analyzer = klass.ancestors.include?(Mihari::Analyzers::Base)
|
34
33
|
|
35
34
|
instance = is_analyzer ? klass.new("dummy") : klass.new
|
36
|
-
|
37
|
-
|
35
|
+
is_configured = instance.configured?
|
36
|
+
values = instance.configuration_values
|
37
|
+
type = is_analyzer ? "Analyzer" : "Emitter"
|
38
38
|
|
39
|
-
|
39
|
+
values ? {is_configured: is_configured, values: values, type: type} : nil
|
40
40
|
rescue ArgumentError => _e
|
41
41
|
nil
|
42
42
|
end
|