mihari 7.1.1 → 7.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mihari/actor.rb +5 -5
- data/lib/mihari/analyzers/base.rb +12 -3
- data/lib/mihari/analyzers/passivetotal.rb +1 -1
- data/lib/mihari/analyzers/securitytrails.rb +1 -1
- data/lib/mihari/analyzers/virustotal.rb +1 -1
- data/lib/mihari/analyzers/virustotal_intelligence.rb +2 -2
- data/lib/mihari/constants.rb +1 -1
- data/lib/mihari/emitters/base.rb +11 -1
- data/lib/mihari/emitters/database.rb +4 -0
- data/lib/mihari/emitters/misp.rb +7 -0
- data/lib/mihari/emitters/slack.rb +7 -0
- data/lib/mihari/emitters/the_hive.rb +7 -0
- data/lib/mihari/emitters/webhook.rb +7 -0
- data/lib/mihari/enrichers/base.rb +3 -1
- data/lib/mihari/enrichers/google_public_dns.rb +1 -1
- data/lib/mihari/schemas/analyzer.rb +19 -19
- data/lib/mihari/schemas/emitter.rb +5 -5
- data/lib/mihari/schemas/enricher.rb +4 -4
- data/lib/mihari/structs/config.rb +1 -1
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/public/assets/{index-U5u7qHZZ.js → index-Guw2aMpk.js} +53 -53
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari.rb +3 -3
- data/mihari.gemspec +4 -4
- metadata +57 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52d1c8320fdb5233c9738f3b4599868260fef892599cdfb42da6c3af17583b75
|
4
|
+
data.tar.gz: 625cd92558eff5a4d5613e588cc5ee85b9b714a9af211788da1a294d8d54ac45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96811d3ebfffcb27a7577b814be280916dd46bd3477233374ffafd2bf784d9e5133f89b1d7650c722c25e2f678f82380f5ced2eff8f9b7e1f3c96583f54a1114
|
7
|
+
data.tar.gz: 5c13581e670c7aff158e93335fe9c626294cad622f153e61a338f31bb5a1e459302f34a3a9ddf18e0bb322e1359c43a6b782387cdc800f9b047c04e5521f4c70
|
data/lib/mihari/actor.rb
CHANGED
@@ -55,7 +55,7 @@ module Mihari
|
|
55
55
|
|
56
56
|
joined = self.class.configuration_keys.join(", ")
|
57
57
|
be = (self.class.configuration_keys.length > 1) ? "are" : "is"
|
58
|
-
message = "#{self.class.
|
58
|
+
message = "#{self.class.key} is not configured correctly. #{joined} #{be} missing."
|
59
59
|
raise ConfigurationError, message
|
60
60
|
end
|
61
61
|
|
@@ -75,22 +75,22 @@ module Mihari
|
|
75
75
|
#
|
76
76
|
# @return [String]
|
77
77
|
#
|
78
|
-
def
|
78
|
+
def key
|
79
79
|
to_s.split("::").last.downcase
|
80
80
|
end
|
81
81
|
|
82
82
|
#
|
83
83
|
# @return [Array<String>, nil]
|
84
84
|
#
|
85
|
-
def
|
85
|
+
def key_aliases
|
86
86
|
nil
|
87
87
|
end
|
88
88
|
|
89
89
|
#
|
90
90
|
# @return [Array<String>]
|
91
91
|
#
|
92
|
-
def
|
93
|
-
([
|
92
|
+
def keys
|
93
|
+
([key] + [key_aliases]).flatten.compact.map(&:downcase)
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -65,7 +65,7 @@ module Mihari
|
|
65
65
|
# It is set automatically in #initialize
|
66
66
|
artifact = artifact.is_a?(Models::Artifact) ? artifact : Models::Artifact.new(data: artifact)
|
67
67
|
|
68
|
-
artifact.source = self.class.
|
68
|
+
artifact.source = self.class.key
|
69
69
|
artifact.query = query
|
70
70
|
|
71
71
|
artifact
|
@@ -93,14 +93,23 @@ module Mihari
|
|
93
93
|
return result if result.success?
|
94
94
|
|
95
95
|
# Wrap failure with AnalyzerError to explicitly name a failed analyzer
|
96
|
-
error = AnalyzerError.new(result.failure.message, self.class.
|
96
|
+
error = AnalyzerError.new(result.failure.message, self.class.key, cause: result.failure)
|
97
97
|
return Failure(error) unless ignore_error?
|
98
98
|
|
99
99
|
# Return Success if ignore_error? is true with logging
|
100
|
-
Mihari.logger.warn("Analyzer:#{self.class.
|
100
|
+
Mihari.logger.warn("Analyzer:#{self.class.key} with #{truncated_query} failed - #{result.failure}")
|
101
101
|
Success([])
|
102
102
|
end
|
103
103
|
|
104
|
+
#
|
105
|
+
# Truncate query for logging
|
106
|
+
#
|
107
|
+
# @return [String]
|
108
|
+
#
|
109
|
+
def truncated_query
|
110
|
+
query.truncate(32)
|
111
|
+
end
|
112
|
+
|
104
113
|
class << self
|
105
114
|
#
|
106
115
|
# Initialize an analyzer by query params
|
data/lib/mihari/constants.rb
CHANGED
@@ -5,7 +5,7 @@ module Mihari
|
|
5
5
|
DEFAULT_DATA_TYPES = Types::DataTypes.values.freeze
|
6
6
|
|
7
7
|
# @return [Array<Hash>]
|
8
|
-
DEFAULT_EMITTERS = Emitters::Database.
|
8
|
+
DEFAULT_EMITTERS = Emitters::Database.keys.map { |name| { emitter: name.downcase } }.freeze
|
9
9
|
|
10
10
|
# @return [Array<Hash>]
|
11
11
|
DEFAULT_ENRICHERS = Mihari.enricher_to_class.keys.map { |name| { enricher: name.downcase } }.freeze
|
data/lib/mihari/emitters/base.rb
CHANGED
@@ -19,6 +19,14 @@ module Mihari
|
|
19
19
|
@rule = rule
|
20
20
|
end
|
21
21
|
|
22
|
+
# A target to emit the data
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
#
|
26
|
+
def target
|
27
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
28
|
+
end
|
29
|
+
|
22
30
|
#
|
23
31
|
# @param [Array<Mihari::Models::Artifact>] artifacts
|
24
32
|
#
|
@@ -38,7 +46,9 @@ module Mihari
|
|
38
46
|
) { call(artifacts) }
|
39
47
|
end.to_result
|
40
48
|
|
41
|
-
|
49
|
+
if result.failure?
|
50
|
+
Mihari.logger.warn("Emitter:#{self.class.key} for #{target.truncate(32)} failed - #{result.failure}")
|
51
|
+
end
|
42
52
|
|
43
53
|
result
|
44
54
|
end
|
data/lib/mihari/emitters/misp.rb
CHANGED
@@ -33,7 +33,9 @@ module Mihari
|
|
33
33
|
) { call value }
|
34
34
|
end.to_result
|
35
35
|
|
36
|
-
|
36
|
+
if result.failure?
|
37
|
+
Mihari.logger.warn("Enricher:#{self.class.key} for #{value.truncate(32)} failed: #{result.failure}")
|
38
|
+
end
|
37
39
|
|
38
40
|
result
|
39
41
|
end
|
@@ -10,12 +10,12 @@ module Mihari
|
|
10
10
|
|
11
11
|
# Analyzer with API key and pagination
|
12
12
|
[
|
13
|
-
Mihari::Analyzers::BinaryEdge.
|
14
|
-
Mihari::Analyzers::GreyNoise.
|
15
|
-
Mihari::Analyzers::Onyphe.
|
16
|
-
Mihari::Analyzers::Shodan.
|
17
|
-
Mihari::Analyzers::Urlscan.
|
18
|
-
Mihari::Analyzers::VirusTotalIntelligence.
|
13
|
+
Mihari::Analyzers::BinaryEdge.keys,
|
14
|
+
Mihari::Analyzers::GreyNoise.keys,
|
15
|
+
Mihari::Analyzers::Onyphe.keys,
|
16
|
+
Mihari::Analyzers::Shodan.keys,
|
17
|
+
Mihari::Analyzers::Urlscan.keys,
|
18
|
+
Mihari::Analyzers::VirusTotalIntelligence.keys
|
19
19
|
].each do |keys|
|
20
20
|
key = keys.first
|
21
21
|
const_set(key.upcase, Dry::Schema.Params do
|
@@ -28,10 +28,10 @@ module Mihari
|
|
28
28
|
|
29
29
|
# Analyzer with API key
|
30
30
|
[
|
31
|
-
Mihari::Analyzers::OTX.
|
32
|
-
Mihari::Analyzers::Pulsedive.
|
33
|
-
Mihari::Analyzers::VirusTotal.
|
34
|
-
Mihari::Analyzers::SecurityTrails.
|
31
|
+
Mihari::Analyzers::OTX.keys,
|
32
|
+
Mihari::Analyzers::Pulsedive.keys,
|
33
|
+
Mihari::Analyzers::VirusTotal.keys,
|
34
|
+
Mihari::Analyzers::SecurityTrails.keys
|
35
35
|
].each do |keys|
|
36
36
|
key = keys.first
|
37
37
|
const_set(key.upcase, Dry::Schema.Params do
|
@@ -43,13 +43,13 @@ module Mihari
|
|
43
43
|
end
|
44
44
|
|
45
45
|
DNSTwister = Dry::Schema.Params do
|
46
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::DNSTwister.
|
46
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::DNSTwister.keys))
|
47
47
|
required(:query).value(:string)
|
48
48
|
optional(:options).hash(AnalyzerOptions)
|
49
49
|
end
|
50
50
|
|
51
51
|
Censys = Dry::Schema.Params do
|
52
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Censys.
|
52
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Censys.keys))
|
53
53
|
required(:query).value(:string)
|
54
54
|
optional(:id).value(:string)
|
55
55
|
optional(:secret).value(:string)
|
@@ -57,7 +57,7 @@ module Mihari
|
|
57
57
|
end
|
58
58
|
|
59
59
|
CIRCL = Dry::Schema.Params do
|
60
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::CIRCL.
|
60
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::CIRCL.keys))
|
61
61
|
required(:query).value(:string)
|
62
62
|
optional(:username).value(:string)
|
63
63
|
optional(:password).value(:string)
|
@@ -65,7 +65,7 @@ module Mihari
|
|
65
65
|
end
|
66
66
|
|
67
67
|
Fofa = Dry::Schema.Params do
|
68
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Fofa.
|
68
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Fofa.keys))
|
69
69
|
required(:query).value(:string)
|
70
70
|
optional(:api_key).value(:string)
|
71
71
|
optional(:email).value(:string)
|
@@ -73,7 +73,7 @@ module Mihari
|
|
73
73
|
end
|
74
74
|
|
75
75
|
PassiveTotal = Dry::Schema.Params do
|
76
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::PassiveTotal.
|
76
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::PassiveTotal.keys))
|
77
77
|
required(:query).value(:string)
|
78
78
|
optional(:username).value(:string)
|
79
79
|
optional(:api_key).value(:string)
|
@@ -81,14 +81,14 @@ module Mihari
|
|
81
81
|
end
|
82
82
|
|
83
83
|
ZoomEye = Dry::Schema.Params do
|
84
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::ZoomEye.
|
84
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::ZoomEye.keys))
|
85
85
|
required(:query).value(:string)
|
86
86
|
required(:type).value(Types::String.enum("host", "web"))
|
87
87
|
optional(:options).hash(AnalyzerPaginationOptions)
|
88
88
|
end
|
89
89
|
|
90
90
|
Crtsh = Dry::Schema.Params do
|
91
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Crtsh.
|
91
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Crtsh.keys))
|
92
92
|
required(:query).value(:string)
|
93
93
|
optional(:exclude_expired).value(:bool).default(true)
|
94
94
|
optional(:match).value(Types::String.enum("=", "ILIKE", "LIKE", "single", "any", "FTS")).default(nil)
|
@@ -96,7 +96,7 @@ module Mihari
|
|
96
96
|
end
|
97
97
|
|
98
98
|
HunterHow = Dry::Schema.Params do
|
99
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::HunterHow.
|
99
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::HunterHow.keys))
|
100
100
|
required(:query).value(:string)
|
101
101
|
required(:start_time).value(:date)
|
102
102
|
required(:end_time).value(:date)
|
@@ -105,7 +105,7 @@ module Mihari
|
|
105
105
|
end
|
106
106
|
|
107
107
|
Feed = Dry::Schema.Params do
|
108
|
-
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Feed.
|
108
|
+
required(:analyzer).value(Types::String.enum(*Mihari::Analyzers::Feed.keys))
|
109
109
|
required(:query).value(:string)
|
110
110
|
required(:selector).value(:string)
|
111
111
|
optional(:method).value(Types::HTTPRequestMethods).default("GET")
|
@@ -9,33 +9,33 @@ module Mihari
|
|
9
9
|
extend Concerns::Orrable
|
10
10
|
|
11
11
|
Database = Dry::Schema.Params do
|
12
|
-
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Database.
|
12
|
+
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Database.keys))
|
13
13
|
optional(:options).hash(Options)
|
14
14
|
end
|
15
15
|
|
16
16
|
MISP = Dry::Schema.Params do
|
17
|
-
required(:emitter).value(Types::String.enum(*Mihari::Emitters::MISP.
|
17
|
+
required(:emitter).value(Types::String.enum(*Mihari::Emitters::MISP.keys))
|
18
18
|
optional(:url).value(:string)
|
19
19
|
optional(:api_key).value(:string)
|
20
20
|
optional(:options).hash(Options)
|
21
21
|
end
|
22
22
|
|
23
23
|
TheHive = Dry::Schema.Params do
|
24
|
-
required(:emitter).value(Types::String.enum(*Mihari::Emitters::TheHive.
|
24
|
+
required(:emitter).value(Types::String.enum(*Mihari::Emitters::TheHive.keys))
|
25
25
|
optional(:url).value(:string)
|
26
26
|
optional(:api_key).value(:string)
|
27
27
|
optional(:options).hash(Options)
|
28
28
|
end
|
29
29
|
|
30
30
|
Slack = Dry::Schema.Params do
|
31
|
-
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Slack.
|
31
|
+
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Slack.keys))
|
32
32
|
optional(:webhook_url).value(:string)
|
33
33
|
optional(:channel).value(:string)
|
34
34
|
optional(:options).hash(Options)
|
35
35
|
end
|
36
36
|
|
37
37
|
Webhook = Dry::Schema.Params do
|
38
|
-
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Webhook.
|
38
|
+
required(:emitter).value(Types::String.enum(*Mihari::Emitters::Webhook.keys))
|
39
39
|
required(:url).value(:string)
|
40
40
|
optional(:method).value(Types::HTTPRequestMethods).default("POST")
|
41
41
|
optional(:headers).value(:hash).default({})
|
@@ -9,22 +9,22 @@ module Mihari
|
|
9
9
|
extend Concerns::Orrable
|
10
10
|
|
11
11
|
MMDB = Dry::Schema.Params do
|
12
|
-
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::MMDB.
|
12
|
+
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::MMDB.keys))
|
13
13
|
optional(:options).hash(Options)
|
14
14
|
end
|
15
15
|
|
16
16
|
Whois = Dry::Schema.Params do
|
17
|
-
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::Whois.
|
17
|
+
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::Whois.keys))
|
18
18
|
optional(:options).hash(Options)
|
19
19
|
end
|
20
20
|
|
21
21
|
Shodan = Dry::Schema.Params do
|
22
|
-
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::Shodan.
|
22
|
+
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::Shodan.keys))
|
23
23
|
optional(:options).hash(Options)
|
24
24
|
end
|
25
25
|
|
26
26
|
GooglePublicDNS = Dry::Schema.Params do
|
27
|
-
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::GooglePublicDNS.
|
27
|
+
required(:enricher).value(Types::String.enum(*Mihari::Enrichers::GooglePublicDNS.keys))
|
28
28
|
optional(:options).hash(Options)
|
29
29
|
end
|
30
30
|
end
|
data/lib/mihari/version.rb
CHANGED