mihari 5.3.0 → 5.3.2
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/Rakefile +8 -2
- data/frontend/package-lock.json +657 -576
- data/frontend/package.json +23 -20
- data/frontend/src/ace-config.ts +6 -0
- data/frontend/src/components/Loading.vue +1 -1
- data/frontend/src/components/alert/Alert.vue +1 -1
- data/frontend/src/components/alert/AlertsWrapper.vue +1 -1
- data/frontend/src/components/alert/Form.vue +2 -2
- data/frontend/src/components/artifact/Artifact.vue +3 -3
- data/frontend/src/components/config/Configs.vue +2 -2
- data/frontend/src/components/rule/EditRule.vue +4 -3
- data/frontend/src/components/rule/Form.vue +2 -2
- data/frontend/src/components/rule/InputForm.vue +18 -59
- data/frontend/src/components/rule/NewRule.vue +1 -1
- data/frontend/src/components/rule/Rule.vue +3 -3
- data/frontend/src/components/rule/RulesWrapper.vue +1 -1
- data/frontend/src/components/rule/YAML.vue +21 -28
- data/frontend/src/main.ts +33 -3
- data/frontend/src/views/Artifact.vue +3 -8
- data/frontend/src/views/EditRule.vue +2 -7
- data/frontend/src/views/Rule.vue +3 -8
- data/lib/mihari/analyzers/base.rb +6 -0
- data/lib/mihari/analyzers/binaryedge.rb +1 -1
- data/lib/mihari/analyzers/censys.rb +1 -1
- data/lib/mihari/analyzers/onyphe.rb +1 -1
- data/lib/mihari/analyzers/rule.rb +4 -7
- data/lib/mihari/analyzers/shodan.rb +1 -1
- data/lib/mihari/analyzers/urlscan.rb +1 -1
- data/lib/mihari/analyzers/virustotal_intelligence.rb +1 -1
- data/lib/mihari/analyzers/zoomeye.rb +2 -2
- data/lib/mihari/commands/rule.rb +3 -3
- data/lib/mihari/commands/search.rb +3 -3
- data/lib/mihari/constants.rb +3 -0
- data/lib/mihari/emitters/base.rb +2 -2
- data/lib/mihari/emitters/misp.rb +3 -3
- data/lib/mihari/emitters/slack.rb +1 -1
- data/lib/mihari/emitters/the_hive.rb +1 -1
- data/lib/mihari/emitters/webhook.rb +1 -1
- data/lib/mihari/mixins/configurable.rb +5 -0
- data/lib/mihari/mixins/falsepositive.rb +1 -1
- data/lib/mihari/mixins/retriable.rb +0 -2
- data/lib/mihari/{structs → services}/rule.rb +16 -16
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/endpoints/rules.rb +9 -8
- data/lib/mihari/web/public/assets/index-116033d0.js +1737 -0
- data/lib/mihari/web/public/assets/index-33165282.css +1 -0
- data/lib/mihari/web/public/assets/mode-yaml-a21faa53.js +8 -0
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari.rb +3 -2
- data/mihari.gemspec +5 -4
- metadata +15 -21
- data/lib/mihari/web/public/assets/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-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-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-0515a423.ttf +0 -0
- data/lib/mihari/web/public/assets/fa-v4compatibility-694a17c3.woff2 +0 -0
- data/lib/mihari/web/public/assets/index-2ba8f0a6.css +0 -5
- data/lib/mihari/web/public/assets/index-71285b15.js +0 -50
@@ -37,14 +37,14 @@ module Mihari
|
|
37
37
|
class Rule
|
38
38
|
include Mixins::FalsePositive
|
39
39
|
|
40
|
-
# @return [Mihari::
|
40
|
+
# @return [Mihari::Services::Rule]
|
41
41
|
attr_reader :rule
|
42
42
|
|
43
43
|
# @return [Time]
|
44
44
|
attr_reader :base_time
|
45
45
|
|
46
46
|
#
|
47
|
-
# @param [Mihari::
|
47
|
+
# @param [Mihari::Services::Rule] rule
|
48
48
|
#
|
49
49
|
def initialize(rule)
|
50
50
|
@rule = rule
|
@@ -146,11 +146,8 @@ module Mihari
|
|
146
146
|
def falsepositive?(value)
|
147
147
|
return true if rule.falsepositives.include?(value)
|
148
148
|
|
149
|
-
rule.falsepositives.select
|
150
|
-
|
151
|
-
end.any? do |falseposistive|
|
152
|
-
falseposistive.match?(value)
|
153
|
-
end
|
149
|
+
regexps = rule.falsepositives.select { |fp| fp.is_a?(Regexp) }
|
150
|
+
regexps.any? { |fp| fp.match?(value) }
|
154
151
|
end
|
155
152
|
|
156
153
|
#
|
@@ -60,7 +60,7 @@ module Mihari
|
|
60
60
|
break if res.total <= page * PAGE_SIZE
|
61
61
|
|
62
62
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
63
|
-
|
63
|
+
sleep_interval
|
64
64
|
rescue JSON::ParserError
|
65
65
|
# ignore JSON::ParserError
|
66
66
|
# ref. https://github.com/ninoseki/mihari/issues/197
|
@@ -104,7 +104,7 @@ module Mihari
|
|
104
104
|
break if total <= page * PAGE_SIZE
|
105
105
|
|
106
106
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
107
|
-
|
107
|
+
sleep_interval
|
108
108
|
end
|
109
109
|
convert_responses responses.compact
|
110
110
|
end
|
@@ -137,7 +137,7 @@ module Mihari
|
|
137
137
|
break if total <= page * PAGE_SIZE
|
138
138
|
|
139
139
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
140
|
-
|
140
|
+
sleep_interval
|
141
141
|
end
|
142
142
|
convert_responses responses.compact
|
143
143
|
end
|
data/lib/mihari/commands/rule.rb
CHANGED
@@ -15,7 +15,7 @@ module Mihari
|
|
15
15
|
# @param [String] path
|
16
16
|
#
|
17
17
|
def validate(path)
|
18
|
-
rule =
|
18
|
+
rule = Services::Rule.from_path_or_id(path)
|
19
19
|
|
20
20
|
begin
|
21
21
|
rule.validate!
|
@@ -44,10 +44,10 @@ module Mihari
|
|
44
44
|
|
45
45
|
no_commands do
|
46
46
|
#
|
47
|
-
# @return [Mihari::
|
47
|
+
# @return [Mihari::Services::Rule]
|
48
48
|
#
|
49
49
|
def rule_template
|
50
|
-
|
50
|
+
Services::Rule.from_path File.expand_path("../templates/rule.yml.erb", __dir__)
|
51
51
|
end
|
52
52
|
|
53
53
|
#
|
@@ -33,12 +33,12 @@ module Mihari
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def update_or_create
|
36
|
-
rule.
|
36
|
+
rule.to_model.save
|
37
37
|
end
|
38
38
|
|
39
39
|
def run
|
40
40
|
begin
|
41
|
-
analyzer = rule.
|
41
|
+
analyzer = rule.to_analyzer
|
42
42
|
rescue ConfigurationError => e
|
43
43
|
# if there is a configuration error, output that error without the stack trace
|
44
44
|
Mihari.logger.error e.to_s
|
@@ -69,7 +69,7 @@ module Mihari
|
|
69
69
|
#
|
70
70
|
def search(path_or_id)
|
71
71
|
Mihari::Database.with_db_connection do
|
72
|
-
rule =
|
72
|
+
rule = Services::Rule.from_path_or_id path_or_id
|
73
73
|
|
74
74
|
begin
|
75
75
|
rule.validate!
|
data/lib/mihari/constants.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mihari
|
4
|
+
# @return [Array<String>]
|
4
5
|
DEFAULT_DATA_TYPES = %w[hash ip domain url mail].freeze
|
5
6
|
|
7
|
+
# @return [Array<Hash>]
|
6
8
|
DEFAULT_EMITTERS = %w[database misp slack the_hive].map { |name| { emitter: name } }.freeze
|
7
9
|
|
10
|
+
# @return [Array<Hash>]
|
8
11
|
DEFAULT_ENRICHERS = %w[whois ipinfo shodan google_public_dns].map { |name| { enricher: name } }.freeze
|
9
12
|
|
10
13
|
DEFAULT_RETRY_TIMES = 3
|
data/lib/mihari/emitters/base.rb
CHANGED
@@ -9,12 +9,12 @@ module Mihari
|
|
9
9
|
# @return [Array<Mihari::Artifact>]
|
10
10
|
attr_reader :artifacts
|
11
11
|
|
12
|
-
# @return [Mihari::
|
12
|
+
# @return [Mihari::Services::Rule]
|
13
13
|
attr_reader :rule
|
14
14
|
|
15
15
|
#
|
16
16
|
# @param [Array<Mihari::Artifact>] artifacts
|
17
|
-
# @param [Mihari::
|
17
|
+
# @param [Mihari::Services::Rule] rule
|
18
18
|
# @param [Hash] **_options
|
19
19
|
#
|
20
20
|
def initialize(artifacts:, rule:, **_options)
|
data/lib/mihari/emitters/misp.rb
CHANGED
@@ -12,12 +12,12 @@ module Mihari
|
|
12
12
|
# @return [Array<Mihari::Artifact>]
|
13
13
|
attr_reader :artifacts
|
14
14
|
|
15
|
-
# @return [Mihari::
|
15
|
+
# @return [Mihari::Services::Rule]
|
16
16
|
attr_reader :rule
|
17
17
|
|
18
18
|
#
|
19
19
|
# @param [Array<Mihari::Artifact>] artifacts
|
20
|
-
# @param [Mihari::
|
20
|
+
# @param [Mihari::Services::Rule] rule
|
21
21
|
# @param [Hash] **options
|
22
22
|
#
|
23
23
|
def initialize(artifacts:, rule:, **options)
|
@@ -47,7 +47,7 @@ module Mihari
|
|
47
47
|
# Create a MISP event
|
48
48
|
#
|
49
49
|
# @param [Arra<Mihari::Artifact>] artifacts
|
50
|
-
# @param [Mihari::
|
50
|
+
# @param [Mihari::Services::Rule] rule
|
51
51
|
#
|
52
52
|
# @return [::MISP::Event]
|
53
53
|
#
|
@@ -8,7 +8,7 @@ require "securerandom"
|
|
8
8
|
require "yaml"
|
9
9
|
|
10
10
|
module Mihari
|
11
|
-
module
|
11
|
+
module Services
|
12
12
|
class Rule
|
13
13
|
include Mixins::FalsePositive
|
14
14
|
|
@@ -49,16 +49,16 @@ module Mihari
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def validate!
|
52
|
-
|
53
|
-
|
52
|
+
return unless errors?
|
53
|
+
|
54
54
|
Mihari.logger.error "Failed to parse the input as a rule:"
|
55
55
|
Mihari.logger.error JSON.pretty_generate(errors.to_h)
|
56
56
|
|
57
|
-
raise
|
57
|
+
raise RuleValidationError, errors
|
58
58
|
end
|
59
59
|
|
60
60
|
def [](key)
|
61
|
-
data
|
61
|
+
data key.to_sym
|
62
62
|
end
|
63
63
|
|
64
64
|
#
|
@@ -141,7 +141,7 @@ module Mihari
|
|
141
141
|
#
|
142
142
|
# @return [Mihari::Rule]
|
143
143
|
#
|
144
|
-
def
|
144
|
+
def to_model
|
145
145
|
rule = Mihari::Rule.find(id)
|
146
146
|
|
147
147
|
rule.title = title
|
@@ -161,8 +161,8 @@ module Mihari
|
|
161
161
|
#
|
162
162
|
# @return [Mihari::Analyzers::Rule]
|
163
163
|
#
|
164
|
-
def
|
165
|
-
Mihari::Analyzers::Rule.new
|
164
|
+
def to_analyzer
|
165
|
+
Mihari::Analyzers::Rule.new self
|
166
166
|
end
|
167
167
|
|
168
168
|
class << self
|
@@ -171,10 +171,10 @@ module Mihari
|
|
171
171
|
#
|
172
172
|
# @param [String] yaml
|
173
173
|
#
|
174
|
-
# @return [Mihari::
|
174
|
+
# @return [Mihari::Services::Rule]
|
175
175
|
#
|
176
176
|
def from_yaml(yaml)
|
177
|
-
|
177
|
+
Services::Rule.new YAML.safe_load(ERB.new(yaml).result, permitted_classes: [Date, Symbol])
|
178
178
|
rescue Psych::SyntaxError => e
|
179
179
|
raise YAMLSyntaxError, e.message
|
180
180
|
end
|
@@ -182,10 +182,10 @@ module Mihari
|
|
182
182
|
#
|
183
183
|
# @param [Mihari::Rule] model
|
184
184
|
#
|
185
|
-
# @return [Mihari::
|
185
|
+
# @return [Mihari::Services::Rule]
|
186
186
|
#
|
187
187
|
def from_model(model)
|
188
|
-
|
188
|
+
Services::Rule.new model.data
|
189
189
|
end
|
190
190
|
|
191
191
|
#
|
@@ -193,7 +193,7 @@ module Mihari
|
|
193
193
|
#
|
194
194
|
# @param [String] path
|
195
195
|
#
|
196
|
-
# @return [Mihari::
|
196
|
+
# @return [Mihari::Services::Rule, nil]
|
197
197
|
#
|
198
198
|
def from_path(path)
|
199
199
|
return nil unless Pathname(path).exist?
|
@@ -206,18 +206,18 @@ module Mihari
|
|
206
206
|
#
|
207
207
|
# @param [String] id
|
208
208
|
#
|
209
|
-
# @return [Mihari::
|
209
|
+
# @return [Mihari::Services::Rule, nil]
|
210
210
|
#
|
211
211
|
def from_id(id)
|
212
212
|
return nil unless Mihari::Rule.exists?(id)
|
213
213
|
|
214
|
-
|
214
|
+
Services::Rule.from_model Mihari::Rule.find(id)
|
215
215
|
end
|
216
216
|
|
217
217
|
#
|
218
218
|
# @param [String] path_or_id Path to YAML file or YAML string or ID of a rule in the database
|
219
219
|
#
|
220
|
-
# @return [Mihari::
|
220
|
+
# @return [Mihari::Services::Rule]
|
221
221
|
#
|
222
222
|
def from_path_or_id(path_or_id)
|
223
223
|
rule = from_path(path_or_id)
|
data/lib/mihari/version.rb
CHANGED
@@ -83,12 +83,13 @@ module Mihari
|
|
83
83
|
id = params["id"].to_s
|
84
84
|
|
85
85
|
begin
|
86
|
-
rule = Mihari::
|
86
|
+
rule = Mihari::Services::Rule.from_model(Mihari::Rule.find(id))
|
87
87
|
rescue ActiveRecord::RecordNotFound
|
88
88
|
error!({ message: "ID:#{id} is not found" }, 404)
|
89
89
|
end
|
90
90
|
|
91
|
-
rule.
|
91
|
+
analyzer = rule.to_analyzer
|
92
|
+
analyzer.run
|
92
93
|
|
93
94
|
status 201
|
94
95
|
present({ message: "ID:#{id} is ran successfully" }, with: Entities::Message)
|
@@ -105,7 +106,7 @@ module Mihari
|
|
105
106
|
yaml = params[:yaml]
|
106
107
|
|
107
108
|
begin
|
108
|
-
rule =
|
109
|
+
rule = Services::Rule.from_yaml(yaml)
|
109
110
|
rescue YAMLSyntaxError => e
|
110
111
|
error!({ message: e.message }, 400)
|
111
112
|
end
|
@@ -128,13 +129,13 @@ module Mihari
|
|
128
129
|
end
|
129
130
|
|
130
131
|
begin
|
131
|
-
rule.
|
132
|
+
rule.to_model.save
|
132
133
|
rescue ActiveRecord::RecordNotUnique
|
133
134
|
error!({ message: "ID:#{rule.id} is already registered" }, 400)
|
134
135
|
end
|
135
136
|
|
136
137
|
status 201
|
137
|
-
present rule.
|
138
|
+
present rule.to_model, with: Entities::Rule
|
138
139
|
end
|
139
140
|
|
140
141
|
desc "Update a rule", {
|
@@ -156,7 +157,7 @@ module Mihari
|
|
156
157
|
end
|
157
158
|
|
158
159
|
begin
|
159
|
-
rule =
|
160
|
+
rule = Services::Rule.from_yaml(yaml)
|
160
161
|
rescue YAMLSyntaxError => e
|
161
162
|
error!({ message: e.message }, 400)
|
162
163
|
end
|
@@ -171,13 +172,13 @@ module Mihari
|
|
171
172
|
end
|
172
173
|
|
173
174
|
begin
|
174
|
-
rule.
|
175
|
+
rule.to_model.save
|
175
176
|
rescue ActiveRecord::RecordNotUnique
|
176
177
|
error!({ message: "ID:#{id} is already registered" }, 400)
|
177
178
|
end
|
178
179
|
|
179
180
|
status 201
|
180
|
-
present rule.
|
181
|
+
present rule.to_model, with: Entities::Rule
|
181
182
|
end
|
182
183
|
|
183
184
|
desc "Delete a rule", {
|