mihari 4.3.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
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)