mihari 6.0.0 → 6.1.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/.rubocop.yml +4 -0
- data/lib/mihari/actor.rb +1 -1
- data/lib/mihari/analyzers/base.rb +3 -0
- data/lib/mihari/analyzers/hunterhow.rb +1 -1
- data/lib/mihari/config.rb +5 -1
- data/lib/mihari/database.rb +7 -1
- data/lib/mihari/emitters/misp.rb +2 -2
- data/lib/mihari/emitters/slack.rb +5 -5
- data/lib/mihari/emitters/the_hive.rb +2 -2
- data/lib/mihari/enrichers/base.rb +2 -0
- data/lib/mihari/enrichers/ipinfo.rb +1 -0
- data/lib/mihari/enrichers/shodan.rb +1 -0
- data/lib/mihari/enrichers/whois.rb +11 -16
- data/lib/mihari/entities/artifact.rb +1 -0
- data/lib/mihari/mixins/falsepositive.rb +2 -2
- data/lib/mihari/models/artifact.rb +13 -5
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +2 -2
- data/lib/mihari/web/public/assets/{index-07cddfcd.js → index-216d49d1.js} +42 -42
- data/lib/mihari/web/public/assets/{index-56fc2187.css → index-4c8509ee.css} +1 -1
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari/web/public/redoc-static.html +4 -4
- data/lib/mihari.rb +8 -9
- data/mihari.gemspec +1 -1
- data/mkdocs.yml +1 -0
- data/requirements.txt +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc2d39ad14f53cf88ed2c68bb2e2668e9a43f36444099401ef9fbe1347948644
|
4
|
+
data.tar.gz: 2d08fed6ec6f82da36f72a2fb05ae1ede82ba65d6bc9bcdb7c60b8f7e244c71a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 684c4106554f9c11bc7ff7f8633b32c5fa24b4127001415e6d14bd4de73e51a04084eb802a29cac109d8b56c71bc7068c8657f4d6ec7cd53e0519ef353aa859f
|
7
|
+
data.tar.gz: 4a4c3183ca85d47b54f7a98837059a9fae585c2d079fe005336520c62290bc317aa61880695f923a2ad0ad7ba5cf18e3e888990a9394d82b4ac41939f34b3403
|
data/.rubocop.yml
CHANGED
data/lib/mihari/actor.rb
CHANGED
@@ -60,7 +60,10 @@ module Mihari
|
|
60
60
|
# No need to set data_type manually
|
61
61
|
# It is set automatically in #initialize
|
62
62
|
artifact = artifact.is_a?(Models::Artifact) ? artifact : Models::Artifact.new(data: artifact)
|
63
|
+
|
63
64
|
artifact.source = self.class.class_key
|
65
|
+
artifact.query = query
|
66
|
+
|
64
67
|
artifact
|
65
68
|
end.select(&:valid?).uniq(&:data)
|
66
69
|
end
|
@@ -22,7 +22,7 @@ module Mihari
|
|
22
22
|
# @param [Hash, nil] options
|
23
23
|
# @param [String, nil] api_key
|
24
24
|
#
|
25
|
-
def initialize(query, start_time
|
25
|
+
def initialize(query, start_time: nil, end_time: nil, options: nil, api_key: nil)
|
26
26
|
super(query, options: options)
|
27
27
|
|
28
28
|
@api_key = api_key || Mihari.config.hunterhow_api_key
|
data/lib/mihari/config.rb
CHANGED
@@ -45,7 +45,8 @@ module Mihari
|
|
45
45
|
retry_exponential_backoff: true,
|
46
46
|
retry_interval: 5,
|
47
47
|
retry_times: 3,
|
48
|
-
sentry_dsn: nil
|
48
|
+
sentry_dsn: nil,
|
49
|
+
sentry_trace_sample_rate: 0.25
|
49
50
|
)
|
50
51
|
|
51
52
|
# @!attribute [r] binaryedge_api_key
|
@@ -132,6 +133,9 @@ module Mihari
|
|
132
133
|
# @!attribute [r] sentry_dsn
|
133
134
|
# @return [String, nil]
|
134
135
|
|
136
|
+
# @!attribute [r] sentry_trace_sample_rate
|
137
|
+
# @return [Float]
|
138
|
+
|
135
139
|
# @!attribute [r] retry_interval
|
136
140
|
# @return [Integer]
|
137
141
|
|
data/lib/mihari/database.rb
CHANGED
@@ -111,6 +111,12 @@ class V5Schema < ActiveRecord::Migration[7.1]
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
class V61Schema < ActiveRecord::Migration[7.1]
|
115
|
+
def change
|
116
|
+
add_column :artifacts, :query, :string
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
114
120
|
def adapter
|
115
121
|
return "postgresql" if %w[postgresql postgres].include?(Mihari.config.database_url.scheme)
|
116
122
|
return "mysql2" if Mihari.config.database_url.scheme == "mysql2"
|
@@ -122,7 +128,7 @@ end
|
|
122
128
|
# @return [Array<ActiveRecord::Migration>] schemas
|
123
129
|
#
|
124
130
|
def schemas
|
125
|
-
[V5Schema]
|
131
|
+
[V5Schema, V61Schema]
|
126
132
|
end
|
127
133
|
|
128
134
|
module Mihari
|
data/lib/mihari/emitters/misp.rb
CHANGED
@@ -6,7 +6,7 @@ require "slack-notifier"
|
|
6
6
|
module Mihari
|
7
7
|
module Emitters
|
8
8
|
class Attachment
|
9
|
-
|
9
|
+
prepend MemoWise
|
10
10
|
|
11
11
|
# @return [String]
|
12
12
|
attr_reader :data
|
@@ -76,7 +76,7 @@ module Mihari
|
|
76
76
|
"https://urlscan.io/domain/#{uri.hostname}"
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
memo_wise :_urlscan_link
|
80
80
|
|
81
81
|
# @return [String, nil]
|
82
82
|
def _vt_link
|
@@ -93,19 +93,19 @@ module Mihari
|
|
93
93
|
"https://www.virustotal.com/#/search/#{data}"
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
96
|
+
memo_wise :_vt_link
|
97
97
|
|
98
98
|
# @return [String, nil]
|
99
99
|
def _censys_link
|
100
100
|
(data_type == "ip") ? "https://search.censys.io/hosts/#{data}" : nil
|
101
101
|
end
|
102
|
-
|
102
|
+
memo_wise :_censys_link
|
103
103
|
|
104
104
|
# @return [String, nil]
|
105
105
|
def _shodan_link
|
106
106
|
(data_type == "ip") ? "https://www.shodan.io/host/#{data}" : nil
|
107
107
|
end
|
108
|
-
|
108
|
+
memo_wise :_shodan_link
|
109
109
|
|
110
110
|
# @return [String]
|
111
111
|
def sha256
|
@@ -66,12 +66,12 @@ module Mihari
|
|
66
66
|
end.first
|
67
67
|
end
|
68
68
|
|
69
|
-
private
|
70
|
-
|
71
69
|
def configuration_keys
|
72
70
|
%w[thehive_url thehive_api_key]
|
73
71
|
end
|
74
72
|
|
73
|
+
private
|
74
|
+
|
75
75
|
def client
|
76
76
|
@client ||= Clients::TheHive.new(url, api_key: api_key, api_version: normalized_api_version, timeout: timeout)
|
77
77
|
end
|
@@ -8,16 +8,11 @@ module Mihari
|
|
8
8
|
# Whois enricher
|
9
9
|
#
|
10
10
|
class Whois < Base
|
11
|
-
# @return [Hash]
|
12
|
-
attr_accessor :memo
|
13
|
-
|
14
11
|
#
|
15
12
|
# @param [Hash, nil] options
|
16
13
|
#
|
17
14
|
def initialize(options: nil)
|
18
15
|
super(options: options)
|
19
|
-
|
20
|
-
@memo = {}
|
21
16
|
end
|
22
17
|
|
23
18
|
#
|
@@ -28,16 +23,22 @@ module Mihari
|
|
28
23
|
# @return [Mihari::Models::WhoisRecord, nil]
|
29
24
|
#
|
30
25
|
def call(domain)
|
31
|
-
|
26
|
+
_call PublicSuffix.domain(domain)
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
return memo[domain].dup if memo.key?(domain)
|
29
|
+
private
|
35
30
|
|
31
|
+
#
|
32
|
+
# @param [String] domain
|
33
|
+
#
|
34
|
+
# @return [Mihari::Models::WhoisRecord, nil]
|
35
|
+
#
|
36
|
+
def _call(domain)
|
36
37
|
record = whois.lookup(domain)
|
37
38
|
parser = record.parser
|
38
39
|
return nil if parser.available?
|
39
40
|
|
40
|
-
|
41
|
+
Models::WhoisRecord.new(
|
41
42
|
domain: domain,
|
42
43
|
created_on: get_created_on(parser),
|
43
44
|
updated_on: get_updated_on(parser),
|
@@ -45,14 +46,8 @@ module Mihari
|
|
45
46
|
registrar: get_registrar(parser),
|
46
47
|
contacts: get_contacts(parser)
|
47
48
|
)
|
48
|
-
|
49
|
-
# set memo
|
50
|
-
memo[domain] = whois_record
|
51
|
-
|
52
|
-
whois_record
|
53
49
|
end
|
54
|
-
|
55
|
-
private
|
50
|
+
memo_wise :_call
|
56
51
|
|
57
52
|
#
|
58
53
|
# @return [::Whois::Client]
|
@@ -11,6 +11,7 @@ module Mihari
|
|
11
11
|
expose :data, documentation: { type: String, required: true }
|
12
12
|
expose :data_type, documentation: { type: String, required: true }, as: :dataType
|
13
13
|
expose :source, documentation: { type: String, required: true }
|
14
|
+
expose :query, documentation: { type: String, required: false }
|
14
15
|
expose :tags, documentation: { type: String, is_array: true }
|
15
16
|
end
|
16
17
|
|
@@ -6,7 +6,7 @@ module Mihari
|
|
6
6
|
# False positive mixins
|
7
7
|
#
|
8
8
|
module FalsePositive
|
9
|
-
|
9
|
+
prepend MemoWise
|
10
10
|
|
11
11
|
#
|
12
12
|
# Normalize a falsepositive value
|
@@ -22,7 +22,7 @@ module Mihari
|
|
22
22
|
value_without_slashes = value[1..-2]
|
23
23
|
Regexp.compile value_without_slashes.to_s
|
24
24
|
end
|
25
|
-
|
25
|
+
memo_wise :normalize_falsepositive
|
26
26
|
|
27
27
|
#
|
28
28
|
# Check whether a value is valid format as a disallowed data value
|
@@ -158,13 +158,13 @@ module Mihari
|
|
158
158
|
# Enrich all the enrichable relationships of the artifact
|
159
159
|
#
|
160
160
|
def enrich_all
|
161
|
-
enrich_autonomous_system
|
161
|
+
enrich_autonomous_system ipinfo
|
162
162
|
enrich_dns
|
163
|
-
enrich_geolocation
|
164
|
-
enrich_reverse_dns
|
163
|
+
enrich_geolocation ipinfo
|
164
|
+
enrich_reverse_dns shodan
|
165
165
|
enrich_whois
|
166
|
-
enrich_ports
|
167
|
-
enrich_cpes
|
166
|
+
enrich_ports shodan
|
167
|
+
enrich_cpes shodan
|
168
168
|
end
|
169
169
|
|
170
170
|
ENRICH_METHODS_BY_ENRICHER = {
|
@@ -197,6 +197,14 @@ module Mihari
|
|
197
197
|
|
198
198
|
private
|
199
199
|
|
200
|
+
def ipinfo
|
201
|
+
@ipinfo ||= Enrichers::IPInfo.new
|
202
|
+
end
|
203
|
+
|
204
|
+
def shodan
|
205
|
+
@shodan ||= Enrichers::Shodan.new
|
206
|
+
end
|
207
|
+
|
200
208
|
def normalize_as_domain(url_or_domain)
|
201
209
|
return url_or_domain if data_type == "domain"
|
202
210
|
|
data/lib/mihari/version.rb
CHANGED
data/lib/mihari/web/app.rb
CHANGED
@@ -53,17 +53,17 @@ module Mihari
|
|
53
53
|
|
54
54
|
class << self
|
55
55
|
def instance
|
56
|
-
|
56
|
+
Rack::Builder.new do
|
57
57
|
use Rack::Cors do
|
58
58
|
allow do
|
59
59
|
origins "*"
|
60
60
|
resource "*", headers: :any, methods: %i[get post put delete options]
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
64
63
|
use Middleware::ConnectionAdapter
|
65
64
|
use Middleware::ErrorNotificationAdapter
|
66
65
|
|
66
|
+
use Sentry::Rack::CaptureExceptions if Sentry.initialized?
|
67
67
|
use BetterErrors::Middleware if ENV["RACK_ENV"] == "development" && defined?(BetterErrors::Middleware)
|
68
68
|
|
69
69
|
run App.new
|