mihari 0.17.0 → 0.17.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: 0a5030ba15be3b81b4a71d9f38f3a0305d023dcddb3121e0c700a0cb82f1dcd9
4
- data.tar.gz: fc4f48e49a363550d165367e7aba0e3802535f3b13bcb32304d71a82eab256c7
3
+ metadata.gz: e28756adc591b441b67579ca8e4a0e7fcaadc1cf332a3c9e57e01438c19d6554
4
+ data.tar.gz: 0c9bf23eb782882354b6332878a41168293b4957724a27b2beab077f3caf3256
5
5
  SHA512:
6
- metadata.gz: 79487f0a7350c6299d159a32d7bc9655ac76934c2f2d224b059de59f128c18c4b23725269687cc3bd777d111c7245100f0b735d7011be997fc1bfed293b9f7b1
7
- data.tar.gz: 3071b839707180910cd1286041696b9f6b768abff4bb6e9a724ce553945118edb26784c70c848f0f5f888e1be7854c9e0b6d6a1645c8019d726926c10bda065f
6
+ metadata.gz: a91dc83d7a9988df7aff4b1ad90029c67223dfa717354a4c00fcba40e01b409ff77aba4c07969cc767dafa4d89bc6a5d9af807099665245ff0a578f3df4ae6cd
7
+ data.tar.gz: 34d6cc2546ce6b9e1a0b5918ec2a14dcf3f8f692222d950a7c27a7f28206308f78c0c40c66487108e5bcedfd70b25bbc9fa9f478862bf390aa041249ab3d31a9
@@ -4,4 +4,4 @@ language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
6
  - 2.6
7
- before_install: gem install bundler -v 2.0.1
7
+ before_install: gem install bundler -v 2.1
data/README.md CHANGED
@@ -6,22 +6,22 @@
6
6
  [![Coverage Status](https://coveralls.io/repos/github/ninoseki/mihari/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/mihari?branch=master)
7
7
  [![CodeFactor](https://www.codefactor.io/repository/github/ninoseki/mihari/badge)](https://www.codefactor.io/repository/github/ninoseki/mihari)
8
8
 
9
- mihari(`見張り`) is a sidekick tool for [TheHive](https://github.com/TheHive-Project/TheHive) for monitoring malicious hosts (C2 / landing page / phishing, etc.) continuously.
9
+ Mihari is a sidekick tool for [TheHive](https://github.com/TheHive-Project/TheHive) for monitoring malicious hosts (C2 / landing page / phishing, etc.) continuously.
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 results.
14
- - mihari checks whether TheHive 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 on TheHive.
17
- - mihari sends a notification to Slack. (Optional)
18
- - mihari creates an event on MISP. (Optional)
16
+ - Mihari creates an alert on TheHive.
17
+ - Mihari sends a notification to Slack. (Optional)
18
+ - Mihari creates an event on MISP. (Optional)
19
19
 
20
20
  ![img](https://github.com/ninoseki/mihari/raw/master/screenshots/eyecatch.png)
21
21
 
22
22
  Check this blog post for more details: [Continuous C2 hunting with Censys, Shodan, Onyphe and TheHive](https://hackmd.io/s/SkUaSrqoE).
23
23
 
24
- You can use mihari without TheHive. But note that mihari depends on TheHive to manage artifacts. It means mihari might make duplications when without TheHive.
24
+ You can use mihari without TheHive but note that mihari depends on TheHive to manage artifacts. It means mihari might make duplications when without TheHive.
25
25
 
26
26
  ### Screenshots
27
27
 
@@ -51,7 +51,7 @@ docker pull ninoseki/mihari
51
51
 
52
52
  ## Basic usage
53
53
 
54
- mihari supports the following services by default.
54
+ Mihari supports the following services by default.
55
55
 
56
56
  - [BinaryEdge](https://www.binaryedge.io/)
57
57
  - [Censys](http://censys.io)
@@ -96,11 +96,14 @@ Commands:
96
96
  mihari virustotal [IP|DOMAIN] # VirusTotal resolutions lookup by an ip or domain
97
97
  mihari zoomeye [QUERY] # ZoomEye search by a query
98
98
 
99
+ Options:
100
+ [--config=CONFIG] # path to config file
101
+
99
102
  ```
100
103
 
101
104
  ### Cross searches
102
105
 
103
- mihari has cross search features. A cross search is a search across a number of services.
106
+ Mihari has cross search features. A cross search is a search across a number of services.
104
107
 
105
108
  You can get aggregated results by using the following commands.
106
109
 
@@ -224,7 +227,7 @@ The input is a JSON data should have `title`, `description` and `artifacts` key.
224
227
 
225
228
  ## Configuration
226
229
 
227
- All configuration is done via ENV variables.
230
+ Configuration can be done via environment variables or a YAML file.
228
231
 
229
232
  | Key | Desc. | Required or optional |
230
233
  |------------------------|--------------------------------|--------------------------------|
@@ -249,6 +252,20 @@ All configuration is done via ENV variables.
249
252
  | ZOOMEYE_USERNAMME | ZoomEye username | Optional |
250
253
  | ZOOMEYE_PASSWORD | ZoomEye password | Optional |
251
254
 
255
+ Instead of using environment variables, you can use a YAML file for configuration.
256
+
257
+ ```bash
258
+ mihari virustotal 1.1.1.1 --config /path/to/yaml.yml
259
+ ```
260
+
261
+ The YAML file should be a hash like below:
262
+
263
+ ```yaml
264
+ thehive_api_endpoint: https://localhost
265
+ thehive_api_key: foo
266
+ virustotal_api_key: foo
267
+ ```
268
+
252
269
  You can check the configuration status via `status` command.
253
270
 
254
271
  ```bash
@@ -299,7 +316,7 @@ See `/examples` for more.
299
316
 
300
317
  ## Caching
301
318
 
302
- mihari caches execution results in `/tmp/mihari` and the default cache duration is 7 days. If you want to clear the cache, please clear `/tmp/mihari`.
319
+ Mihari caches execution results in `/tmp/mihari` and the default cache duration is 7 days. If you want to clear the cache, please clear `/tmp/mihari`.
303
320
 
304
321
  ## Using it with Docker
305
322
 
@@ -24,6 +24,7 @@ require "mihari/errors"
24
24
 
25
25
  require "mihari/artifact"
26
26
  require "mihari/cache"
27
+ require "mihari/config"
27
28
  require "mihari/type_checker"
28
29
 
29
30
  require "mihari/html"
@@ -43,8 +43,6 @@ module Mihari
43
43
  else
44
44
  raise InvalidInputError, "#{@query}(type: #{@type || 'unknown'}) is not supported."
45
45
  end
46
- rescue ::PassiveCIRCL::Error => _e
47
- nil
48
46
  end
49
47
 
50
48
  def passive_dns_lookup
@@ -35,8 +35,6 @@ module Mihari
35
35
  rows.map do |row|
36
36
  [row.dig("name"), row.dig("zoneid")].join(".")
37
37
  end
38
- rescue ::DNPedia::Error => _e
39
- nil
40
38
  end
41
39
  end
42
40
  end
@@ -55,8 +55,6 @@ module Mihari
55
55
  Parallel.map(domains) do |domain|
56
56
  resolvable?(domain) ? domain : nil
57
57
  end.compact
58
- rescue ::DNSTwister::Error => _e
59
- nil
60
58
  end
61
59
  end
62
60
  end
@@ -54,8 +54,6 @@ module Mihari
54
54
  else
55
55
  raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
56
56
  end
57
- rescue ::PassiveTotal::Error => _e
58
- nil
59
57
  end
60
58
 
61
59
  def passive_dns_lookup
@@ -51,8 +51,6 @@ module Mihari
51
51
  (properties.dig("dns") || []).map do |property|
52
52
  property.dig("value") if ["A", "PTR"].include?(property.dig("name"))
53
53
  end.compact
54
- rescue ::Pulsedive::ResponseError => _e
55
- nil
56
54
  end
57
55
  end
58
56
  end
@@ -52,8 +52,6 @@ module Mihari
52
52
  else
53
53
  raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
54
54
  end
55
- rescue ::SecurityTrails::Error => _e
56
- nil
57
55
  end
58
56
 
59
57
  def domain_lookup
@@ -53,8 +53,6 @@ module Mihari
53
53
  new_domains.select do |domain|
54
54
  regexp.match? domain
55
55
  end
56
- rescue ::SecurityTrails::Error => _e
57
- nil
58
56
  end
59
57
 
60
58
  def new_domains
@@ -45,8 +45,6 @@ module Mihari
45
45
 
46
46
  def search_with_page(query, page: 1)
47
47
  api.host.search(query, page: page)
48
- rescue ::Shodan::Error => _e
49
- nil
50
48
  end
51
49
 
52
50
  def search
@@ -41,8 +41,6 @@ module Mihari
41
41
 
42
42
  def search
43
43
  api.search(query, size: 10_000)
44
- rescue ::UrlScan::ResponseError => _e
45
- nil
46
44
  end
47
45
 
48
46
  def valid_target_type?
@@ -50,16 +50,10 @@ module Mihari
50
50
  else
51
51
  raise InvalidInputError, "#{indicator}(type: #{type || 'unknown'}) is not supported." unless valid_type?
52
52
  end
53
- rescue ::VirusTotal::Error => _e
54
- nil
55
53
  end
56
54
 
57
55
  def domain_lookup
58
- begin
59
- res = api.domain.resolutions(indicator)
60
- rescue ::VirusTotal::Error => _e
61
- return nil
62
- end
56
+ res = api.domain.resolutions(indicator)
63
57
 
64
58
  data = res.dig("data") || []
65
59
  data.map do |item|
@@ -68,11 +62,7 @@ module Mihari
68
62
  end
69
63
 
70
64
  def ip_lookup
71
- begin
72
- res = api.ip_address.resolutions(indicator)
73
- rescue ::VirusTotal::Error => _e
74
- return nil
75
- end
65
+ res = api.ip_address.resolutions(indicator)
76
66
 
77
67
  data = res.dig("data") || []
78
68
  data.map do |item|
@@ -5,6 +5,8 @@ require "json"
5
5
 
6
6
  module Mihari
7
7
  class CLI < Thor
8
+ class_option :config, type: :string, desc: "path to config file"
9
+
8
10
  desc "censys [QUERY]", "Censys IPv4 search by a query"
9
11
  method_option :title, type: :string, desc: "title"
10
12
  method_option :description, type: :string, desc: "description"
@@ -280,15 +282,29 @@ module Mihari
280
282
  %w(title description artifacts).all? { |key| json.key? key }
281
283
  end
282
284
 
285
+ def load_configuration
286
+ config = options["config"]
287
+ Config.load_from_yaml(config) if config
288
+ end
289
+
283
290
  def run_analyzer(analyzer_class, query:, options:)
291
+ load_configuration
292
+
284
293
  options = symbolize_hash_keys(options)
294
+ options = normalize_options(options)
285
295
 
286
296
  analyzer = analyzer_class.new(query, **options)
287
297
  analyzer.run
288
298
  end
289
299
 
290
300
  def symbolize_hash_keys(hash)
291
- hash.map{ |k, v| [k.to_sym, v] }.to_h
301
+ hash.map { |k, v| [k.to_sym, v] }.to_h
302
+ end
303
+
304
+ def normalize_options(options)
305
+ # Delete :config because it is not intended to use for running an analyzer
306
+ options.delete(:config)
307
+ options
292
308
  end
293
309
 
294
310
  def refang(indicator)
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Mihari
6
+ class Config
7
+ class << self
8
+ def load_from_yaml(path)
9
+ raise ArgumentError, "#{path} does not exist." unless File.exist?(path)
10
+
11
+ data = File.read(path)
12
+ begin
13
+ yaml = YAML.safe_load(data)
14
+ rescue TypeError => _e
15
+ return
16
+ end
17
+
18
+ yaml.each do |key, value|
19
+ ENV[key.upcase] = value
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "0.17.0"
4
+ VERSION = "0.17.1"
5
5
  end
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_development_dependency "bundler", "~> 2.0"
27
+ spec.add_development_dependency "bundler", "~> 2.1"
28
28
  spec.add_development_dependency "coveralls", "~> 0.8"
29
29
  spec.add_development_dependency "fakefs", "~> 0.20"
30
30
  spec.add_development_dependency "rake", "~> 13.0"
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_dependency "misp", "~> 0.1"
47
47
  spec.add_dependency "murmurhash3", "~> 0.1"
48
48
  spec.add_dependency "net-ping", "~> 2.0"
49
- spec.add_dependency "onyphe", "~> 1.0"
49
+ spec.add_dependency "onyphe", "~> 1.1"
50
50
  spec.add_dependency "parallel", "~> 1.19"
51
51
  spec.add_dependency "passive_circl", "~> 0.1"
52
52
  spec.add_dependency "passivetotalx", "~> 0.1"
@@ -55,8 +55,8 @@ Gem::Specification.new do |spec|
55
55
  spec.add_dependency "securitytrails", "~> 1.0"
56
56
  spec.add_dependency "shodanx", "~> 0.2"
57
57
  spec.add_dependency "slack-notifier", "~> 2.3"
58
- spec.add_dependency "thor", "~> 0.20"
59
- spec.add_dependency "urlscan", "~> 0.4"
58
+ spec.add_dependency "thor", "~> 1.0"
59
+ spec.add_dependency "urlscan", "~> 0.5"
60
60
  spec.add_dependency "virustotalx", "~> 1.1"
61
61
  spec.add_dependency "zoomeye-rb", "~> 0.1"
62
62
  end
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.17.0
4
+ version: 0.17.1
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-12-11 00:00:00.000000000 Z
11
+ date: 2019-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: coveralls
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -310,14 +310,14 @@ dependencies:
310
310
  requirements:
311
311
  - - "~>"
312
312
  - !ruby/object:Gem::Version
313
- version: '1.0'
313
+ version: '1.1'
314
314
  type: :runtime
315
315
  prerelease: false
316
316
  version_requirements: !ruby/object:Gem::Requirement
317
317
  requirements:
318
318
  - - "~>"
319
319
  - !ruby/object:Gem::Version
320
- version: '1.0'
320
+ version: '1.1'
321
321
  - !ruby/object:Gem::Dependency
322
322
  name: parallel
323
323
  requirement: !ruby/object:Gem::Requirement
@@ -436,28 +436,28 @@ dependencies:
436
436
  requirements:
437
437
  - - "~>"
438
438
  - !ruby/object:Gem::Version
439
- version: '0.20'
439
+ version: '1.0'
440
440
  type: :runtime
441
441
  prerelease: false
442
442
  version_requirements: !ruby/object:Gem::Requirement
443
443
  requirements:
444
444
  - - "~>"
445
445
  - !ruby/object:Gem::Version
446
- version: '0.20'
446
+ version: '1.0'
447
447
  - !ruby/object:Gem::Dependency
448
448
  name: urlscan
449
449
  requirement: !ruby/object:Gem::Requirement
450
450
  requirements:
451
451
  - - "~>"
452
452
  - !ruby/object:Gem::Version
453
- version: '0.4'
453
+ version: '0.5'
454
454
  type: :runtime
455
455
  prerelease: false
456
456
  version_requirements: !ruby/object:Gem::Requirement
457
457
  requirements:
458
458
  - - "~>"
459
459
  - !ruby/object:Gem::Version
460
- version: '0.4'
460
+ version: '0.5'
461
461
  - !ruby/object:Gem::Dependency
462
462
  name: virustotalx
463
463
  requirement: !ruby/object:Gem::Requirement
@@ -534,6 +534,7 @@ files:
534
534
  - lib/mihari/artifact.rb
535
535
  - lib/mihari/cache.rb
536
536
  - lib/mihari/cli.rb
537
+ - lib/mihari/config.rb
537
538
  - lib/mihari/configurable.rb
538
539
  - lib/mihari/emitters/base.rb
539
540
  - lib/mihari/emitters/misp.rb