mihari 4.3.0 → 4.4.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mihari/analyzers/binaryedge.rb +10 -1
  3. data/lib/mihari/analyzers/censys.rb +26 -1
  4. data/lib/mihari/analyzers/circl.rb +23 -1
  5. data/lib/mihari/analyzers/greynoise.rb +10 -1
  6. data/lib/mihari/analyzers/onyphe.rb +10 -1
  7. data/lib/mihari/analyzers/otx.rb +8 -2
  8. data/lib/mihari/analyzers/passivetotal.rb +25 -3
  9. data/lib/mihari/analyzers/pulsedive.rb +7 -1
  10. data/lib/mihari/analyzers/securitytrails.rb +7 -1
  11. data/lib/mihari/analyzers/shodan.rb +10 -1
  12. data/lib/mihari/analyzers/spyse.rb +10 -1
  13. data/lib/mihari/analyzers/urlscan.rb +6 -1
  14. data/lib/mihari/analyzers/virustotal.rb +7 -2
  15. data/lib/mihari/analyzers/virustotal_intelligence.rb +6 -1
  16. data/lib/mihari/analyzers/zoomeye.rb +16 -2
  17. data/lib/mihari/cli/main.rb +2 -0
  18. data/lib/mihari/commands/search.rb +14 -0
  19. data/lib/mihari/commands/version.rb +18 -0
  20. data/lib/mihari/database.rb +10 -2
  21. data/lib/mihari/emitters/misp.rb +14 -8
  22. data/lib/mihari/emitters/slack.rb +20 -28
  23. data/lib/mihari/emitters/the_hive.rb +18 -6
  24. data/lib/mihari/entities/rule.rb +1 -12
  25. data/lib/mihari/errors.rb +2 -0
  26. data/lib/mihari/mixins/configurable.rb +12 -1
  27. data/lib/mihari/mixins/rule.rb +16 -19
  28. data/lib/mihari/models/artifact.rb +7 -2
  29. data/lib/mihari/models/rule.rb +12 -3
  30. data/lib/mihari/schemas/analyzer.rb +89 -10
  31. data/lib/mihari/schemas/emitter.rb +35 -0
  32. data/lib/mihari/schemas/rule.rb +5 -62
  33. data/lib/mihari/structs/rule.rb +33 -5
  34. data/lib/mihari/types.rb +0 -25
  35. data/lib/mihari/version.rb +1 -1
  36. data/lib/mihari/web/endpoints/rules.rb +20 -3
  37. data/lib/mihari/web/public/index.html +1 -1
  38. data/lib/mihari/web/public/redoc-static.html +11 -11
  39. data/lib/mihari/web/public/static/css/app.de5845d8.css +1 -0
  40. data/lib/mihari/web/public/static/css/chunk-vendors.da2a7bfc.css +7 -0
  41. data/lib/mihari/web/public/static/js/app-legacy.f550d6ae.js +2 -0
  42. data/lib/mihari/web/public/static/js/app-legacy.f550d6ae.js.map +1 -0
  43. data/lib/mihari/web/public/static/js/app.40749592.js +2 -0
  44. data/lib/mihari/web/public/static/js/app.40749592.js.map +1 -0
  45. data/lib/mihari/web/public/static/js/chunk-vendors-legacy.d6b76c57.js +25 -0
  46. data/lib/mihari/web/public/static/js/chunk-vendors-legacy.d6b76c57.js.map +1 -0
  47. data/lib/mihari/web/public/static/js/chunk-vendors.3bdbaffb.js +31 -0
  48. data/lib/mihari/web/public/static/js/chunk-vendors.3bdbaffb.js.map +1 -0
  49. data/mihari.gemspec +2 -2
  50. data/sig/lib/mihari/analyzers/binaryedge.rbs +2 -0
  51. data/sig/lib/mihari/analyzers/censys.rbs +4 -0
  52. data/sig/lib/mihari/analyzers/circl.rbs +5 -1
  53. data/sig/lib/mihari/analyzers/onyphe.rbs +2 -0
  54. data/sig/lib/mihari/analyzers/otx.rbs +3 -1
  55. data/sig/lib/mihari/analyzers/passivetotal.rbs +5 -1
  56. data/sig/lib/mihari/analyzers/pulsedive.rbs +3 -1
  57. data/sig/lib/mihari/analyzers/securitytrails.rbs +3 -1
  58. data/sig/lib/mihari/analyzers/shodan.rbs +2 -0
  59. data/sig/lib/mihari/analyzers/spyse.rbs +3 -1
  60. data/sig/lib/mihari/analyzers/urlscan.rbs +2 -0
  61. data/sig/lib/mihari/analyzers/virustotal.rbs +3 -1
  62. data/sig/lib/mihari/analyzers/virustotal_intelligence.rbs +2 -0
  63. data/sig/lib/mihari/analyzers/zoomeye.rbs +3 -1
  64. data/sig/lib/mihari/emitters/misp.rbs +6 -0
  65. data/sig/lib/mihari/emitters/slack.rbs +8 -20
  66. data/sig/lib/mihari/emitters/the_hive.rbs +4 -0
  67. data/sig/lib/mihari/mixins/configurable.rbs +4 -0
  68. data/sig/lib/mihari/mixins/rule.rbs +2 -0
  69. data/sig/lib/mihari/models/rule.rbs +3 -0
  70. data/sig/lib/mihari/structs/rule.rbs +5 -1
  71. metadata +18 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc5b6ab7daa3030a0ef0778df2753247bde10b978be709102ecf1be60b672a9c
4
- data.tar.gz: 1c1c283cf1e2989e9e94e0aa582567dd71b7900f5c5faa40a0ce3f1b327982a3
3
+ metadata.gz: 44f680c0a24d2b66c8f13c8abe14994138231a4099b975d94a917f105561329c
4
+ data.tar.gz: b9da29828c04ad6151bb748f17c3518875b90208f728e4f1be9e0f716acd5368
5
5
  SHA512:
6
- metadata.gz: 918ee19022035b5f5e3db9a00318253803b1cc430b45676225af94861fe6dc6fe51343545d224e6094f09ad37dc003713fbbcb1777904b01205903e22d05bf23
7
- data.tar.gz: c5ce99eb3d8e01b1b2a8ac51916afa172c1fecb55611a3b8aa76e686c72801beb11135ed1c8aed31e11b693b7467dbe513902f55e229c834bbfcb09460ba4202
6
+ metadata.gz: ddccc9e9b10822bc93bb595f837a327c6459c51799ad95483014173c7d911405fd7fcd869f435a7404af585ccfa21ddfcd1ae922a94096a850eda52c4886627b
7
+ data.tar.gz: 8962eb94f57de019a7dd1040132d315482dbf3668a36ae4f61da46f31994c3bac0df47142fdbe998b80603cdcce86de0c7bb276eb2335e48d25820eebc94dee8
@@ -9,6 +9,15 @@ module Mihari
9
9
 
10
10
  option :interval, default: proc { 0 }
11
11
 
12
+ # @return [String, nil]
13
+ attr_reader :api_key
14
+
15
+ def initialize(*args, **kwargs)
16
+ super(*args, **kwargs)
17
+
18
+ @api_key = kwargs[:api_key] || Mihari.config.binaryedge_api_key
19
+ end
20
+
12
21
  def artifacts
13
22
  results = search
14
23
  return [] unless results || results.empty?
@@ -67,7 +76,7 @@ module Mihari
67
76
  end
68
77
 
69
78
  def api
70
- @api ||= ::BinaryEdge::API.new(Mihari.config.binaryedge_api_key)
79
+ @api ||= ::BinaryEdge::API.new(api_key)
71
80
  end
72
81
  end
73
82
  end
@@ -9,10 +9,27 @@ module Mihari
9
9
 
10
10
  option :interval, default: proc { 0 }
11
11
 
12
+ # @return [String, nil]
13
+ attr_reader :id
14
+
15
+ # @return [String, nil]
16
+ attr_reader :secret
17
+
18
+ def initialize(*args, **kwargs)
19
+ super(*args, **kwargs)
20
+
21
+ @id = kwargs[:id] || Mihari.config.censys_id
22
+ @secret = kwargs[:secret] || Mihari.config.censys_secret
23
+ end
24
+
12
25
  def artifacts
13
26
  search
14
27
  end
15
28
 
29
+ def configured?
30
+ configuration_keys.all? { |key| Mihari.config.send(key) } || (id? && secret?)
31
+ end
32
+
16
33
  private
17
34
 
18
35
  #
@@ -85,7 +102,15 @@ module Mihari
85
102
  end
86
103
 
87
104
  def api
88
- @api ||= ::Censys::API.new(Mihari.config.censys_id, Mihari.config.censys_secret)
105
+ @api ||= ::Censys::API.new(id, secret)
106
+ end
107
+
108
+ def id?
109
+ !id.nil?
110
+ end
111
+
112
+ def secret?
113
+ !secret.nil?
89
114
  end
90
115
  end
91
116
  end
@@ -9,19 +9,33 @@ module Mihari
9
9
 
10
10
  param :query
11
11
 
12
+ # @return [String, nil]
12
13
  attr_reader :type
13
14
 
15
+ # @return [String, nil]
16
+ attr_reader :username
17
+
18
+ # @return [String, nil]
19
+ attr_reader :password
20
+
14
21
  def initialize(*args, **kwargs)
15
22
  super
16
23
 
17
24
  @query = refang(query)
18
25
  @type = TypeChecker.type(query)
26
+
27
+ @username = kwargs[:username] || Mihari.config.circl_passive_username
28
+ @password = kwargs[:password] || Mihari.config.circl_passive_password
19
29
  end
20
30
 
21
31
  def artifacts
22
32
  search || []
23
33
  end
24
34
 
35
+ def configured?
36
+ configuration_keys.all? { |key| Mihari.config.send(key) } || (username? && password?)
37
+ end
38
+
25
39
  private
26
40
 
27
41
  def configuration_keys
@@ -29,7 +43,7 @@ module Mihari
29
43
  end
30
44
 
31
45
  def api
32
- @api ||= ::PassiveCIRCL::API.new(username: Mihari.config.circl_passive_username, password: Mihari.config.circl_passive_password)
46
+ @api ||= ::PassiveCIRCL::API.new(username: username, password: password)
33
47
  end
34
48
 
35
49
  #
@@ -71,6 +85,14 @@ module Mihari
71
85
  seen = result["seen"] || []
72
86
  seen.uniq
73
87
  end
88
+
89
+ def username?
90
+ !username.nil?
91
+ end
92
+
93
+ def password?
94
+ !password.nil?
95
+ end
74
96
  end
75
97
  end
76
98
  end
@@ -7,6 +7,15 @@ module Mihari
7
7
  class GreyNoise < Base
8
8
  param :query
9
9
 
10
+ # @return [String, nil]
11
+ attr_reader :api_key
12
+
13
+ def initialize(*args, **kwargs)
14
+ super(*args, **kwargs)
15
+
16
+ @api_key = kwargs[:api_key] || Mihari.config.greynoise_api_key
17
+ end
18
+
10
19
  def artifacts
11
20
  res = Structs::GreyNoise::Response.from_dynamic!(search)
12
21
  res.data.map do |datum|
@@ -23,7 +32,7 @@ module Mihari
23
32
  end
24
33
 
25
34
  def api
26
- @api ||= ::GreyNoise::API.new(key: Mihari.config.greynoise_api_key)
35
+ @api ||= ::GreyNoise::API.new(key: api_key)
27
36
  end
28
37
 
29
38
  #
@@ -10,6 +10,15 @@ module Mihari
10
10
 
11
11
  option :interval, default: proc { 0 }
12
12
 
13
+ # @return [String, nil]
14
+ attr_reader :api_key
15
+
16
+ def initialize(*args, **kwargs)
17
+ super(*args, **kwargs)
18
+
19
+ @api_key = kwargs[:api_key] || Mihari.config.onyphe_api_key
20
+ end
21
+
13
22
  def artifacts
14
23
  responses = search
15
24
  return [] unless responses
@@ -29,7 +38,7 @@ module Mihari
29
38
  end
30
39
 
31
40
  def api
32
- @api ||= ::Onyphe::API.new(Mihari.config.onyphe_api_key)
41
+ @api ||= ::Onyphe::API.new(api_key)
33
42
  end
34
43
 
35
44
  #
@@ -9,13 +9,19 @@ module Mihari
9
9
 
10
10
  param :query
11
11
 
12
+ # @return [String, nil]
12
13
  attr_reader :type
13
14
 
15
+ # @return [String, nil]
16
+ attr_reader :api_key
17
+
14
18
  def initialize(*args, **kwargs)
15
19
  super
16
20
 
17
21
  @query = refang(query)
18
22
  @type = TypeChecker.type(query)
23
+
24
+ @api_key = kwargs[:api_key] || Mihari.config.otx_api_key
19
25
  end
20
26
 
21
27
  def artifacts
@@ -29,11 +35,11 @@ module Mihari
29
35
  end
30
36
 
31
37
  def domain_client
32
- @domain_client ||= ::OTX::Domain.new(Mihari.config.otx_api_key)
38
+ @domain_client ||= ::OTX::Domain.new(api_key)
33
39
  end
34
40
 
35
41
  def ip_client
36
- @ip_client ||= ::OTX::IP.new(Mihari.config.otx_api_key)
42
+ @ip_client ||= ::OTX::IP.new(api_key)
37
43
  end
38
44
 
39
45
  #
@@ -9,19 +9,33 @@ module Mihari
9
9
 
10
10
  param :query
11
11
 
12
+ # @return [String, nil]
12
13
  attr_reader :type
13
14
 
15
+ # @return [String, nil]
16
+ attr_reader :username
17
+
18
+ # @return [String, nil]
19
+ attr_reader :api_key
20
+
14
21
  def initialize(*args, **kwargs)
15
- super
22
+ super(*args, **kwargs)
16
23
 
17
24
  @query = refang(query)
18
25
  @type = TypeChecker.type(query)
26
+
27
+ @username = kwargs[:username] || Mihari.config.passivetotal_username
28
+ @api_key = kwargs[:api_key] || Mihari.config.passivetotal_api_key
19
29
  end
20
30
 
21
31
  def artifacts
22
32
  search || []
23
33
  end
24
34
 
35
+ def configured?
36
+ configuration_keys.all? { |key| Mihari.config.send(key) } || (username? && api_key?)
37
+ end
38
+
25
39
  private
26
40
 
27
41
  def configuration_keys
@@ -29,7 +43,7 @@ module Mihari
29
43
  end
30
44
 
31
45
  def api
32
- @api ||= ::PassiveTotal::API.new(username: Mihari.config.passivetotal_username, api_key: Mihari.config.passivetotal_api_key)
46
+ @api ||= ::PassiveTotal::API.new(username: username, api_key: api_key)
33
47
  end
34
48
 
35
49
  #
@@ -93,9 +107,17 @@ module Mihari
93
107
  results = res["results"] || []
94
108
  results.map do |result|
95
109
  data = result["ipAddresses"]
96
- Artifact.new(data: data, source: source, metadata: result)
110
+ data.map { |d| Artifact.new(data: d, source: source, metadata: result) }
97
111
  end.flatten
98
112
  end
113
+
114
+ def username?
115
+ !username.nil?
116
+ end
117
+
118
+ def api_key?
119
+ !api_key.nil?
120
+ end
99
121
  end
100
122
  end
101
123
  end
@@ -9,13 +9,19 @@ module Mihari
9
9
 
10
10
  param :query
11
11
 
12
+ # @return [String, nil]
12
13
  attr_reader :type
13
14
 
15
+ # @return [String, nil]
16
+ attr_reader :api_key
17
+
14
18
  def initialize(*args, **kwargs)
15
19
  super
16
20
 
17
21
  @query = refang(query)
18
22
  @type = TypeChecker.type(query)
23
+
24
+ @api_key = kwargs[:api_key] || Mihari.config.pulsedive_api_key
19
25
  end
20
26
 
21
27
  def artifacts
@@ -29,7 +35,7 @@ module Mihari
29
35
  end
30
36
 
31
37
  def api
32
- @api ||= ::Pulsedive::API.new(Mihari.config.pulsedive_api_key)
38
+ @api ||= ::Pulsedive::API.new(api_key)
33
39
  end
34
40
 
35
41
  #
@@ -9,13 +9,19 @@ module Mihari
9
9
 
10
10
  param :query
11
11
 
12
+ # @return [String, nil]
12
13
  attr_reader :type
13
14
 
15
+ # @return [String, nil]
16
+ attr_reader :api_key
17
+
14
18
  def initialize(*args, **kwargs)
15
19
  super
16
20
 
17
21
  @query = refang(query)
18
22
  @type = TypeChecker.type(query)
23
+
24
+ @api_key = kwargs[:api_key] || Mihari.config.securitytrails_api_key
19
25
  end
20
26
 
21
27
  def artifacts
@@ -29,7 +35,7 @@ module Mihari
29
35
  end
30
36
 
31
37
  def api
32
- @api ||= ::SecurityTrails::API.new(Mihari.config.securitytrails_api_key)
38
+ @api ||= ::SecurityTrails::API.new(api_key)
33
39
  end
34
40
 
35
41
  #
@@ -9,6 +9,15 @@ module Mihari
9
9
 
10
10
  option :interval, default: proc { 0 }
11
11
 
12
+ # @return [String, nil]
13
+ attr_reader :api_key
14
+
15
+ def initialize(*args, **kwargs)
16
+ super(*args, **kwargs)
17
+
18
+ @api_key = kwargs[:api_key] || Mihari.config.shodan_api_key
19
+ end
20
+
12
21
  def artifacts
13
22
  results = search
14
23
  return [] unless results || results.empty?
@@ -29,7 +38,7 @@ module Mihari
29
38
  end
30
39
 
31
40
  def api
32
- @api ||= ::Shodan::API.new(key: Mihari.config.shodan_api_key)
41
+ @api ||= ::Shodan::API.new(key: api_key)
33
42
  end
34
43
 
35
44
  #
@@ -9,6 +9,15 @@ module Mihari
9
9
 
10
10
  option :type, default: proc { "domain" }
11
11
 
12
+ # @return [String, nil]
13
+ attr_reader :api_key
14
+
15
+ def initialize(*args, **kwargs)
16
+ super(*args, **kwargs)
17
+
18
+ @api_key = kwargs[:api_key] || Mihari.config.spyse_api_key
19
+ end
20
+
12
21
  def artifacts
13
22
  search || []
14
23
  end
@@ -24,7 +33,7 @@ module Mihari
24
33
  end
25
34
 
26
35
  def api
27
- @api ||= ::Spyse::API.new(Mihari.config.spyse_api_key)
36
+ @api ||= ::Spyse::API.new(api_key)
28
37
  end
29
38
 
30
39
  #
@@ -14,10 +14,15 @@ module Mihari
14
14
  SUPPORTED_DATA_TYPES = %w[url domain ip].freeze
15
15
  SIZE = 1000
16
16
 
17
+ # @return [String, nil]
18
+ attr_reader :api_key
19
+
17
20
  def initialize(*args, **kwargs)
18
21
  super
19
22
 
20
23
  raise InvalidInputError, "allowed_data_types should be any of url, domain and ip." unless valid_alllowed_data_types?
24
+
25
+ @api_key = kwargs[:api_key] || Mihari.config.urlscan_api_key
21
26
  end
22
27
 
23
28
  def artifacts
@@ -40,7 +45,7 @@ module Mihari
40
45
  end
41
46
 
42
47
  def api
43
- @api ||= ::UrlScan::API.new(Mihari.config.urlscan_api_key)
48
+ @api ||= ::UrlScan::API.new(api_key)
44
49
  end
45
50
 
46
51
  #
@@ -11,11 +11,16 @@ module Mihari
11
11
 
12
12
  attr_reader :type
13
13
 
14
+ # @return [String, nil]
15
+ attr_reader :api_key
16
+
14
17
  def initialize(*args, **kwargs)
15
- super
18
+ super(*args, **kwargs)
16
19
 
17
20
  @query = refang(query)
18
21
  @type = TypeChecker.type(query)
22
+
23
+ @api_key = kwargs[:api_key] || Mihari.config.virustotal_api_key
19
24
  end
20
25
 
21
26
  def artifacts
@@ -29,7 +34,7 @@ module Mihari
29
34
  end
30
35
 
31
36
  def api
32
- @api = ::VirusTotal::API.new(key: Mihari.config.virustotal_api_key)
37
+ @api = ::VirusTotal::API.new(key: api_key)
33
38
  end
34
39
 
35
40
  #
@@ -9,10 +9,15 @@ module Mihari
9
9
 
10
10
  option :interval, default: proc { 0 }
11
11
 
12
+ # @return [String, nil]
13
+ attr_reader :api_key
14
+
12
15
  def initialize(*args, **kwargs)
13
16
  super
14
17
 
15
18
  @query = query
19
+
20
+ @api_key = kwargs[:api_key] || Mihari.config.virustotal_api_key
16
21
  end
17
22
 
18
23
  def artifacts
@@ -36,7 +41,7 @@ module Mihari
36
41
  # @return [::VirusTotal::API]
37
42
  #
38
43
  def api
39
- @api = ::VirusTotal::API.new(key: Mihari.config.virustotal_api_key)
44
+ @api = ::VirusTotal::API.new(key: api_key)
40
45
  end
41
46
 
42
47
  #
@@ -11,6 +11,15 @@ module Mihari
11
11
 
12
12
  option :interval, default: proc { 0 }
13
13
 
14
+ # @return [String, nil]
15
+ attr_reader :api_key
16
+
17
+ def initialize(*args, **kwargs)
18
+ super(*args, **kwargs)
19
+
20
+ @api_key = kwargs[:api_key] || Mihari.config.zoomeye_api_key
21
+ end
22
+
14
23
  def artifacts
15
24
  case type
16
25
  when "host"
@@ -40,7 +49,7 @@ module Mihari
40
49
  end
41
50
 
42
51
  def api
43
- @api ||= ::ZoomEye::API.new(api_key: Mihari.config.zoomeye_api_key)
52
+ @api ||= ::ZoomEye::API.new(api_key: api_key)
44
53
  end
45
54
 
46
55
  #
@@ -55,7 +64,12 @@ module Mihari
55
64
  matches = res["matches"] || []
56
65
  matches.map do |match|
57
66
  data = match["ip"]
58
- Artifact.new(data: data, source: source, metadata: match)
67
+
68
+ if data.is_a?(Array)
69
+ data.map { |d| Artifact.new(data: d, source: source, metadata: match) }
70
+ else
71
+ Artifact.new(data: data, source: source, metadata: match)
72
+ end
59
73
  end
60
74
  end.flatten.compact.uniq
61
75
  end
@@ -4,6 +4,7 @@ require "thor"
4
4
 
5
5
  # Commands
6
6
  require "mihari/commands/search"
7
+ require "mihari/commands/version"
7
8
  require "mihari/commands/web"
8
9
 
9
10
  # CLIs
@@ -16,6 +17,7 @@ module Mihari
16
17
  module CLI
17
18
  class Main < Base
18
19
  include Mihari::Commands::Search
20
+ include Mihari::Commands::Version
19
21
  include Mihari::Commands::Web
20
22
 
21
23
  desc "init", "Sub commands to initialize a rule"
@@ -10,6 +10,7 @@ module Mihari
10
10
  def self.included(thor)
11
11
  thor.class_eval do
12
12
  desc "search [RULE]", "Search by a rule"
13
+ method_option :yes, type: :boolean, aliases: "-y", desc: "yes to overwrite the rule in the database"
13
14
  def search_by_rule(path_or_id)
14
15
  rule = load_rule(path_or_id)
15
16
 
@@ -20,6 +21,19 @@ module Mihari
20
21
  raise e
21
22
  end
22
23
 
24
+ # check update
25
+ id = rule.id
26
+ yes = options["yes"] || false
27
+ unless yes
28
+ with_db_connection do
29
+ rule_ = Mihari::Rule.find(id)
30
+ next if rule.yaml == rule_.yaml
31
+ return unless yes?("This operation will overwrite the rule in the database (Rule ID: #{id}). Are you sure you want to update the rule? (yes/no)")
32
+ rescue ActiveRecord::RecordNotFound
33
+ next
34
+ end
35
+ end
36
+
23
37
  analyzer = rule.to_analyzer
24
38
 
25
39
  with_error_notification do
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Commands
5
+ module Version
6
+ def self.included(thor)
7
+ thor.class_eval do
8
+ map %w[--version -v] => :__print_version
9
+
10
+ desc "--version, -v", "Print the version"
11
+ def __print_version
12
+ puts Mihari::VERSION
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -112,6 +112,12 @@ class AddeMetadataToArtifactSchema < ActiveRecord::Migration[7.0]
112
112
  end
113
113
  end
114
114
 
115
+ class AddYAMLToRulesSchema < ActiveRecord::Migration[7.0]
116
+ def change
117
+ add_column :rules, :yaml, :text, if_not_exists: true
118
+ end
119
+ end
120
+
115
121
  def adapter
116
122
  return "postgresql" if Mihari.config.database.start_with?("postgresql://", "postgres://")
117
123
  return "mysql2" if Mihari.config.database.start_with?("mysql2://")
@@ -137,9 +143,11 @@ module Mihari
137
143
  AddeSourceToArtifactSchema,
138
144
  EnrichmentsSchema,
139
145
  EnrichmentCreatedAtSchema,
140
- # v4
146
+ # v4.0
141
147
  RuleSchema,
142
- AddeMetadataToArtifactSchema
148
+ AddeMetadataToArtifactSchema,
149
+ # v4.4
150
+ AddYAMLToRulesSchema
143
151
  ].each { |schema| schema.migrate direction }
144
152
  end
145
153
  memoize :migrate unless test_env?
@@ -5,12 +5,21 @@ require "misp"
5
5
  module Mihari
6
6
  module Emitters
7
7
  class MISP < Base
8
- def initialize
9
- super()
8
+ # @return [String, nil]
9
+ attr_reader :api_endpoint
10
+
11
+ # @return [String, nil]
12
+ attr_reader :api_key
13
+
14
+ def initialize(*args, **kwargs)
15
+ super(*args, **kwargs)
16
+
17
+ @api_endpoint = kwargs[:api_endpoint] || Mihari.config.misp_api_endpoint
18
+ @api_key = kwargs[:api_key] || Mihari.config.misp_api_key
10
19
 
11
20
  ::MISP.configure do |config|
12
- config.api_endpoint = Mihari.config.misp_api_endpoint
13
- config.api_key = Mihari.config.misp_api_key
21
+ config.api_endpoint = api_endpoint
22
+ config.api_key = api_key
14
23
  end
15
24
  end
16
25
 
@@ -99,7 +108,6 @@ module Mihari
99
108
  # @return [Boolean]
100
109
  #
101
110
  def api_endpoint?
102
- api_endpoint = ::MISP.configuration.api_endpoint
103
111
  !api_endpoint.nil? && !api_endpoint.empty?
104
112
  end
105
113
 
@@ -109,7 +117,6 @@ module Mihari
109
117
  # @return [Boolean]
110
118
  #
111
119
  def api_key?
112
- api_key = ::MISP.configuration.api_key
113
120
  !api_key.nil? && !api_key.empty?
114
121
  end
115
122
 
@@ -119,8 +126,7 @@ module Mihari
119
126
  # @return [Boolean]
120
127
  #
121
128
  def ping?
122
- base_url = ::MISP.configuration.api_endpoint
123
- base_url = base_url.end_with?("/") ? base_url[0..-2] : base_url
129
+ base_url = api_endpoint.end_with?("/") ? api_endpoint[0..-2] : api_endpoint
124
130
  url = "#{base_url}/users/login"
125
131
 
126
132
  http = Net::Ping::HTTP.new(url)