mihari 5.1.4 → 5.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mihari/commands/web.rb +12 -8
- data/lib/mihari/entities/artifact.rb +3 -2
- data/lib/mihari/mixins/configurable.rb +3 -1
- data/lib/mihari/models/alert.rb +16 -12
- data/lib/mihari/models/rule.rb +1 -2
- data/lib/mihari/schemas/rule.rb +1 -0
- data/lib/mihari/structs/filters.rb +1 -15
- data/lib/mihari/structs/rule.rb +1 -1
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +9 -7
- data/lib/mihari/web/endpoints/alerts.rb +7 -20
- data/lib/mihari/web/endpoints/rules.rb +4 -11
- data/lib/mihari/web/public/assets/{fa-brands-400-2ef6fdde.ttf → fa-brands-400-20c4a58b.ttf} +0 -0
- data/lib/mihari/web/public/assets/fa-brands-400-74833209.woff2 +0 -0
- data/lib/mihari/web/public/assets/{fa-regular-400-12dea17b.ttf → fa-regular-400-528d022d.ttf} +0 -0
- data/lib/mihari/web/public/assets/fa-regular-400-8e7e5ea1.woff2 +0 -0
- data/lib/mihari/web/public/assets/{fa-solid-900-67a880b4.ttf → fa-solid-900-67a65763.ttf} +0 -0
- data/lib/mihari/web/public/assets/fa-solid-900-7152a693.woff2 +0 -0
- data/lib/mihari/web/public/assets/{fa-v4compatibility-8d9500e8.ttf → fa-v4compatibility-0515a423.ttf} +0 -0
- data/lib/mihari/web/public/assets/fa-v4compatibility-694a17c3.woff2 +0 -0
- data/lib/mihari/web/public/assets/index-cbe1734c.js +50 -0
- data/lib/mihari/web/public/assets/index-eed1bcd8.css +5 -0
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari/web/public/redoc-static.html +7 -4
- data/lib/mihari.rb +2 -0
- data/mihari.gemspec +13 -13
- metadata +40 -40
- data/lib/mihari/web/public/assets/fa-brands-400-f4617423.woff2 +0 -0
- data/lib/mihari/web/public/assets/fa-regular-400-7ba24c41.woff2 +0 -0
- data/lib/mihari/web/public/assets/fa-solid-900-e2c5cf54.woff2 +0 -0
- data/lib/mihari/web/public/assets/fa-v4compatibility-7c377405.woff2 +0 -0
- data/lib/mihari/web/public/assets/index-625e95fe.css +0 -5
- data/lib/mihari/web/public/assets/index-7d0fb8c4.js +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ce7e22d3d54cc3e66fec62b494ce5f9def9107129513cd51803c71b8ae48b18
|
4
|
+
data.tar.gz: fd85f33a666a77a8b43d12dc3234ab2656cd843c8f7e23025c1a5f076947fbcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a17809e3c6f52e7d37f6df2fc92b0ad5a1d134556e6ef13cb64b3802074a44f2ecd0c2475ab632e5da0f57e7c68a44fca15f722f31124fbb9e8af512f46aa2ac
|
7
|
+
data.tar.gz: d777cac77ceeb2a98c8f37a8e001d9240403b47a1e2326a6f1bc42c3cf48e7813dd69ab2260ce5a29a34b7b9b3e0ef54fa541785f8b5dbc82b787381e549525e
|
data/lib/mihari/commands/web.rb
CHANGED
@@ -11,17 +11,21 @@ module Mihari
|
|
11
11
|
method_option :threads, type: :string, default: "0:5", desc: "min:max threads to use"
|
12
12
|
method_option :verbose, type: :boolean, default: true, desc: "Report each request"
|
13
13
|
method_option :worker_timeout, type: :numeric, default: 60, desc: "Worker timeout value (in seconds)"
|
14
|
+
method_option :hide_config_values, type: :boolean, default: false,
|
15
|
+
desc: "Whether to hide config values or not"
|
16
|
+
method_option :open, type: :boolean, default: true, desc: "Whether to open the app in browser or not"
|
14
17
|
def web
|
15
|
-
|
16
|
-
host = options["host"]
|
17
|
-
threads = options["threads"]
|
18
|
-
verbose = options["verbose"]
|
19
|
-
worker_timeout = options["worker_timeout"]
|
20
|
-
|
18
|
+
Mihari.config.hide_config_values = options["hide_config_values"]
|
21
19
|
# set rack env as production
|
22
20
|
ENV["RACK_ENV"] ||= "production"
|
23
|
-
|
24
|
-
|
21
|
+
Mihari::App.run!(
|
22
|
+
port: options["port"],
|
23
|
+
host: options["host"],
|
24
|
+
threads: options["threads"],
|
25
|
+
verbose: options["verbose"],
|
26
|
+
worker_timeout: options["worker_timeout"],
|
27
|
+
open: options["open"]
|
28
|
+
)
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -12,11 +12,12 @@ module Mihari
|
|
12
12
|
expose :data_type, documentation: { type: String, required: true }, as: :dataType
|
13
13
|
expose :source, documentation: { type: String, required: true }
|
14
14
|
expose :tags, documentation: { type: String, is_array: true }
|
15
|
-
|
16
|
-
expose :metadata, documentation: { type: Hash }
|
17
15
|
end
|
18
16
|
|
19
17
|
class Artifact < BaseArtifact
|
18
|
+
# NOTE: do not define metadata in BaseArtifact since metadata can be relatively big
|
19
|
+
expose :metadata, documentation: { type: Hash }
|
20
|
+
|
20
21
|
expose :autonomous_system, using: Entities::AutonomousSystem,
|
21
22
|
documentation: { type: Entities::AutonomousSystem, required: false }, as: :autonomousSystem
|
22
23
|
expose :geolocation, using: Entities::Geolocation, documentation: { type: Entities::Geolocation, required: false }
|
@@ -23,7 +23,9 @@ module Mihari
|
|
23
23
|
return nil if configuration_keys.empty?
|
24
24
|
|
25
25
|
configuration_keys.map do |key|
|
26
|
-
|
26
|
+
value = Mihari.config.send(key)
|
27
|
+
value = "REDACTED" if value && Mihari.config.hide_config_values
|
28
|
+
{ key: key.upcase, value: value }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
data/lib/mihari/models/alert.rb
CHANGED
@@ -48,22 +48,29 @@ module Mihari
|
|
48
48
|
#
|
49
49
|
# @param [Structs::Filters::Alert::SearchFilter] filter
|
50
50
|
#
|
51
|
-
# @return [
|
51
|
+
# @return [Array<Integer>]
|
52
52
|
#
|
53
|
-
def
|
53
|
+
def get_artifact_ids_by_filter(filter)
|
54
54
|
artifact_ids = []
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
artifact = artifact.where(dns_records: { value: filter.dns_record }) if filter.dns_record
|
59
|
-
artifact = artifact.where(reverse_dns_names: { name: filter.reverse_dns_name }) if filter.reverse_dns_name
|
60
|
-
# get artifact ids if there is any valid filter for artifact
|
61
|
-
if filter.valid_artifact_filters?
|
55
|
+
|
56
|
+
if filter.artifact_data
|
57
|
+
artifact = Artifact.where(data: filter.artifact_data)
|
62
58
|
artifact_ids = artifact.pluck(:id)
|
63
59
|
# set invalid ID if nothing is matched with the filters
|
64
60
|
artifact_ids = [-1] if artifact_ids.empty?
|
65
61
|
end
|
66
62
|
|
63
|
+
artifact_ids
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# @param [Structs::Filters::Alert::SearchFilter] filter
|
68
|
+
#
|
69
|
+
# @return [Mihari::Alert]
|
70
|
+
#
|
71
|
+
def build_relation(filter)
|
72
|
+
artifact_ids = get_artifact_ids_by_filter(filter)
|
73
|
+
|
67
74
|
relation = self
|
68
75
|
relation = relation.includes(:artifacts, :tags)
|
69
76
|
|
@@ -71,9 +78,6 @@ module Mihari
|
|
71
78
|
relation = relation.where(tags: { name: filter.tag_name }) if filter.tag_name
|
72
79
|
|
73
80
|
relation = relation.where(rule_id: filter.rule_id) if filter.rule_id
|
74
|
-
relation = relation.where(title: filter.title) if filter.title
|
75
|
-
|
76
|
-
relation = relation.where("description LIKE ?", "%#{filter.description}%") if filter.description
|
77
81
|
|
78
82
|
relation = relation.where("alerts.created_at >= ?", filter.from_at) if filter.from_at
|
79
83
|
relation = relation.where("alerts.created_at <= ?", filter.to_at) if filter.to_at
|
data/lib/mihari/models/rule.rb
CHANGED
@@ -67,8 +67,7 @@ module Mihari
|
|
67
67
|
|
68
68
|
relation = relation.where(alerts: { tags: { name: filter.tag_name } }) if filter.tag_name
|
69
69
|
|
70
|
-
relation = relation.where(title
|
71
|
-
|
70
|
+
relation = relation.where("rules.title LIKE ?", "%#{filter.title}%") if filter.title
|
72
71
|
relation = relation.where("rules.description LIKE ?", "%#{filter.description}%") if filter.description
|
73
72
|
|
74
73
|
relation = relation.where("rules.created_at >= ?", filter.from_at) if filter.from_at
|
data/lib/mihari/schemas/rule.rb
CHANGED
@@ -33,6 +33,7 @@ module Mihari
|
|
33
33
|
optional(:falsepositives).value(array[:string]).default([])
|
34
34
|
|
35
35
|
optional(:artifact_lifetime).value(:integer)
|
36
|
+
optional(:artifact_ttl).value(:integer)
|
36
37
|
|
37
38
|
before(:key_coercer) do |result|
|
38
39
|
# it looks like that dry-schema v1.9.1 has an issue with setting an array of schemas as a default value
|
@@ -6,19 +6,10 @@ module Mihari
|
|
6
6
|
module Alert
|
7
7
|
class SearchFilter < Dry::Struct
|
8
8
|
attribute? :artifact_data, Types::String.optional
|
9
|
-
attribute? :description, Types::String.optional
|
10
9
|
attribute? :rule_id, Types::String.optional
|
11
10
|
attribute? :tag_name, Types::String.optional
|
12
|
-
attribute? :title, Types::String.optional
|
13
11
|
attribute? :from_at, Types::DateTime.optional
|
14
12
|
attribute? :to_at, Types::DateTime.optional
|
15
|
-
attribute? :asn, Types::Int.optional
|
16
|
-
attribute? :dns_record, Types::String.optional
|
17
|
-
attribute? :reverse_dns_name, Types::String.optional
|
18
|
-
|
19
|
-
def valid_artifact_filters?
|
20
|
-
!(artifact_data || asn || dns_record || reverse_dns_name).nil?
|
21
|
-
end
|
22
13
|
end
|
23
14
|
|
24
15
|
class SearchFilterWithPagination < SearchFilter
|
@@ -28,15 +19,10 @@ module Mihari
|
|
28
19
|
def without_pagination
|
29
20
|
SearchFilter.new(
|
30
21
|
artifact_data: artifact_data,
|
31
|
-
description: description,
|
32
22
|
from_at: from_at,
|
33
23
|
rule_id: rule_id,
|
34
24
|
tag_name: tag_name,
|
35
|
-
|
36
|
-
to_at: to_at,
|
37
|
-
asn: asn,
|
38
|
-
dns_record: dns_record,
|
39
|
-
reverse_dns_name: reverse_dns_name
|
25
|
+
to_at: to_at
|
40
26
|
)
|
41
27
|
end
|
42
28
|
end
|
data/lib/mihari/structs/rule.rb
CHANGED
data/lib/mihari/version.rb
CHANGED
data/lib/mihari/web/app.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "launchy"
|
4
|
+
|
4
5
|
require "rack"
|
5
|
-
require "
|
6
|
-
require "rack/handler/puma"
|
6
|
+
require "rackup"
|
7
7
|
require "rack/cors"
|
8
8
|
|
9
|
+
require "rack/handler/puma"
|
10
|
+
|
9
11
|
require "grape-swagger"
|
10
12
|
require "grape-swagger-entity"
|
11
13
|
|
@@ -18,7 +20,7 @@ module Mihari
|
|
18
20
|
class App
|
19
21
|
def initialize
|
20
22
|
@filenames = ["", ".html", "index.html", "/index.html"]
|
21
|
-
@rack_static =
|
23
|
+
@rack_static = Rack::Static.new(
|
22
24
|
-> { [404, {}, []] },
|
23
25
|
root: File.expand_path("./public", __dir__),
|
24
26
|
urls: ["/"]
|
@@ -42,7 +44,7 @@ module Mihari
|
|
42
44
|
end.to_app
|
43
45
|
end
|
44
46
|
|
45
|
-
def run!(port: 9292, host: "localhost", threads: "0:5", verbose: false, worker_timeout: 60)
|
47
|
+
def run!(port: 9292, host: "localhost", threads: "0:5", verbose: false, worker_timeout: 60, open: true)
|
46
48
|
url = "http://#{host}:#{port}"
|
47
49
|
|
48
50
|
# set maximum number of threads to use as PARALLEL_PROCESSOR_COUNT (if it is not set)
|
@@ -50,15 +52,15 @@ module Mihari
|
|
50
52
|
# TODO: is this the best way?
|
51
53
|
_min_thread, max_thread = threads.split(":")
|
52
54
|
ENV["PARALLEL_PROCESSOR_COUNT"] = max_thread if ENV["PARALLEL_PROCESSOR_COUNT"].nil?
|
53
|
-
|
55
|
+
Rackup::Handler::Puma.run(
|
54
56
|
instance,
|
55
57
|
Port: port,
|
56
58
|
Host: host,
|
57
59
|
Threads: threads,
|
58
60
|
Verbose: verbose,
|
59
61
|
worker_timeout: worker_timeout
|
60
|
-
) do |
|
61
|
-
Launchy.open(url) if ENV["RACK_ENV"] != "development"
|
62
|
+
) do |_|
|
63
|
+
Launchy.open(url) if ENV["RACK_ENV"] != "development" && open
|
62
64
|
rescue Launchy::CommandNotFoundError
|
63
65
|
# ref. https://github.com/ninoseki/mihari/issues/477
|
64
66
|
# do nothing
|
@@ -11,48 +11,35 @@ module Mihari
|
|
11
11
|
summary: "Search alerts"
|
12
12
|
}
|
13
13
|
params do
|
14
|
-
optional :page, type: Integer
|
14
|
+
optional :page, type: Integer, default: 1
|
15
|
+
optional :limit, type: Integer, default: 10
|
15
16
|
|
16
17
|
optional :artifact, type: String
|
17
|
-
optional :description, type: String
|
18
18
|
optional :rule_id, type: String
|
19
19
|
optional :tag, type: String
|
20
|
-
optional :title, type: String
|
21
20
|
|
22
21
|
optional :fromAt, type: DateTime
|
23
22
|
optional :toAt, type: DateTime
|
24
|
-
|
25
|
-
optional :asn, type: Integer
|
26
|
-
optional :dnsRecord, type: String
|
27
|
-
optional :reverseDnsName, type: String
|
28
23
|
end
|
29
24
|
get "/" do
|
30
25
|
filter = params.to_h.to_snake_keys
|
31
26
|
|
32
|
-
# set page & limit
|
33
|
-
page = filter["page"] || 1
|
34
|
-
filter["page"] = page.to_i
|
35
|
-
|
36
|
-
limit = 10
|
37
|
-
filter["limit"] = 10
|
38
|
-
|
39
27
|
# normalize keys
|
40
28
|
filter["artifact_data"] = filter["artifact"]
|
41
29
|
filter["tag_name"] = filter["tag"]
|
42
|
-
|
43
30
|
# symbolize hash keys
|
44
31
|
filter = filter.to_h.symbolize_keys
|
45
32
|
|
46
|
-
|
47
|
-
alerts = Mihari::Alert.search(
|
48
|
-
total = Mihari::Alert.count(
|
33
|
+
search_filter_with_pagination = Structs::Filters::Alert::SearchFilterWithPagination.new(**filter)
|
34
|
+
alerts = Mihari::Alert.search(search_filter_with_pagination)
|
35
|
+
total = Mihari::Alert.count(search_filter_with_pagination.without_pagination)
|
49
36
|
|
50
37
|
present(
|
51
38
|
{
|
52
39
|
alerts: alerts,
|
53
40
|
total: total,
|
54
|
-
current_page: page,
|
55
|
-
page_size: limit
|
41
|
+
current_page: filter[:page].to_i,
|
42
|
+
page_size: filter[:limit].to_i
|
56
43
|
},
|
57
44
|
with: Entities::AlertsWithPagination
|
58
45
|
)
|
@@ -21,7 +21,8 @@ module Mihari
|
|
21
21
|
summary: "Search rules"
|
22
22
|
}
|
23
23
|
params do
|
24
|
-
optional :page, type: Integer
|
24
|
+
optional :page, type: Integer, default: 1
|
25
|
+
optional :limit, type: Integer, default: 10
|
25
26
|
|
26
27
|
optional :title, type: String
|
27
28
|
optional :description, type: String
|
@@ -33,16 +34,8 @@ module Mihari
|
|
33
34
|
get "/" do
|
34
35
|
filter = params.to_h.to_snake_keys
|
35
36
|
|
36
|
-
# set page & limit
|
37
|
-
page = filter["page"] || 1
|
38
|
-
filter["page"] = page.to_i
|
39
|
-
|
40
|
-
limit = 10
|
41
|
-
filter["limit"] = 10
|
42
|
-
|
43
37
|
# normalize keys
|
44
38
|
filter["tag_name"] = filter["tag"]
|
45
|
-
|
46
39
|
# symbolize hash keys
|
47
40
|
filter = filter.to_h.symbolize_keys
|
48
41
|
|
@@ -53,8 +46,8 @@ module Mihari
|
|
53
46
|
present(
|
54
47
|
{ rules: rules,
|
55
48
|
total: total,
|
56
|
-
current_page: page,
|
57
|
-
page_size: limit },
|
49
|
+
current_page: filter[:page].to_i,
|
50
|
+
page_size: filter[:limit].to_i },
|
58
51
|
with: Entities::RulesWithPagination
|
59
52
|
)
|
60
53
|
end
|
Binary file
|
Binary file
|
data/lib/mihari/web/public/assets/{fa-regular-400-12dea17b.ttf → fa-regular-400-528d022d.ttf}
RENAMED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|