mihari 7.3.1 → 7.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.rubocop.yml +0 -2
- data/.shadowenv.d/.gitignore +2 -0
- data/.shadowenv.d/000_unset_all.lisp +39 -0
- data/README.md +2 -8
- data/lib/mihari/analyzers/base.rb +2 -2
- data/lib/mihari/analyzers/binaryedge.rb +5 -5
- data/lib/mihari/analyzers/censys.rb +6 -6
- data/lib/mihari/analyzers/circl.rb +2 -2
- data/lib/mihari/analyzers/crtsh.rb +3 -3
- data/lib/mihari/analyzers/dnstwister.rb +2 -2
- data/lib/mihari/analyzers/feed.rb +12 -18
- data/lib/mihari/analyzers/fofa.rb +6 -6
- data/lib/mihari/analyzers/greynoise.rb +5 -5
- data/lib/mihari/analyzers/hunterhow.rb +4 -4
- data/lib/mihari/analyzers/onyphe.rb +5 -5
- data/lib/mihari/analyzers/otx.rb +2 -2
- data/lib/mihari/analyzers/passivetotal.rb +3 -3
- data/lib/mihari/analyzers/pulsedive.rb +3 -3
- data/lib/mihari/analyzers/securitytrails.rb +4 -4
- data/lib/mihari/analyzers/shodan.rb +5 -5
- data/lib/mihari/analyzers/urlscan.rb +5 -5
- data/lib/mihari/analyzers/virustotal.rb +4 -4
- data/lib/mihari/analyzers/virustotal_intelligence.rb +5 -5
- data/lib/mihari/analyzers/zoomeye.rb +5 -5
- data/lib/mihari/cli/application.rb +1 -1
- data/lib/mihari/clients/base.rb +5 -5
- data/lib/mihari/clients/binaryedge.rb +6 -6
- data/lib/mihari/clients/censys.rb +4 -4
- data/lib/mihari/clients/circl.rb +2 -2
- data/lib/mihari/clients/crtsh.rb +2 -2
- data/lib/mihari/clients/dnstwister.rb +1 -1
- data/lib/mihari/clients/fofa.rb +4 -4
- data/lib/mihari/clients/google_public_dns.rb +2 -2
- data/lib/mihari/clients/greynoise.rb +4 -4
- data/lib/mihari/clients/hunterhow.rb +10 -10
- data/lib/mihari/clients/misp.rb +1 -1
- data/lib/mihari/clients/mmdb.rb +1 -1
- data/lib/mihari/clients/onyphe.rb +4 -4
- data/lib/mihari/clients/otx.rb +1 -1
- data/lib/mihari/clients/passivetotal.rb +5 -5
- data/lib/mihari/clients/publsedive.rb +3 -3
- data/lib/mihari/clients/securitytrails.rb +6 -6
- data/lib/mihari/clients/shodan.rb +6 -6
- data/lib/mihari/clients/shodan_internet_db.rb +1 -1
- data/lib/mihari/clients/the_hive.rb +2 -2
- data/lib/mihari/clients/urlscan.rb +4 -4
- data/lib/mihari/clients/virustotal.rb +4 -4
- data/lib/mihari/clients/zoomeye.rb +12 -12
- data/lib/mihari/commands/alert.rb +1 -1
- data/lib/mihari/commands/artifact.rb +1 -1
- data/lib/mihari/commands/rule.rb +1 -1
- data/lib/mihari/commands/tag.rb +1 -1
- data/lib/mihari/concerns/autonomous_system_normalizable.rb +1 -4
- data/lib/mihari/concerns/configurable.rb +1 -1
- data/lib/mihari/concerns/database_connectable.rb +2 -2
- data/lib/mihari/concerns/retriable.rb +1 -1
- data/lib/mihari/config.rb +6 -2
- data/lib/mihari/constants.rb +2 -2
- data/lib/mihari/emitters/base.rb +2 -2
- data/lib/mihari/emitters/database.rb +1 -1
- data/lib/mihari/emitters/misp.rb +12 -4
- data/lib/mihari/emitters/slack.rb +9 -9
- data/lib/mihari/emitters/the_hive.rb +9 -4
- data/lib/mihari/emitters/webhook.rb +4 -4
- data/lib/mihari/enrichers/base.rb +1 -1
- data/lib/mihari/enrichers/google_public_dns.rb +1 -1
- data/lib/mihari/enrichers/mmdb.rb +1 -1
- data/lib/mihari/enrichers/shodan.rb +10 -12
- data/lib/mihari/enrichers/whois.rb +2 -2
- data/lib/mihari/entities/alert.rb +6 -6
- data/lib/mihari/entities/artifact.rb +17 -17
- data/lib/mihari/entities/autonomous_system.rb +1 -1
- data/lib/mihari/entities/config.rb +8 -4
- data/lib/mihari/entities/cpe.rb +2 -2
- data/lib/mihari/entities/dns.rb +3 -3
- data/lib/mihari/entities/geolocation.rb +3 -3
- data/lib/mihari/entities/ip_address.rb +3 -3
- data/lib/mihari/entities/messages.rb +3 -3
- data/lib/mihari/entities/pagination.rb +3 -3
- data/lib/mihari/entities/port.rb +2 -2
- data/lib/mihari/entities/reverse_dns.rb +2 -2
- data/lib/mihari/entities/rule.rb +8 -8
- data/lib/mihari/entities/tag.rb +3 -3
- data/lib/mihari/entities/vulnerability.rb +2 -2
- data/lib/mihari/entities/whois.rb +7 -7
- data/lib/mihari/errors.rb +1 -1
- data/lib/mihari/models/artifact.rb +2 -2
- data/lib/mihari/models/port.rb +1 -1
- data/lib/mihari/models/tag.rb +3 -0
- data/lib/mihari/rule.rb +10 -14
- data/lib/mihari/schemas/emitter.rb +2 -0
- data/lib/mihari/services/feed.rb +3 -3
- data/lib/mihari/services/getters.rb +1 -1
- data/lib/mihari/services/proxies.rb +1 -1
- data/lib/mihari/services/renderer.rb +2 -0
- data/lib/mihari/services/searchers.rb +1 -1
- data/lib/mihari/sidekiq/application.rb +2 -2
- data/lib/mihari/structs/censys.rb +4 -4
- data/lib/mihari/structs/google_public_dns.rb +3 -3
- data/lib/mihari/structs/greynoise.rb +2 -2
- data/lib/mihari/structs/onyphe.rb +3 -3
- data/lib/mihari/structs/shodan.rb +10 -10
- data/lib/mihari/structs/urlscan.rb +1 -1
- data/lib/mihari/structs/virustotal_intelligence.rb +2 -2
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/api.rb +1 -1
- data/lib/mihari/web/application.rb +1 -1
- data/lib/mihari/web/endpoints/alerts.rb +12 -12
- data/lib/mihari/web/endpoints/artifacts.rb +11 -11
- data/lib/mihari/web/endpoints/configs.rb +7 -2
- data/lib/mihari/web/endpoints/ip_addresses.rb +5 -5
- data/lib/mihari/web/endpoints/rules.rb +26 -26
- data/lib/mihari/web/endpoints/tags.rb +4 -4
- data/lib/mihari/web/public/assets/index-DsMIBgVm.js +1787 -0
- data/lib/mihari/web/public/assets/{index-ReF8ffd-.css → index-qLffdzXi.css} +1 -1
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari/web/public/redoc-static.html +2 -2
- data/lib/mihari.rb +1 -1
- data/mihari.gemspec +16 -16
- data/renovate.json +1 -3
- data/requirements.txt +1 -1
- metadata +37 -36
- data/.standard.yml +0 -4
- data/lib/mihari/web/public/assets/index-JHS0L8KZ.js +0 -1786
- /data/lib/mihari/web/public/assets/{mode-yaml-BC4MIiYj.js → mode-yaml-ELgwiJiP.js} +0 -0
data/lib/mihari/entities/port.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class Port < Grape::Entity
|
6
|
-
expose :number, documentation: {
|
7
|
-
expose :created_at, documentation: {
|
6
|
+
expose :number, documentation: {type: Integer, required: true}
|
7
|
+
expose :created_at, documentation: {type: DateTime, required: true}, as: :createdAt
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class ReverseDnsName < Grape::Entity
|
6
|
-
expose :name, documentation: {
|
7
|
-
expose :created_at, documentation: {
|
6
|
+
expose :name, documentation: {type: String, required: true}
|
7
|
+
expose :created_at, documentation: {type: DateTime, required: true}, as: :createdAt
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
data/lib/mihari/entities/rule.rb
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class Rule < Grape::Entity
|
6
|
-
expose :id, documentation: {
|
7
|
-
expose :title, documentation: {
|
8
|
-
expose :description, documentation: {
|
9
|
-
expose :yaml, documentation: {
|
10
|
-
expose :created_at, documentation: {
|
11
|
-
expose :updated_at, documentation: {
|
12
|
-
expose :tags, using: Entities::Tag, documentation: {
|
6
|
+
expose :id, documentation: {type: String, required: true}
|
7
|
+
expose :title, documentation: {type: String, required: true}
|
8
|
+
expose :description, documentation: {type: String, required: true}
|
9
|
+
expose :yaml, documentation: {type: String, required: true}
|
10
|
+
expose :created_at, documentation: {type: DateTime, required: true}, as: :createdAt
|
11
|
+
expose :updated_at, documentation: {type: DateTime, required: true}, as: :updatedAt
|
12
|
+
expose :tags, using: Entities::Tag, documentation: {type: Entities::Tag, is_array: true, required: true}
|
13
13
|
end
|
14
14
|
|
15
15
|
class RulesWithPagination < Pagination
|
16
|
-
expose :results, using: Entities::Rule, documentation: {
|
16
|
+
expose :results, using: Entities::Rule, documentation: {type: Entities::Rule, is_array: true, required: true}
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
data/lib/mihari/entities/tag.rb
CHANGED
@@ -3,12 +3,12 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class Tag < Grape::Entity
|
6
|
-
expose :id, documentation: {
|
7
|
-
expose :name, documentation: {
|
6
|
+
expose :id, documentation: {type: Integer, required: true}
|
7
|
+
expose :name, documentation: {type: String, required: true}
|
8
8
|
end
|
9
9
|
|
10
10
|
class TagsWithPagination < Pagination
|
11
|
-
expose :results, using: Entities::Tag, documentation: {
|
11
|
+
expose :results, using: Entities::Tag, documentation: {type: Entities::Tag, is_array: true, required: true}
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class Vulnerability < Grape::Entity
|
6
|
-
expose :name, documentation: {
|
7
|
-
expose :created_at, documentation: {
|
6
|
+
expose :name, documentation: {type: String, required: true}
|
7
|
+
expose :created_at, documentation: {type: DateTime, required: true}, as: :createdAt
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module Mihari
|
4
4
|
module Entities
|
5
5
|
class WhoisRecord < Grape::Entity
|
6
|
-
expose :domain, documentation: {
|
7
|
-
expose :created_on, documentation: {
|
8
|
-
expose :updated_on, documentation: {
|
9
|
-
expose :expires_on, documentation: {
|
10
|
-
expose :registrar, documentation: {
|
11
|
-
expose :contacts, documentation: {
|
6
|
+
expose :domain, documentation: {type: String, required: true}
|
7
|
+
expose :created_on, documentation: {type: Date, required: false}, as: :createdOn
|
8
|
+
expose :updated_on, documentation: {type: Date, required: false}, as: :updatedOn
|
9
|
+
expose :expires_on, documentation: {type: Date, required: false}, as: :expiresOn
|
10
|
+
expose :registrar, documentation: {type: Hash, required: false}
|
11
|
+
expose :contacts, documentation: {type: Hash, is_array: true, required: true} do |whois_record, _options|
|
12
12
|
whois_record.contacts.map(&:to_camelback_keys)
|
13
13
|
end
|
14
|
-
expose :created_at, documentation: {
|
14
|
+
expose :created_at, documentation: {type: DateTime, required: true}, as: :createdAt
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/mihari/errors.rb
CHANGED
@@ -159,8 +159,8 @@ module Mihari
|
|
159
159
|
#
|
160
160
|
def unique?(base_time: nil, artifact_ttl: nil)
|
161
161
|
artifact = self.class.joins(:alert).where(
|
162
|
-
data
|
163
|
-
alert: {
|
162
|
+
data:,
|
163
|
+
alert: {rule_id:}
|
164
164
|
).order(created_at: :desc).first
|
165
165
|
return true if artifact.nil?
|
166
166
|
|
data/lib/mihari/models/port.rb
CHANGED
data/lib/mihari/models/tag.rb
CHANGED
data/lib/mihari/rule.rb
CHANGED
@@ -103,7 +103,7 @@ module Mihari
|
|
103
103
|
#
|
104
104
|
def tags
|
105
105
|
data[:tags].uniq.filter_map do |name|
|
106
|
-
Models::Tag.find_or_create_by(name:
|
106
|
+
Models::Tag.find_or_create_by(name:)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -163,7 +163,7 @@ module Mihari
|
|
163
163
|
# @return [Array<Mihari::Models::Artifact>]
|
164
164
|
#
|
165
165
|
def unique_artifacts
|
166
|
-
normalized_artifacts.select { |artifact| artifact.unique?(base_time
|
166
|
+
normalized_artifacts.select { |artifact| artifact.unique?(base_time:, artifact_ttl:) }
|
167
167
|
end
|
168
168
|
|
169
169
|
#
|
@@ -221,11 +221,11 @@ module Mihari
|
|
221
221
|
end
|
222
222
|
rescue ActiveRecord::RecordNotFound
|
223
223
|
Mihari::Models::Rule.new(
|
224
|
-
id
|
225
|
-
title
|
226
|
-
description
|
227
|
-
data
|
228
|
-
taggings:
|
224
|
+
id:,
|
225
|
+
title:,
|
226
|
+
description:,
|
227
|
+
data:,
|
228
|
+
taggings:
|
229
229
|
)
|
230
230
|
end
|
231
231
|
|
@@ -319,9 +319,7 @@ module Mihari
|
|
319
319
|
@analyzers ||= queries.deep_dup.map do |params|
|
320
320
|
name = params.delete(:analyzer)
|
321
321
|
klass = get_analyzer_class(name)
|
322
|
-
klass.from_params(params).tap
|
323
|
-
analyzer.validate_configuration!
|
324
|
-
end
|
322
|
+
klass.from_params(params).tap(&:validate_configuration!)
|
325
323
|
end
|
326
324
|
end
|
327
325
|
|
@@ -363,9 +361,7 @@ module Mihari
|
|
363
361
|
options = params.delete(:options)
|
364
362
|
|
365
363
|
klass = get_emitter_class(name)
|
366
|
-
klass.new(rule: self, options
|
367
|
-
emitter.validate_configuration!
|
368
|
-
end
|
364
|
+
klass.new(rule: self, options:, **params).tap(&:validate_configuration!)
|
369
365
|
end
|
370
366
|
end
|
371
367
|
|
@@ -399,7 +395,7 @@ module Mihari
|
|
399
395
|
options = params.delete(:options)
|
400
396
|
|
401
397
|
klass = get_enricher_class(name)
|
402
|
-
klass.new(options
|
398
|
+
klass.new(options:, **params)
|
403
399
|
end
|
404
400
|
end
|
405
401
|
|
@@ -17,6 +17,7 @@ module Mihari
|
|
17
17
|
required(:emitter).value(Types::String.enum(*Mihari::Emitters::MISP.keys))
|
18
18
|
optional(:url).filled(:string)
|
19
19
|
optional(:api_key).filled(:string)
|
20
|
+
optional(:attribute_tags).array { filled(:string) }.default([])
|
20
21
|
optional(:options).hash(EmitterOptions)
|
21
22
|
end
|
22
23
|
|
@@ -24,6 +25,7 @@ module Mihari
|
|
24
25
|
required(:emitter).value(Types::String.enum(*Mihari::Emitters::TheHive.keys))
|
25
26
|
optional(:url).filled(:string)
|
26
27
|
optional(:api_key).filled(:string)
|
28
|
+
optional(:observable_tags).array { filled(:string) }.default([])
|
27
29
|
optional(:options).hash(EmitterOptions)
|
28
30
|
end
|
29
31
|
|
data/lib/mihari/services/feed.rb
CHANGED
@@ -28,10 +28,10 @@ module Mihari
|
|
28
28
|
|
29
29
|
return read_file(url.path) if url.scheme == "file"
|
30
30
|
|
31
|
-
http = HTTP::Factory.build(headers
|
31
|
+
http = HTTP::Factory.build(headers:, timeout:)
|
32
32
|
|
33
|
-
res = http.get(url, params:
|
34
|
-
res = http.post(url, params
|
33
|
+
res = http.get(url, params:) if method == "GET"
|
34
|
+
res = http.post(url, params:, json:, form:) if method == "POST"
|
35
35
|
|
36
36
|
body = res.body.to_s
|
37
37
|
content_type = res["Content-Type"].to_s
|
@@ -5,9 +5,9 @@ require "sidekiq"
|
|
5
5
|
require "mihari/sidekiq/jobs"
|
6
6
|
|
7
7
|
Sidekiq.configure_server do |config|
|
8
|
-
config.redis = {
|
8
|
+
config.redis = {url: Mihari.config.sidekiq_redis_url.to_s}
|
9
9
|
end
|
10
10
|
|
11
11
|
Sidekiq.configure_client do |config|
|
12
|
-
config.redis = {
|
12
|
+
config.redis = {url: Mihari.config.sidekiq_redis_url.to_s}
|
13
13
|
end
|
@@ -48,8 +48,8 @@ module Mihari
|
|
48
48
|
return nil if country.nil?
|
49
49
|
|
50
50
|
Mihari::Models::Geolocation.new(
|
51
|
-
country
|
52
|
-
country_code:
|
51
|
+
country:,
|
52
|
+
country_code:
|
53
53
|
)
|
54
54
|
end
|
55
55
|
|
@@ -126,10 +126,10 @@ module Mihari
|
|
126
126
|
def artifact
|
127
127
|
Models::Artifact.new(
|
128
128
|
data: ip,
|
129
|
-
metadata
|
129
|
+
metadata:,
|
130
130
|
autonomous_system: autonomous_system.as,
|
131
131
|
geolocation: location.geolocation,
|
132
|
-
ports:
|
132
|
+
ports:
|
133
133
|
)
|
134
134
|
end
|
135
135
|
|
@@ -4,8 +4,8 @@ module Mihari
|
|
4
4
|
module Structs
|
5
5
|
module GooglePublicDNS
|
6
6
|
INT_TYPE_TO_TYPE =
|
7
|
-
{
|
8
|
-
|
7
|
+
{1 => :A, 38 => :A6, 28 => :AAAA, 18 => :AFSDB, 255 => :ANY, 42 => :APL, 34 => :ATMA, 252 => :AXFR, 37 => :CERT,
|
8
|
+
5 => :CNAME, 49 => :DHCID, 32_769 => :DLV, 39 => :DNAME, 48 => :DNSKEY, 43 => :DS, 31 => :EID, 102 => :GID, 27 => :GPOS, 13 => :HINFO, 45 => :IPSECKEY, 20 => :ISDN, 251 => :IXFR, 25 => :KEY, 36 => :KX, 29 => :LOC, 254 => :MAILA, 253 => :MAILB, 7 => :MB, 3 => :MD, 4 => :MF, 8 => :MG, 14 => :MINFO, 9 => :MR, 15 => :MX, 35 => :NAPTR, 32 => :NIMLOC, 2 => :NS, 22 => :NSAP, 23 => :NSAP_PTR, 47 => :NSEC, 50 => :NSEC3, 51 => :NSEC3PARAMS, 10 => :NULL, 30 => :NXT, 41 => :OPT, 12 => :PTR, 26 => :PX, 17 => :RP, 46 => :RRSIG, 21 => :RT, 24 => :SIG, 40 => :SINK, 6 => :SOA, 33 => :SRV, 44 => :SSHFP, 250 => :TSIG, 16 => :TXT, 101 => :UID, 100 => :UINFO, 103 => :UNSPEC, 11 => :WKS, 19 => :X25}.freeze
|
9
9
|
|
10
10
|
class Answer < Dry::Struct
|
11
11
|
# @!attribute [r] name
|
@@ -30,7 +30,7 @@ module Mihari
|
|
30
30
|
new(
|
31
31
|
name: d.fetch("name"),
|
32
32
|
data: d.fetch("data"),
|
33
|
-
resource_type:
|
33
|
+
resource_type:
|
34
34
|
)
|
35
35
|
end
|
36
36
|
end
|
@@ -29,9 +29,9 @@ module Mihari
|
|
29
29
|
def artifact
|
30
30
|
Mihari::Models::Artifact.new(
|
31
31
|
data: ip,
|
32
|
-
metadata
|
32
|
+
metadata:,
|
33
33
|
autonomous_system: as,
|
34
|
-
geolocation:
|
34
|
+
geolocation:
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
@@ -43,7 +43,7 @@ module Mihari
|
|
43
43
|
|
44
44
|
Mihari::Models::Geolocation.new(
|
45
45
|
country: NormalizeCountry(country_code, to: :short),
|
46
|
-
country_code:
|
46
|
+
country_code:
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
@@ -20,7 +20,7 @@ module Mihari
|
|
20
20
|
|
21
21
|
Mihari::Models::Geolocation.new(
|
22
22
|
country: country_name,
|
23
|
-
country_code:
|
23
|
+
country_code:
|
24
24
|
)
|
25
25
|
end
|
26
26
|
|
@@ -106,7 +106,7 @@ module Mihari
|
|
106
106
|
|
107
107
|
new(
|
108
108
|
asn: d["asn"],
|
109
|
-
hostnames
|
109
|
+
hostnames:,
|
110
110
|
location: Location.from_dynamic!(d.fetch("location")),
|
111
111
|
domains: d.fetch("domains"),
|
112
112
|
ip_str: d.fetch("ip_str"),
|
@@ -205,20 +205,20 @@ module Mihari
|
|
205
205
|
|
206
206
|
ports = collect_ports_by_ip(match.ip_str).map { |port| Models::Port.new(number: port) }
|
207
207
|
reverse_dns_names = collect_hostnames_by_ip(match.ip_str).map do |name|
|
208
|
-
Models::ReverseDnsName.new(name:
|
208
|
+
Models::ReverseDnsName.new(name:)
|
209
209
|
end
|
210
|
-
cpes = collect_cpes_by_ip(match.ip_str).map { |name| Models::CPE.new(name:
|
211
|
-
vulnerabilities = collect_vulns_by_ip(match.ip_str).map { |name| Models::Vulnerability.new(name:
|
210
|
+
cpes = collect_cpes_by_ip(match.ip_str).map { |name| Models::CPE.new(name:) }
|
211
|
+
vulnerabilities = collect_vulns_by_ip(match.ip_str).map { |name| Models::Vulnerability.new(name:) }
|
212
212
|
|
213
213
|
Mihari::Models::Artifact.new(
|
214
214
|
data: match.ip_str,
|
215
|
-
metadata
|
215
|
+
metadata:,
|
216
216
|
autonomous_system: match.autonomous_system,
|
217
217
|
geolocation: match.location.geolocation,
|
218
|
-
ports
|
219
|
-
reverse_dns_names
|
220
|
-
cpes
|
221
|
-
vulnerabilities:
|
218
|
+
ports:,
|
219
|
+
reverse_dns_names:,
|
220
|
+
cpes:,
|
221
|
+
vulnerabilities:
|
222
222
|
)
|
223
223
|
end
|
224
224
|
end
|
@@ -53,7 +53,7 @@ module Mihari
|
|
53
53
|
#
|
54
54
|
def artifacts
|
55
55
|
values = [page.url, page.domain, page.ip].compact
|
56
|
-
values.map { |value| Mihari::Models::Artifact.new(data: value, metadata:
|
56
|
+
values.map { |value| Mihari::Models::Artifact.new(data: value, metadata:) }
|
57
57
|
end
|
58
58
|
|
59
59
|
class << self
|
@@ -56,7 +56,7 @@ module Mihari
|
|
56
56
|
# @return [Mihari::Models::Artifact]
|
57
57
|
#
|
58
58
|
def artifact
|
59
|
-
Models::Artifact.new(data: value, metadata:
|
59
|
+
Models::Artifact.new(data: value, metadata:)
|
60
60
|
end
|
61
61
|
|
62
62
|
class << self
|
@@ -74,7 +74,7 @@ module Mihari
|
|
74
74
|
new(
|
75
75
|
type: d.fetch("type"),
|
76
76
|
id: d.fetch("id"),
|
77
|
-
context_attributes
|
77
|
+
context_attributes:,
|
78
78
|
metadata: d
|
79
79
|
)
|
80
80
|
end
|
data/lib/mihari/version.rb
CHANGED
data/lib/mihari/web/api.rb
CHANGED
@@ -33,7 +33,7 @@ module Mihari
|
|
33
33
|
|
34
34
|
desc "Get an alert", {
|
35
35
|
success: Entities::Alert,
|
36
|
-
failure: [{
|
36
|
+
failure: [{code: 404, model: Entities::ErrorMessage}],
|
37
37
|
summary: "Get an alert"
|
38
38
|
}
|
39
39
|
params do
|
@@ -46,14 +46,14 @@ module Mihari
|
|
46
46
|
|
47
47
|
case result.failure
|
48
48
|
when ActiveRecord::RecordNotFound
|
49
|
-
error!({
|
49
|
+
error!({message: "ID:#{id} not found"}, 404)
|
50
50
|
end
|
51
51
|
raise result.failure
|
52
52
|
end
|
53
53
|
|
54
54
|
desc "Delete an alert", {
|
55
|
-
success: {
|
56
|
-
failure: [{
|
55
|
+
success: {code: 204, model: Entities::Message},
|
56
|
+
failure: [{code: 404, model: Entities::ErrorMessage}],
|
57
57
|
summary: "Delete an alert"
|
58
58
|
}
|
59
59
|
params do
|
@@ -64,26 +64,26 @@ module Mihari
|
|
64
64
|
|
65
65
|
id = params["id"].to_i
|
66
66
|
result = Services::AlertDestroyer.result(id)
|
67
|
-
return present({
|
67
|
+
return present({message: ""}, with: Entities::Message) if result.success?
|
68
68
|
|
69
69
|
case result.failure
|
70
70
|
when ActiveRecord::RecordNotFound
|
71
|
-
error!({
|
71
|
+
error!({message: "ID:#{id} not found"}, 404)
|
72
72
|
end
|
73
73
|
raise result.failure
|
74
74
|
end
|
75
75
|
|
76
76
|
desc "Create an alert", {
|
77
|
-
success: {
|
77
|
+
success: {code: 201, model: Entities::Alert},
|
78
78
|
failure: [
|
79
|
-
{
|
79
|
+
{code: 404, model: Entities::ErrorMessage}
|
80
80
|
],
|
81
81
|
summary: "Create an alert"
|
82
82
|
}
|
83
83
|
params do
|
84
|
-
requires :ruleId, type: String, documentation: {
|
85
|
-
requires :artifacts, type: Array, documentation: {
|
86
|
-
optional :source, type: String, documentation: {
|
84
|
+
requires :ruleId, type: String, documentation: {param_type: "body"}
|
85
|
+
requires :artifacts, type: Array, documentation: {type: String, is_array: true, param_type: "body"}
|
86
|
+
optional :source, type: String, documentation: {param_type: "body"}
|
87
87
|
end
|
88
88
|
post "/" do
|
89
89
|
status 201
|
@@ -93,7 +93,7 @@ module Mihari
|
|
93
93
|
|
94
94
|
case result.failure
|
95
95
|
when ActiveRecord::RecordNotFound
|
96
|
-
error!({
|
96
|
+
error!({message: "Rule:#{params["ruleId"]} not found"}, 404)
|
97
97
|
end
|
98
98
|
raise result.failure
|
99
99
|
end
|
@@ -33,7 +33,7 @@ module Mihari
|
|
33
33
|
|
34
34
|
desc "Get an artifact", {
|
35
35
|
success: Entities::Artifact,
|
36
|
-
failure: [{
|
36
|
+
failure: [{code: 404, model: Entities::ErrorMessage}],
|
37
37
|
summary: "Get an artifact"
|
38
38
|
}
|
39
39
|
params do
|
@@ -46,14 +46,14 @@ module Mihari
|
|
46
46
|
|
47
47
|
case result.failure
|
48
48
|
when ActiveRecord::RecordNotFound
|
49
|
-
error!({
|
49
|
+
error!({message: "ID:#{id} not found"}, 404)
|
50
50
|
end
|
51
51
|
raise result.failure
|
52
52
|
end
|
53
53
|
|
54
54
|
desc "Enrich an artifact", {
|
55
|
-
success: {
|
56
|
-
failure: [{
|
55
|
+
success: {code: 201, model: Entities::Message},
|
56
|
+
failure: [{code: 400, model: Entities::ErrorMessage}, {code: 404, model: Entities::ErrorMessage}],
|
57
57
|
summary: "Enrich an artifact"
|
58
58
|
}
|
59
59
|
params do
|
@@ -75,20 +75,20 @@ module Mihari
|
|
75
75
|
end.to_result
|
76
76
|
|
77
77
|
message = queued ? "ID:#{id}'s enrichment is queued" : "ID:#{id}'s enrichment is successful"
|
78
|
-
return present({
|
78
|
+
return present({message:, queued:}, with: Entities::QueueMessage) if result.success?
|
79
79
|
|
80
80
|
case result.failure
|
81
81
|
when UnenrichableError
|
82
|
-
error!({
|
82
|
+
error!({message: result.failure.message}, 400)
|
83
83
|
when ActiveRecord::RecordNotFound
|
84
|
-
error!({
|
84
|
+
error!({message: "ID:#{id} not found"}, 404)
|
85
85
|
end
|
86
86
|
raise result.failure
|
87
87
|
end
|
88
88
|
|
89
89
|
desc "Delete an artifact", {
|
90
|
-
success: {
|
91
|
-
failure: [{
|
90
|
+
success: {code: 204, model: Entities::Message},
|
91
|
+
failure: [{code: 404, model: Entities::ErrorMessage}],
|
92
92
|
summary: "Delete an artifact"
|
93
93
|
}
|
94
94
|
params do
|
@@ -99,11 +99,11 @@ module Mihari
|
|
99
99
|
|
100
100
|
id = params["id"].to_i
|
101
101
|
result = Services::ArtifactDestroyer.result(id)
|
102
|
-
return present({
|
102
|
+
return present({message: ""}, with: Entities::Message) if result.success?
|
103
103
|
|
104
104
|
case result.failure
|
105
105
|
when ActiveRecord::RecordNotFound
|
106
|
-
error!({
|
106
|
+
error!({message: "ID:#{id} not found"}, 404)
|
107
107
|
end
|
108
108
|
raise result.failure
|
109
109
|
end
|
@@ -10,12 +10,17 @@ module Mihari
|
|
10
10
|
namespace :configs do
|
11
11
|
desc "list configs", {
|
12
12
|
is_array: true,
|
13
|
-
success: Entities::
|
13
|
+
success: Entities::Configs,
|
14
14
|
summary: "List configs"
|
15
15
|
}
|
16
16
|
get "/" do
|
17
17
|
configs = Services::ConfigSearcher.call
|
18
|
-
present(
|
18
|
+
present(
|
19
|
+
{
|
20
|
+
results: configs
|
21
|
+
},
|
22
|
+
with: Entities::Configs
|
23
|
+
)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|