mihari 0.10.0 → 0.11.0

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