mihari 0.10.0 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8de738680ca57bdaf9ba336692c3cad0be84cfffc055eef2785fd7c1c3bf32d6
4
- data.tar.gz: e6cda3a6e8d0f9c49728e6d04284332fe7f820287078e83fdd5cfa1ede4c27fc
3
+ metadata.gz: 4a0fd2207c7c92a24cbeda2fb328ecca19db331aa00132b3f6d361d6f8b4b6fd
4
+ data.tar.gz: 77b42d18d1509f6a33be27d38064298b726fa3244364d468714926d2878c3e89
5
5
  SHA512:
6
- metadata.gz: '0238a0da4e31a5146aa4fc5b8ed16b012a9d874657e1ae69ede3ad0bc7ec6c95a74374160b6871e5eade40d90455f54c5522fe17b33d200e0898f7c748629619'
7
- data.tar.gz: 9d60cae8a47366f44eebed73fc78ed0d21c239131636d87be6621af255b669b3ef5abb5649a4d3ae8ba77120f06939cf74bf52f78d07fa4535369bec426a88aa
6
+ metadata.gz: 14bbf6da4dffb24e0fb3c696bc664970a33784298b7fd09d24c9e792262b27a8eebd229fa1b0d17218e1116590acda49b56d4afff0bbc147c8c661dc545df811
7
+ data.tar.gz: 308620e95164284b5370985899ed524705b64808a2ceb073af404e619901a0dc00277653e2e0eb41e83d5a9db4678577436fe28a78c5e8accb2534dd5362ae22
data/README.md CHANGED
@@ -10,10 +10,10 @@ mihari(`見張り`) is a sidekick tool for [TheHive](https://github.com/TheHive-
10
10
 
11
11
  ## How it works
12
12
 
13
- - mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts from the query results.
14
- - mihari checks whether a TheHive instance contains the artifacts or not.
13
+ - mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts from the results.
14
+ - mihari checks whether TheHive contains the artifacts or not.
15
15
  - If it doesn't contain the artifacts:
16
- - mihari creates an alert with the artifacts on the TheHive instance.
16
+ - mihari creates an alert on TheHive.
17
17
  - mihari sends a notification to Slack. (Optional)
18
18
  - mihari creates an event on MISP. (Optional)
19
19
 
@@ -51,7 +51,7 @@ docker pull ninoseki/mihari
51
51
 
52
52
  ## Basic usage
53
53
 
54
- mihari supports Censys, Shodan, Onyphe, urlscan, SecurityTrails, crt.sh, CIRCL passive DNS/SSL and VirusTotal by default.
54
+ mihari supports Censys, Shodan, Onyphe, urlscan, SecurityTrails, crt.sh, CIRCL passive DNS/SSL, PassiveTotal and VirusTotal by default.
55
55
 
56
56
  ```bash
57
57
  $ mihari
@@ -64,7 +64,8 @@ Commands:
64
64
  mihari help [COMMAND] # Describe available commands or one specific command
65
65
  mihari import_from_json # Give a JSON input via STDIN
66
66
  mihari onyphe [QUERY] # Onyphe datascan lookup by a given query
67
- mihari securitytrails [IP|DOMAIN] # SecurityTrails resolutions lookup by a given ip or domain
67
+ mihari passivetotal [IP|DOMAIN|EMAIL|SHA1] # PassiveTotal lookup by a given ip / domain / email / SHA1 certificate fingerprint
68
+ mihari securitytrails [IP|DOMAIN|EMAIL] # SecurityTrails lookup by a given ip, domain or email
68
69
  mihari securitytrails_domain_feed [REGEXP] # SecurityTrails new domain feed lookup by a given regexp
69
70
  mihari shodan [QUERY] # Shodan host lookup by a given query
70
71
  mihari status # Show the current configuration status
@@ -157,9 +158,11 @@ All configuration is done via ENV variables.
157
158
  | SLACK_CHANNEL | Slack channel name | Optional (default: `#general`) |
158
159
  | CENSYS_ID | Censys API ID | Optional |
159
160
  | CENSYS_SECRET | Censys secret | Optional |
160
- | CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username | Optional |
161
161
  | CIRCL_PASSIVE_PASSWORD | CIRC_ passive DNS/SSL password | Optional |
162
+ | CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username | Optional |
162
163
  | ONYPHE_API_KEY | Onyphe API key | Optional |
164
+ | PASSIVETOTAL_API_KEY | PassiveTotal API key | Optional |
165
+ | PASSIVETOTAL_USERNAME | PassiveTotal username | Optional |
163
166
  | SECURITYTRAILS_API_KEY | SecurityTrails API key | Optional |
164
167
  | SHODAN_API_KEY | Shodan API key | Optional |
165
168
  | VIRUSTOTAL_API_KEY | VirusTotal API key | Optional |
@@ -220,20 +223,6 @@ mihari caches execution results in `/tmp/mihari` and the default cache duration
220
223
 
221
224
  ```bash
222
225
  $ docker run --rm ninoseki/mihari
223
- Commands:
224
- mihari alerts # Show the alerts on TheHive
225
- mihari censys [QUERY] # Censys IPv4 lookup by a given...
226
- mihari crtsh [QUERY] # crt.sh lookup by a given query
227
- mihari help [COMMAND] # Describe available commands o...
228
- mihari import_from_json # Give a JSON input via STDIN
229
- mihari onyphe [QUERY] # Onyphe datascan lookup by a g...
230
- mihari securitytrails [IP|DOMAIN] # SecurityTrails resolutions lo...
231
- mihari securitytrails_domain_feed [REGEXP] # SecurityTrails new domain fee...
232
- mihari shodan [QUERY] # Shodan host lookup by a given...
233
- mihari status # Show the current configuratio...
234
- mihari urlscan [QUERY] # urlscan lookup by a given query
235
- mihari virustotal [IP|DOMAIN] # VirusTotal resolutions lookup...
236
-
237
226
  # Note that you should pass configurations via environment variables
238
227
  $ docker run --rm ninoseki/mihari -e THEHIVE_API_ENDPOINT="http://THEHIVE_URL" -e THEHIVE_API_KEY="API KEY" mihari
239
228
  # or
@@ -10,6 +10,11 @@ module Mihari
10
10
  []
11
11
  end
12
12
  memoize :emitters
13
+
14
+ def analyzers
15
+ []
16
+ end
17
+ memoize :analyzers
13
18
  end
14
19
  end
15
20
 
@@ -21,6 +26,8 @@ require "mihari/artifact"
21
26
  require "mihari/cache"
22
27
  require "mihari/type_checker"
23
28
 
29
+ require "mihari/configurable"
30
+
24
31
  require "mihari/the_hive/base"
25
32
  require "mihari/the_hive/alert"
26
33
  require "mihari/the_hive/artifact"
@@ -33,6 +40,7 @@ require "mihari/analyzers/circl"
33
40
  require "mihari/analyzers/crtsh"
34
41
  require "mihari/analyzers/dnpedia"
35
42
  require "mihari/analyzers/onyphe"
43
+ require "mihari/analyzers/passivetotal"
36
44
  require "mihari/analyzers/securitytrails_domain_feed"
37
45
  require "mihari/analyzers/securitytrails"
38
46
  require "mihari/analyzers/shodan"
@@ -5,10 +5,7 @@ require "parallel"
5
5
  module Mihari
6
6
  module Analyzers
7
7
  class Base
8
- def initialize
9
- @the_hive = TheHive.new
10
- @cache = Cache.new
11
- end
8
+ include Configurable
12
9
 
13
10
  # @return [Array<String>, Array<Mihari::Artifact>]
14
11
  def artifacts
@@ -47,8 +44,20 @@ module Mihari
47
44
  puts "Emission by #{emitter.class} is failed: #{e}"
48
45
  end
49
46
 
47
+ def self.inherited(child)
48
+ Mihari.analyzers << child
49
+ end
50
+
50
51
  private
51
52
 
53
+ def the_hive
54
+ @the_hive ||= TheHive.new
55
+ end
56
+
57
+ def cache
58
+ @cache ||= Cache.new
59
+ end
60
+
52
61
  # @return [Array<Mihari::Artifact>]
53
62
  def normalized_artifacts
54
63
  @normalized_artifacts ||= artifacts.map do |artifact|
@@ -58,15 +67,15 @@ module Mihari
58
67
 
59
68
  def uncached_artifacts
60
69
  @uncached_artifacts ||= normalized_artifacts.reject do |artifact|
61
- @cache.cached? artifact.data
70
+ cache.cached? artifact.data
62
71
  end
63
72
  end
64
73
 
65
74
  # @return [Array<Mihari::Artifact>]
66
75
  def unique_artifacts
67
- return uncached_artifacts unless @the_hive.valid?
76
+ return uncached_artifacts unless the_hive.valid?
68
77
 
69
- @unique_artifacts ||= @the_hive.artifact.find_non_existing_artifacts(uncached_artifacts)
78
+ @unique_artifacts ||= the_hive.artifact.find_non_existing_artifacts(uncached_artifacts)
70
79
  end
71
80
 
72
81
  def set_unique_artifacts
@@ -3,14 +3,12 @@
3
3
  module Mihari
4
4
  module Analyzers
5
5
  class Basic < Base
6
- attr_reader :title
6
+ attr_accessor :title
7
7
  attr_reader :description
8
8
  attr_reader :artifacts
9
9
  attr_reader :tags
10
10
 
11
11
  def initialize(title:, description:, artifacts:, tags: [])
12
- super()
13
-
14
12
  @title = title
15
13
  @description = description
16
14
  @artifacts = artifacts
@@ -10,9 +10,6 @@ module Mihari
10
10
  attr_reader :query
11
11
  attr_reader :tags
12
12
 
13
- CENSYS_ID_KEY = "CENSYS_ID"
14
- CENSYS_SECRET_KEY = "CENSYS_SECRET"
15
-
16
13
  def initialize(query, title: nil, description: nil, tags: [])
17
14
  super()
18
15
 
@@ -24,34 +21,22 @@ module Mihari
24
21
 
25
22
  def artifacts
26
23
  ipv4s = []
24
+
27
25
  res = api.ipv4.search(query: query)
28
26
  res.each_page do |page|
29
- page.each { |result| ipv4s << result.ip }
27
+ ipv4s << page.map(&:ip)
30
28
  end
31
29
 
32
- ipv4s
33
- end
34
-
35
- # @return [true, false]
36
- def valid?
37
- censys_id? && censys_secret?
30
+ ipv4s.flatten
38
31
  end
39
32
 
40
33
  private
41
34
 
42
- # @return [true, false]
43
- def censys_id?
44
- ENV.key? CENSYS_ID_KEY
45
- end
46
-
47
- # @return [true, false]
48
- def censys_secret?
49
- ENV.key? CENSYS_SECRET_KEY
35
+ def config_keys
36
+ %w(CENSYS_ID CENSYS_SECRET)
50
37
  end
51
38
 
52
39
  def api
53
- raise ArgumentError, "#{CENSYS_ID_KEY} and #{CENSYS_SECRET_KEY} are required" unless valid?
54
-
55
40
  @api ||= ::Censys::API.new
56
41
  end
57
42
  end
@@ -26,6 +26,10 @@ module Mihari
26
26
 
27
27
  private
28
28
 
29
+ def config_keys
30
+ %w(CIRCL_PASSIVE_USERNAME CIRCL_PASSIVE_PASSWORD)
31
+ end
32
+
29
33
  def api
30
34
  @api ||= ::PassiveCIRCL::API.new
31
35
  end
@@ -29,6 +29,10 @@ module Mihari
29
29
 
30
30
  private
31
31
 
32
+ def config_keys
33
+ %w(ONYPHE_API_KEY)
34
+ end
35
+
32
36
  def api
33
37
  @api ||= ::Onyphe::API.new
34
38
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "passivetotal"
4
+
5
+ module Mihari
6
+ module Analyzers
7
+ class PassiveTotal < Base
8
+ attr_reader :query
9
+ attr_reader :type
10
+
11
+ attr_reader :title
12
+ attr_reader :description
13
+ attr_reader :tags
14
+
15
+ def initialize(query, title: nil, description: nil, tags: [])
16
+ super()
17
+
18
+ @query = query
19
+ @type = TypeChecker.type(query)
20
+
21
+ @title = title || "PassiveTotal lookup"
22
+ @description = description || "query = #{query}"
23
+ @tags = tags
24
+ end
25
+
26
+ def artifacts
27
+ lookup || []
28
+ end
29
+
30
+ private
31
+
32
+ def config_keys
33
+ %w(PASSIVETOTAL_USERNAME PASSIVETOTAL_API_KEY)
34
+ end
35
+
36
+ def api
37
+ @api ||= ::PassiveTotal::API.new
38
+ end
39
+
40
+ def valid_type?
41
+ %w(ip domain mail).include? type
42
+ end
43
+
44
+ def lookup
45
+ case type
46
+ when "domain"
47
+ passive_dns_lookup
48
+ when "ip"
49
+ passive_dns_lookup
50
+ when "mail"
51
+ reverse_whois_lookup
52
+ when "hash"
53
+ ssl_lookup
54
+ else
55
+ raise ArgumentError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
56
+ end
57
+ rescue ::PassiveTotal::Error => _e
58
+ nil
59
+ end
60
+
61
+ def passive_dns_lookup
62
+ res = api.dns.passive_unique(query)
63
+ res.dig("results") || []
64
+ end
65
+
66
+ def reverse_whois_lookup
67
+ res = api.whois.search(query: query, field: "email")
68
+ results = res.dig("results") || []
69
+ results.map do |result|
70
+ result.dig("domain")
71
+ end.flatten.compact.uniq
72
+ end
73
+
74
+ def ssl_lookup
75
+ res = api.ssl.history(query)
76
+ results = res.dig("results") || []
77
+ results.map do |result|
78
+ result.dig("ipAddresses")
79
+ end.flatten.compact.uniq
80
+ end
81
+ end
82
+ end
83
+ end
@@ -5,21 +5,21 @@ require "securitytrails"
5
5
  module Mihari
6
6
  module Analyzers
7
7
  class SecurityTrails < Base
8
- attr_reader :indicator
8
+ attr_reader :query
9
9
  attr_reader :type
10
10
 
11
11
  attr_reader :title
12
12
  attr_reader :description
13
13
  attr_reader :tags
14
14
 
15
- def initialize(indicator, title: nil, description: nil, tags: [])
15
+ def initialize(query, title: nil, description: nil, tags: [])
16
16
  super()
17
17
 
18
- @indicator = indicator
19
- @type = TypeChecker.type(indicator)
18
+ @query = query
19
+ @type = TypeChecker.type(query)
20
20
 
21
21
  @title = title || "SecurityTrails lookup"
22
- @description = description || "indicator = #{indicator}"
22
+ @description = description || "query = #{query}"
23
23
  @tags = tags
24
24
  end
25
25
 
@@ -29,12 +29,16 @@ module Mihari
29
29
 
30
30
  private
31
31
 
32
+ def config_keys
33
+ %w(SECURITYTRAILS_API_KEY)
34
+ end
35
+
32
36
  def api
33
37
  @api ||= ::SecurityTrails::API.new
34
38
  end
35
39
 
36
40
  def valid_type?
37
- %w(ip domain).include? type
41
+ %w(ip domain mail).include? type
38
42
  end
39
43
 
40
44
  def lookup
@@ -43,28 +47,33 @@ module Mihari
43
47
  domain_lookup
44
48
  when "ip"
45
49
  ip_lookup
50
+ when "mail"
51
+ mail_lookup
46
52
  else
47
- raise ArgumentError, "#{indicator}(type: #{type || 'unknown'}) is not supported." unless valid_type?
53
+ raise ArgumentError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
48
54
  end
49
55
  rescue ::SecurityTrails::Error => _e
50
56
  nil
51
57
  end
52
58
 
53
59
  def domain_lookup
54
- result = api.history.get_all_dns_history(indicator, "a").to_h
55
- records = result.dig(:records) || []
60
+ result = api.history.get_all_dns_history(query, "a")
61
+ records = result.records || []
56
62
  records.map do |record|
57
- values = record.dig(:values) || []
58
- values.map { |value| value.dig(:ip) }
59
- end.compact.flatten.uniq
63
+ (record.values || []).map(&:ip)
64
+ end.flatten.compact.uniq
60
65
  end
61
66
 
62
67
  def ip_lookup
63
- result = api.domains.search( filter: { ipv4: indicator }).to_h
64
- records = result.dig(:records) || []
65
- records.map do |record|
66
- record.dig(:hostname)
67
- end.compact.uniq
68
+ result = api.domains.search( filter: { ipv4: query })
69
+ records = result.records || []
70
+ records.map(&:hostname).compact.uniq
71
+ end
72
+
73
+ def mail_lookup
74
+ result = api.domains.search( filter: { whois_email: query })
75
+ records = result.records || []
76
+ records.map(&:hostname).compact.uniq
68
77
  end
69
78
  end
70
79
  end
@@ -31,6 +31,10 @@ module Mihari
31
31
 
32
32
  private
33
33
 
34
+ def config_keys
35
+ %w(SECURITYTRAILS_API_KEY)
36
+ end
37
+
34
38
  def api
35
39
  @api ||= ::SecurityTrails::API.new
36
40
  end
@@ -31,6 +31,10 @@ module Mihari
31
31
 
32
32
  private
33
33
 
34
+ def config_keys
35
+ %w(SHODAN_API_KEY)
36
+ end
37
+
34
38
  def api
35
39
  @api ||= ::Shodan::API.new
36
40
  end
@@ -29,6 +29,10 @@ module Mihari
29
29
 
30
30
  private
31
31
 
32
+ def config_keys
33
+ %w(VIRUSTOTAL_API_KEY)
34
+ end
35
+
32
36
  def api
33
37
  @api = ::VirusTotal::API.new
34
38
  end
@@ -56,7 +56,7 @@ module Mihari
56
56
  end
57
57
  end
58
58
 
59
- desc "securitytrails [IP|DOMAIN]", "SecurityTrails resolutions lookup by a given ip or domain"
59
+ desc "securitytrails [IP|DOMAIN|EMAIL]", "SecurityTrails lookup by a given ip, domain or email"
60
60
  method_option :title, type: :string, desc: "title"
61
61
  method_option :description, type: :string, desc: "description"
62
62
  method_option :tags, type: :array, desc: "tags"
@@ -109,6 +109,16 @@ module Mihari
109
109
  end
110
110
  end
111
111
 
112
+ desc "passivetotal [IP|DOMAIN|EMAIL|SHA1]", "PassiveTotal lookup by a given ip / domain / email / SHA1 certificate fingerprint"
113
+ method_option :title, type: :string, desc: "title"
114
+ method_option :description, type: :string, desc: "description"
115
+ method_option :tags, type: :array, desc: "tags"
116
+ def passivetotal(query)
117
+ with_error_handling do
118
+ run_analyzer Analyzers::PassiveTotal, query: query, options: options
119
+ end
120
+ end
121
+
112
122
  desc "import_from_json", "Give a JSON input via STDIN"
113
123
  def import_from_json(input = nil)
114
124
  with_error_handling do
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Configurable
5
+ def configured?
6
+ config_keys.all? { |key| ENV.key? key }
7
+ end
8
+
9
+ def configuration_status
10
+ return nil if config_keys.empty?
11
+
12
+ names = config_keys.join(" and ")
13
+ be_verb = config_keys.length == 1 ? "is" : "are"
14
+ status = configured? ? "found" : "missing"
15
+ "#{names} #{be_verb} #{status}"
16
+ end
17
+
18
+ def config_keys
19
+ []
20
+ end
21
+ end
22
+ end
@@ -3,6 +3,8 @@
3
3
  module Mihari
4
4
  module Emitters
5
5
  class Base
6
+ include Configurable
7
+
6
8
  def self.inherited(child)
7
9
  Mihari.emitters << child
8
10
  end
@@ -27,6 +27,10 @@ module Mihari
27
27
 
28
28
  private
29
29
 
30
+ def config_keys
31
+ %w(MISP_API_ENDPOINT MISP_API_KEY)
32
+ end
33
+
30
34
  def build_attribute(artifact)
31
35
  ::MISP::Attribute.new(value: artifact.data, type: to_misp_type(type: artifact.data_type, value: artifact.data))
32
36
  end
@@ -122,6 +122,12 @@ module Mihari
122
122
 
123
123
  notifier.notify(text: text, attachments: attachments)
124
124
  end
125
+
126
+ private
127
+
128
+ def config_keys
129
+ %w(SLACK_WEBHOOK_URL)
130
+ end
125
131
  end
126
132
  end
127
133
  end
@@ -3,13 +3,6 @@
3
3
  module Mihari
4
4
  module Emitters
5
5
  class TheHive < Base
6
- attr_reader :the_hive
7
-
8
- def initialize
9
- @the_hive = Mihari::TheHive.new
10
- @cache = Cache.new
11
- end
12
-
13
6
  # @return [true, false]
14
7
  def valid?
15
8
  the_hive.valid?
@@ -30,8 +23,20 @@ module Mihari
30
23
 
31
24
  private
32
25
 
26
+ def config_keys
27
+ %w(THEHIVE_API_ENDPOINT THEHIVE_API_KEY)
28
+ end
29
+
30
+ def the_hive
31
+ @the_hive ||= Mihari::TheHive.new
32
+ end
33
+
34
+ def cache
35
+ @cache ||= Cache.new
36
+ end
37
+
33
38
  def save_as_cache(data)
34
- @cache.save data
39
+ cache.save data
35
40
  end
36
41
  end
37
42
  end
@@ -3,16 +3,7 @@
3
3
  module Mihari
4
4
  class Status
5
5
  def check
6
- {
7
- censys: { status: censys?, message: censys },
8
- misp: { status: misp?, message: misp },
9
- onyphe: { status: onyphe?, message: onyphe },
10
- securitytrails: { status: securitytrails?, message: securitytrails },
11
- shodan: { status: shodan?, message: shodan },
12
- slack: { status: slack?, message: slack },
13
- the_hive: { status: the_hive?, message: the_hive },
14
- virustotal: { status: virustotal?, message: virustotal },
15
- }.map do |key, value|
6
+ statuses.map do |key, value|
16
7
  [key, convert(value)]
17
8
  end.to_h
18
9
  end
@@ -30,68 +21,24 @@ module Mihari
30
21
  }
31
22
  end
32
23
 
33
- def securitytrails?
34
- ENV.key? "SECURITYTRAILS_API_KEY"
35
- end
36
-
37
- def securitytrails
38
- securitytrails? ? "SECURITYTRAILS_API_KEY is found" : "SECURITYTRAILS_API_KEY is missing"
39
- end
40
-
41
- def virustotal?
42
- ENV.key?("VIRUSTOTAL_API_KEY")
43
- end
44
-
45
- def virustotal
46
- virustotal? ? "VIRUSTOTAL_API_KEY is found" : "VIRUSTOTAL_API_KEY is missing"
47
- end
48
-
49
- def onyphe?
50
- ENV.key? "ONYPHE_API_KEY"
51
- end
52
-
53
- def onyphe
54
- onyphe? ? "ONYPHE_API_KEY is found" : "ONYPHE_API_KEY is missing"
55
- end
56
-
57
- def censys?
58
- ENV.key?("CENSYS_ID") && ENV.key?("CENSYS_SECRET")
59
- end
60
-
61
- def censys
62
- censys? ? "CENSYS_ID and CENSYS_SECRET are found" : "CENSYS_ID and CENSYS_SECRET are missing"
63
- end
24
+ def statuses
25
+ (Mihari.analyzers + Mihari.emitters).map do |klass|
26
+ name = klass.to_s.downcase.split("::").last.to_s
64
27
 
65
- def shodan?
66
- ENV.key? "SHODAN_API_KEY"
28
+ [name, build_status(klass)]
29
+ end.to_h.compact
67
30
  end
68
31
 
69
- def shodan
70
- shodan? ? "SHODAN_API_KEY is found" : "SHODAN_API_KEY is missing"
71
- end
32
+ def build_status(klass)
33
+ is_analyzer = klass.ancestors.include?(Mihari::Analyzers::Base)
72
34
 
73
- def slack?
74
- ENV.key? "SLACK_WEBHOOK_URL"
75
- end
76
-
77
- def slack
78
- slack? ? "SLACK_WEBHOOK_URL is found" : "SLACK_WEBHOOK_URL is missing"
79
- end
80
-
81
- def the_hive?
82
- ENV.key?("THEHIVE_API_ENDPOINT") && ENV.key?("THEHIVE_API_KEY")
83
- end
84
-
85
- def the_hive
86
- the_hive? ? "THEHIVE_API_ENDPOINT and THEHIVE_API_KEY are found" : "THEHIVE_API_ENDPOINT and THEHIVE_API_KEY are are missing"
87
- end
88
-
89
- def misp?
90
- ENV.key?("MISP_API_ENDPOINT") && ENV.key?("MISP_API_KEY")
91
- end
35
+ instance = is_analyzer ? klass.new("dummy") : klass.new
36
+ status = instance.configured?
37
+ message = instance.configuration_status
92
38
 
93
- def misp
94
- misp? ? "MISP_API_ENDPOINT and MISP_API_KEY are found" : "MISP_API_ENDPOINT and MISP_API_KEY are are missing"
39
+ message ? { status: status, message: message } : nil
40
+ rescue ArgumentError => _e
41
+ nil
95
42
  end
96
43
  end
97
44
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
5
5
  end
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "bundler", "~> 2.0"
28
28
  spec.add_development_dependency "coveralls", "~> 0.8"
29
29
  spec.add_development_dependency "fakefs", "~> 0.20"
30
- spec.add_development_dependency "rake", "~> 12.3"
30
+ spec.add_development_dependency "rake", "~> 13.0"
31
31
  spec.add_development_dependency "rspec", "~> 3.8"
32
32
  spec.add_development_dependency "timecop", "~> 0.9"
33
33
  spec.add_development_dependency "vcr", "~> 5.0"
@@ -44,8 +44,9 @@ Gem::Specification.new do |spec|
44
44
  spec.add_dependency "misp", "~> 0.1"
45
45
  spec.add_dependency "net-ping", "~> 2.0"
46
46
  spec.add_dependency "onyphe", "~> 0.2"
47
- spec.add_dependency "parallel", "~> 1.17"
47
+ spec.add_dependency "parallel", "~> 1.18"
48
48
  spec.add_dependency "passive_circl", "~> 0.1"
49
+ spec.add_dependency "passivetotalx", "~> 0.1"
49
50
  spec.add_dependency "public_suffix", "~> 4.0"
50
51
  spec.add_dependency "securitytrails", "~> 0.2"
51
52
  spec.add_dependency "shodanx", "~> 0.2"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mihari
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '12.3'
61
+ version: '13.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '12.3'
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -282,14 +282,14 @@ dependencies:
282
282
  requirements:
283
283
  - - "~>"
284
284
  - !ruby/object:Gem::Version
285
- version: '1.17'
285
+ version: '1.18'
286
286
  type: :runtime
287
287
  prerelease: false
288
288
  version_requirements: !ruby/object:Gem::Requirement
289
289
  requirements:
290
290
  - - "~>"
291
291
  - !ruby/object:Gem::Version
292
- version: '1.17'
292
+ version: '1.18'
293
293
  - !ruby/object:Gem::Dependency
294
294
  name: passive_circl
295
295
  requirement: !ruby/object:Gem::Requirement
@@ -304,6 +304,20 @@ dependencies:
304
304
  - - "~>"
305
305
  - !ruby/object:Gem::Version
306
306
  version: '0.1'
307
+ - !ruby/object:Gem::Dependency
308
+ name: passivetotalx
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - "~>"
312
+ - !ruby/object:Gem::Version
313
+ version: '0.1'
314
+ type: :runtime
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '0.1'
307
321
  - !ruby/object:Gem::Dependency
308
322
  name: public_suffix
309
323
  requirement: !ruby/object:Gem::Requirement
@@ -431,6 +445,7 @@ files:
431
445
  - lib/mihari/analyzers/crtsh.rb
432
446
  - lib/mihari/analyzers/dnpedia.rb
433
447
  - lib/mihari/analyzers/onyphe.rb
448
+ - lib/mihari/analyzers/passivetotal.rb
434
449
  - lib/mihari/analyzers/securitytrails.rb
435
450
  - lib/mihari/analyzers/securitytrails_domain_feed.rb
436
451
  - lib/mihari/analyzers/shodan.rb
@@ -439,6 +454,7 @@ files:
439
454
  - lib/mihari/artifact.rb
440
455
  - lib/mihari/cache.rb
441
456
  - lib/mihari/cli.rb
457
+ - lib/mihari/configurable.rb
442
458
  - lib/mihari/emitters/base.rb
443
459
  - lib/mihari/emitters/misp.rb
444
460
  - lib/mihari/emitters/slack.rb
@@ -479,7 +495,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
479
495
  - !ruby/object:Gem::Version
480
496
  version: '0'
481
497
  requirements: []
482
- rubygems_version: 3.0.4
498
+ rubygems_version: 3.0.6
483
499
  signing_key:
484
500
  specification_version: 4
485
501
  summary: A framework for continuous malicious hosts monitoring.