mihari 7.5.0 → 7.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71b5cf7cdeb320c813848b90973908a3999c839f742b9307ae819c1fbf20829b
4
- data.tar.gz: 18b06e35086d2888016d6d1fd7a61c9e62f72e31f6a384e0c1a96f4fde8ab592
3
+ metadata.gz: 2fd0c07fe2661f57d6db5b409c527789c5e17d23e7691d5ac241ff5b36a20698
4
+ data.tar.gz: d7f2a832b3cb364aca8bdfad71cf762f72dc707892d2697ef8bb272bcb794b1d
5
5
  SHA512:
6
- metadata.gz: 2861d810f7ade8e177fd343e706c55a4ef64f734c3f19ae324a58d29c2992b3a11ccc8ad6d6735dff9831b15ce552305e3981c72b9326d55b83f621154f9d2f9
7
- data.tar.gz: edf9f41d660252298cb5909eec731a6ca39968eab5d73c3d6eca3d55f8b452337ee22898427e9165312881058f6e2ba474d6f548aac922431c1b483b7a9c9746
6
+ metadata.gz: 39c5c92cf79721ed6d98b09a63a3d609eab8e8da9ba5badb1cd1a9f01fcb04d8f11edaa3b50fd7e0aed6dcb44f7befb77166e9bbf8399bac4d6592eafd943763
7
+ data.tar.gz: 7c06bd2ca9616605aa9601d198a413529f92205861dcafbfd86e84fa5bca6e2344d42ef558f27ee4c358f09778679fdaa2018954a6d34bfa534f2a3fa155042d
@@ -35,5 +35,6 @@
35
35
  (env/set "THEHIVE_API_KEY" ())
36
36
  (env/set "THEHIVE_URL" ())
37
37
  (env/set "URLSCAN_API_KEY" ())
38
+ (env/set "VALIDIN_API_KEY" ())
38
39
  (env/set "VIRUSTOTAL_API_KEY" ())
39
40
  (env/set "ZOOMEYE_API_KEY" ())
data/Rakefile CHANGED
@@ -55,17 +55,21 @@ namespace :build do
55
55
 
56
56
  puts "Swagger doc is built in #{elapsed}s"
57
57
  end
58
+
59
+ desc "Build frontend assets"
60
+ task :frontend do
61
+ # Build frontend assets
62
+ sh "cd frontend && npm install && npm run docs && npm run build-only"
63
+ # Copy built assets into ./lib/web/public/
64
+ sh "rm -rf ./lib/mihari/web/public/"
65
+ sh "mkdir -p ./lib/mihari/web/public/"
66
+ sh "cp -r frontend/dist/* ./lib/mihari/web/public"
67
+ end
58
68
  end
59
69
 
60
70
  task :build do
61
71
  Rake::Task["build:swagger"].invoke
62
-
63
- # Build ReDocs docs & frontend assets
64
- sh "cd frontend && npm install && npm run docs && npm run build-only"
65
- # Copy built assets into ./lib/web/public/
66
- sh "rm -rf ./lib/mihari/web/public/"
67
- sh "mkdir -p ./lib/mihari/web/public/"
68
- sh "cp -r frontend/dist/* ./lib/mihari/web/public"
72
+ Rake::Task["build:frontend"].invoke
69
73
  end
70
74
 
71
75
  # require it later enables doing pre-build step (= build the frontend app)
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mihari/clients/validin"
4
+
5
+ module Mihari
6
+ module Analyzers
7
+ #
8
+ # Validin analyzer
9
+ #
10
+ class Validin < Base
11
+ include Concerns::Refangable
12
+
13
+ # @return [String, nil]
14
+ attr_reader :type
15
+
16
+ # @return [String, nil]
17
+ attr_reader :username
18
+
19
+ # @return [String, nil]
20
+ attr_reader :api_key
21
+
22
+ #
23
+ # @param [String] query
24
+ # @param [Hash, nil] options
25
+ # @param [String, nil] api_key
26
+ #
27
+ def initialize(query, options: nil, api_key: nil)
28
+ super(refang(query), options:)
29
+
30
+ @type = DataType.type(query)
31
+
32
+ @api_key = api_key || Mihari.config.validin_api_key
33
+ end
34
+
35
+ def artifacts
36
+ case type
37
+ when "domain"
38
+ dns_history_search
39
+ when "ip"
40
+ reverse_ip_search
41
+ else
42
+ raise ValueError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def dns_history_search
49
+ res = client.dns_history_search(query)
50
+ (res.dig("records", "A") || []).filter_map do |r|
51
+ r["value"]
52
+ end
53
+ end
54
+
55
+ def reverse_ip_search
56
+ res = client.dns_history_search(query)
57
+ (res.dig("records", "A") || []).filter_map do |r|
58
+ r["value"]
59
+ end
60
+ end
61
+
62
+ def client
63
+ Clients::Validin.new(api_key:, timeout:)
64
+ end
65
+
66
+ #
67
+ # Check whether a type is valid or not
68
+ #
69
+ # @return [Boolean]
70
+ #
71
+ def valid_type?
72
+ %w[ip domain].include? type
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Clients
5
+ #
6
+ # Validin API client
7
+ #
8
+ class Validin < Base
9
+ #
10
+ # @param [String] base_url
11
+ # @param [String, nil] api_key
12
+ # @param [Hash] headers
13
+ # @param [Integer, nil] timeout
14
+ #
15
+ def initialize(
16
+ base_url = "https://app.validin.com",
17
+ api_key:,
18
+ headers: {},
19
+ timeout: nil
20
+ )
21
+ raise(ArgumentError, "api_key is required") if api_key.nil?
22
+
23
+ headers["Authorization"] = "Bearer #{api_key}"
24
+
25
+ super(base_url, headers:, timeout:)
26
+ end
27
+
28
+ #
29
+ # @param [String] domain
30
+ #
31
+ # @return [Hash]
32
+ #
33
+ def dns_history_search(domain)
34
+ get_json "/api/axon/domain/dns/history/#{domain}/A"
35
+ end
36
+
37
+ #
38
+ # @param [String] ip
39
+ #
40
+ # @return [Hash]
41
+ #
42
+ def search_reverse_ip(ip)
43
+ get_json "/api/axon/ip/dns/history/#{ip}"
44
+ end
45
+ end
46
+ end
47
+ end
data/lib/mihari/config.rb CHANGED
@@ -33,6 +33,7 @@ module Mihari
33
33
  thehive_api_key: nil,
34
34
  thehive_url: nil,
35
35
  urlscan_api_key: nil,
36
+ validin_api_key: nil,
36
37
  virustotal_api_key: nil,
37
38
  yeti_api_key: nil,
38
39
  yeti_url: nil,
@@ -122,6 +123,9 @@ module Mihari
122
123
  # @!attribute [r] urlscan_api_key
123
124
  # @return [String, nil]
124
125
 
126
+ # @!attribute [r] validin_api_key
127
+ # @return [String, nil]
128
+
125
129
  # @!attribute [r] virustotal_api_key
126
130
  # @return [String, nil]
127
131
 
@@ -15,6 +15,7 @@ module Mihari
15
15
  Mihari::Analyzers::Onyphe.keys,
16
16
  Mihari::Analyzers::Shodan.keys,
17
17
  Mihari::Analyzers::Urlscan.keys,
18
+ Mihari::Analyzers::Validin.keys,
18
19
  Mihari::Analyzers::VirusTotalIntelligence.keys
19
20
  ].each do |keys|
20
21
  key = keys.first
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "7.5.0"
4
+ VERSION = "7.6.1"
5
5
  end
@@ -52,7 +52,7 @@ module Mihari
52
52
  end
53
53
 
54
54
  desc "Delete an alert", {
55
- success: {code: 204, model: Entities::Message},
55
+ success: {code: 204},
56
56
  failure: [{code: 404, model: Entities::ErrorMessage}],
57
57
  summary: "Delete an alert"
58
58
  }
@@ -60,11 +60,9 @@ module Mihari
60
60
  requires :id, type: Integer
61
61
  end
62
62
  delete "/:id" do
63
- status 204
64
-
65
63
  id = params["id"].to_i
66
64
  result = Services::AlertDestroyer.result(id)
67
- return present({message: ""}, with: Entities::Message) if result.success?
65
+ return if result.success?
68
66
 
69
67
  case result.failure
70
68
  when ActiveRecord::RecordNotFound
@@ -87,7 +87,7 @@ module Mihari
87
87
  end
88
88
 
89
89
  desc "Delete an artifact", {
90
- success: {code: 204, model: Entities::Message},
90
+ success: {code: 204},
91
91
  failure: [{code: 404, model: Entities::ErrorMessage}],
92
92
  summary: "Delete an artifact"
93
93
  }
@@ -99,7 +99,7 @@ module Mihari
99
99
 
100
100
  id = params["id"].to_i
101
101
  result = Services::ArtifactDestroyer.result(id)
102
- return present({message: ""}, with: Entities::Message) if result.success?
102
+ return if result.success?
103
103
 
104
104
  case result.failure
105
105
  when ActiveRecord::RecordNotFound
@@ -15,12 +15,7 @@ module Mihari
15
15
  }
16
16
  get "/" do
17
17
  configs = Services::ConfigSearcher.call
18
- present(
19
- {
20
- results: configs
21
- },
22
- with: Entities::Configs
23
- )
18
+ present({results: configs}, with: Entities::Configs)
24
19
  end
25
20
  end
26
21
  end
@@ -167,7 +167,7 @@ module Mihari
167
167
  end
168
168
 
169
169
  desc "Delete a rule", {
170
- success: {code: 204, model: Entities::Message},
170
+ success: {code: 204},
171
171
  failure: [{code: 404, model: Entities::ErrorMessage}],
172
172
  summary: "Delete a rule"
173
173
  }
@@ -179,7 +179,7 @@ module Mihari
179
179
 
180
180
  id = params[:id].to_s
181
181
  result = Services::RuleDestroyer.result(id)
182
- return present({message: "ID:#{id} is deleted"}, with: Entities::Message) if result.success?
182
+ return if result.success?
183
183
 
184
184
  case result.failure
185
185
  when ActiveRecord::RecordNotFound
@@ -32,7 +32,7 @@ module Mihari
32
32
  end
33
33
 
34
34
  desc "Delete a tag", {
35
- success: {code: 204, model: Entities::Message},
35
+ success: {code: 204},
36
36
  failure: [{code: 404, model: Entities::ErrorMessage}],
37
37
  summary: "Delete a tag"
38
38
  }
@@ -44,7 +44,7 @@ module Mihari
44
44
 
45
45
  id = params[:id].to_i
46
46
  result = Services::TagDestroyer.result(id)
47
- return present({message: ""}, with: Entities::Message) if result.success?
47
+ return if result.success?
48
48
 
49
49
  case result.failure
50
50
  when ActiveRecord::RecordNotFound