mihari 1.0.1 → 1.1.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: 44cc5eea0746aa47918f5102cf4834fcd436b67f371b37f8a1e4fe6999902c82
4
- data.tar.gz: e0dd701f1d5b705239d73125ca8865fa15c949d4b62cb59a2c9beef8e01e363d
3
+ metadata.gz: 46761bb6c390e76763b5b76c711cd222a08735bb3e539862bb2cac211d44bfc3
4
+ data.tar.gz: 19cdc765f98da35dd299038ce8f310ce30cd4a7903a2c56344e97631fdf32f87
5
5
  SHA512:
6
- metadata.gz: 36722428cc688eaefd3f293f1de99db20b8671945082b1d5f1d08d61c9b977491e46f45122311010650d80b1f0077dd7ec9323e304c02fdcf9c4fc1b22c66672
7
- data.tar.gz: ad9e0603040bc4069194df7f21c0963e096beaa3e6e2ac13ea0d66803217619b885f3afef4624c0c45ae4282c64f8bda905bf61d8c564f9aef8c7a5b33bb2dca
6
+ metadata.gz: eda0f8f7537c6a9a456c225545bc615d3573f4789ce9b411faf3fc83cf155417adac87bd043e605303874199d24395f2a71e06275cae5909b9e2fb95221e4651
7
+ data.tar.gz: 38a9250b72efb654b1e8c10904077f205838a7d61742f3e545cef26d3703a161c60b77c1459ee10fd0d2fa814e1b234663fd13132cc2d406833aaf6d51519de8
data/.travis.yml CHANGED
@@ -1,8 +1,13 @@
1
1
  ---
2
- sudo: false
3
2
  language: ruby
4
3
  cache: bundler
4
+ services:
5
+ - postgresql
5
6
  rvm:
6
7
  - 2.6
7
8
  - 2.7
9
+ env:
10
+ - DATABASE=":memory:"
11
+ - DATABASE="postgresql://postgres@0.0.0.0:5432/travis_ci_test"
8
12
  before_install: gem install bundler -v 2.1
13
+ before_script: psql -c 'create database travis_ci_test;' -U postgres
data/README.md CHANGED
@@ -11,7 +11,7 @@ Mihari is a helper to run queries & manage results continuously. Mihari can be u
11
11
  ## How it works
12
12
 
13
13
  - Mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts (IP addresses, domains, URLs and hashes) from the results.
14
- - Mihari checks whether a DB (SQLite3) contains the artifacts or not.
14
+ - Mihari checks whether a DB (SQLite3 or PostgreSQL) contains the artifacts or not.
15
15
  - If it doesn't contain the artifacts:
16
16
  - Mihari creates an alert on TheHive. (Optional)
17
17
  - Mihari sends a notification to Slack. (Optional)
@@ -189,29 +189,29 @@ The input is a JSON data should have `title`, `description` and `artifacts` key.
189
189
 
190
190
  Configuration can be done via environment variables or a YAML file.
191
191
 
192
- | Key | Description | Default |
193
- |------------------------|--------------------------------|-------------|
194
- | DATABASE | A path to the SQLite database | `mihari.db` |
195
- | BINARYEDGE_API_KEY | BinaryEdge API key | |
196
- | CENSYS_ID | Censys API ID | |
197
- | CENSYS_SECRET | Censys secret | |
198
- | CIRCL_PASSIVE_PASSWORD | CIRCL passive DNS/SSL password | |
199
- | CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username | |
200
- | MISP_API_ENDPOINT | MISP URL | |
201
- | MISP_API_KEY | MISP API key | |
202
- | ONYPHE_API_KEY | Onyphe API key | |
203
- | PASSIVETOTAL_API_KEY | PassiveTotal API key | |
204
- | PASSIVETOTAL_USERNAME | PassiveTotal username | |
205
- | PULSEDIVE_API_KEY | Pulsedive API key | |
206
- | SECURITYTRAILS_API_KEY | SecurityTrails API key | |
207
- | SHODAN_API_KEY | Shodan API key | |
208
- | SLACK_CHANNEL | Slack channel name | `#general` |
209
- | SLACK_WEBHOOK_URL | Slack Webhook URL | |
210
- | THEHIVE_API_ENDPOINT | TheHive URL | |
211
- | THEHIVE_API_KEY | TheHive API key | |
212
- | VIRUSTOTAL_API_KEY | VirusTotal API key | |
213
- | ZOOMEYE_PASSWORD | ZoomEye password | |
214
- | ZOOMEYE_USERNAMME | ZoomEye username | |
192
+ | Key | Description | Default |
193
+ |------------------------|-------------------------------------------------------------------------------------------------|-------------|
194
+ | DATABASE | A path to the SQLite database or a DB URL (e.g. `postgres://postgres:pass@db.host:5432/somedb`) | `mihari.db` |
195
+ | BINARYEDGE_API_KEY | BinaryEdge API key | |
196
+ | CENSYS_ID | Censys API ID | |
197
+ | CENSYS_SECRET | Censys secret | |
198
+ | CIRCL_PASSIVE_PASSWORD | CIRCL passive DNS/SSL password | |
199
+ | CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username | |
200
+ | MISP_API_ENDPOINT | MISP URL | |
201
+ | MISP_API_KEY | MISP API key | |
202
+ | ONYPHE_API_KEY | Onyphe API key | |
203
+ | PASSIVETOTAL_API_KEY | PassiveTotal API key | |
204
+ | PASSIVETOTAL_USERNAME | PassiveTotal username | |
205
+ | PULSEDIVE_API_KEY | Pulsedive API key | |
206
+ | SECURITYTRAILS_API_KEY | SecurityTrails API key | |
207
+ | SHODAN_API_KEY | Shodan API key | |
208
+ | SLACK_CHANNEL | Slack channel name | `#general` |
209
+ | SLACK_WEBHOOK_URL | Slack Webhook URL | |
210
+ | THEHIVE_API_ENDPOINT | TheHive URL | |
211
+ | THEHIVE_API_KEY | TheHive API key | |
212
+ | VIRUSTOTAL_API_KEY | VirusTotal API key | |
213
+ | ZOOMEYE_PASSWORD | ZoomEye password | |
214
+ | ZOOMEYE_USERNAMME | ZoomEye username | |
215
215
 
216
216
  Instead of using environment variables, you can use a YAML file for configuration.
217
217
 
data/docker/Dockerfile CHANGED
@@ -1,12 +1,12 @@
1
1
  FROM ruby:2.6-alpine3.10
2
- RUN apk --no-cache add git build-base ruby-dev \
2
+ RUN apk --no-cache add git build-base ruby-dev sqlite-dev postgresql-dev \
3
3
  && cd /tmp/ \
4
4
  && git clone https://github.com/ninoseki/mihari.git \
5
5
  && cd mihari \
6
6
  && gem build mihari.gemspec -o mihari.gem \
7
7
  && gem install mihari.gem \
8
8
  && rm -rf /tmp/mihari \
9
- && apk del --purge git build-base ruby-dev
9
+ && apk del --purge git build-base ruby-dev sqlite-dev postgresql-dev
10
10
 
11
11
  ENTRYPOINT ["mihari"]
12
12
 
data/lib/mihari.rb CHANGED
@@ -71,9 +71,9 @@ require "mihari/notifiers/slack"
71
71
  require "mihari/notifiers/exception_notifier"
72
72
 
73
73
  require "mihari/emitters/base"
74
+ require "mihari/emitters/database"
74
75
  require "mihari/emitters/misp"
75
76
  require "mihari/emitters/slack"
76
- require "mihari/emitters/sqlite"
77
77
  require "mihari/emitters/stdout"
78
78
  require "mihari/emitters/the_hive"
79
79
 
@@ -2,17 +2,21 @@
2
2
 
3
3
  module Mihari
4
4
  class AlertViewer
5
- attr_reader :limit
5
+ def list(title: nil, source: nil, tag: nil, limit: 5)
6
+ limit = limit.to_i
7
+ raise ArgumentError, "limit should be bigger than zero" unless limit.positive?
6
8
 
7
- def initialize(limit: 5)
8
- @limit = limit.to_i
9
- raise ArgumentError, "limit should be bigger than zero" unless @limit.positive?
10
- end
9
+ relation = Alert.includes(:tags, :artifacts)
10
+ relation = relation.where(title: title) if title
11
+ relation = relation.where(source: source) if source
12
+ relation = relation.where(tags: { name: tag } ) if tag
11
13
 
12
- def list
13
- alerts = Alert.order(id: :desc).limit(limit).includes(:tags, :artifacts)
14
+ alerts = relation.limit(limit).order(id: :desc)
14
15
  alerts.map do |alert|
15
- AlertSerializer.new(alert).as_json
16
+ json = AlertSerializer.new(alert).as_json
17
+ json[:artifacts] = (json.dig(:artifacts) || []).map { |artifact_| artifact_.dig(:data) }
18
+ json[:tags] = (json.dig(:tags) || []).map { |tag_| tag_.dig(:name) }
19
+ json
16
20
  end
17
21
  end
18
22
  end
@@ -52,7 +52,7 @@ module Mihari
52
52
  end
53
53
 
54
54
  def config_keys
55
- [Mihari.config.binaryedge_api_key]
55
+ %w(binaryedge_api_key)
56
56
  end
57
57
 
58
58
  def api
@@ -86,7 +86,7 @@ module Mihari
86
86
  end
87
87
 
88
88
  def config_keys
89
- [Mihari.config.censys_id, Mihari.config.censys_secret]
89
+ %w(censys_id censys_secret)
90
90
  end
91
91
 
92
92
  def api
@@ -27,7 +27,7 @@ module Mihari
27
27
  private
28
28
 
29
29
  def config_keys
30
- [Mihari.config.circl_passive_password, Mihari.config.circl_passive_username]
30
+ %w(circl_passive_password circl_passive_username)
31
31
  end
32
32
 
33
33
  def api
@@ -35,7 +35,7 @@ module Mihari
35
35
  PAGE_SIZE = 10
36
36
 
37
37
  def config_keys
38
- [Mihari.config.onyphe_api_key]
38
+ %w(onyphe_api_key)
39
39
  end
40
40
 
41
41
  def api
@@ -30,7 +30,7 @@ module Mihari
30
30
  private
31
31
 
32
32
  def config_keys
33
- [Mihari.config.passivetotal_username, Mihari.config.passivetotal_api_key]
33
+ %w(passivetotal_username passivetotal_api_key)
34
34
  end
35
35
 
36
36
  def api
@@ -30,7 +30,7 @@ module Mihari
30
30
  private
31
31
 
32
32
  def config_keys
33
- [Mihari.config.pulsedive_api_key]
33
+ %w(pulsedive_api_key)
34
34
  end
35
35
 
36
36
  def api
@@ -30,7 +30,7 @@ module Mihari
30
30
  private
31
31
 
32
32
  def config_keys
33
- [Mihari.config.securitytrails_api_key]
33
+ %w(securitytrails_api_key)
34
34
  end
35
35
 
36
36
  def api
@@ -32,7 +32,7 @@ module Mihari
32
32
  private
33
33
 
34
34
  def config_keys
35
- [Mihari.config.securitytrails_api_key]
35
+ %w(securitytrails_api_key)
36
36
  end
37
37
 
38
38
  def api
@@ -36,7 +36,7 @@ module Mihari
36
36
  PAGE_SIZE = 100
37
37
 
38
38
  def config_keys
39
- [Mihari.config.shodan_api_key]
39
+ %w(shodan_api_key)
40
40
  end
41
41
 
42
42
  def api
@@ -30,7 +30,7 @@ module Mihari
30
30
  private
31
31
 
32
32
  def config_keys
33
- [Mihari.config.virustotal_api_key]
33
+ %w(virustotal_api_key)
34
34
  end
35
35
 
36
36
  def api
@@ -41,7 +41,7 @@ module Mihari
41
41
  end
42
42
 
43
43
  def config_keys
44
- [Mihari.config.zoomeye_password, Mihari.config.zoomeye_username]
44
+ %w(zoomeye_password zoomeye_username)
45
45
  end
46
46
 
47
47
  def api
data/lib/mihari/cli.rb CHANGED
@@ -249,10 +249,15 @@ module Mihari
249
249
 
250
250
  desc "alerts", "Show the alerts on TheHive"
251
251
  method_option :limit, type: :string, default: "5", desc: "Number of alerts to show (or 'all' to show all the alerts)"
252
+ method_option :title, type: :string, desc: "Title to filter"
253
+ method_option :source, type: :string, desc: "Source to filter"
254
+ method_option :tag, type: :string, desc: "Tag to filter"
252
255
  def alerts
253
256
  with_error_handling do
254
- viewer = AlertViewer.new(limit: options["limit"])
255
- alerts = viewer.list
257
+ load_configuration
258
+
259
+ viewer = AlertViewer.new
260
+ alerts = viewer.list(limit: options["limit"], title: options["title"], source: options["source"], tag: options[:tag])
256
261
  puts JSON.pretty_generate(alerts)
257
262
  end
258
263
  end
@@ -261,6 +266,7 @@ module Mihari
261
266
  def status
262
267
  with_error_handling do
263
268
  load_configuration
269
+
264
270
  puts JSON.pretty_generate(Status.check)
265
271
  end
266
272
  end
@@ -289,8 +295,7 @@ module Mihari
289
295
  return unless config
290
296
 
291
297
  Config.load_from_yaml(config)
292
- # reload database settings
293
- load File.expand_path("./database.rb", __dir__)
298
+ Database.connect
294
299
  end
295
300
 
296
301
  def run_analyzer(analyzer_class, query:, options:)
@@ -3,7 +3,7 @@
3
3
  module Mihari
4
4
  module Configurable
5
5
  def configured?
6
- config_keys.all? { |key| !key.nil? }
6
+ config_keys.all? { |key| Mihari.config.send(key) }
7
7
  end
8
8
 
9
9
  def configuration_status
@@ -2,11 +2,6 @@
2
2
 
3
3
  require "active_record"
4
4
 
5
- ActiveRecord::Base.establish_connection(
6
- adapter: "sqlite3",
7
- database: Mihari.config.database
8
- )
9
-
10
5
  class InitialSchema < ActiveRecord::Migration[6.0]
11
6
  def change
12
7
  create_table :tags, if_not_exists: true do |t|
@@ -37,9 +32,37 @@ class InitialSchema < ActiveRecord::Migration[6.0]
37
32
  end
38
33
  end
39
34
 
40
- begin
41
- ActiveRecord::Migration.verbose = false
42
- InitialSchema.migrate(:up)
43
- rescue StandardError
44
- # Do nothing
35
+ def adapter
36
+ return "postgresql" if Mihari.config.database.start_with?("postgresql://", "postgres://")
37
+
38
+ "sqlite3"
45
39
  end
40
+
41
+ module Mihari
42
+ class Database
43
+ class << self
44
+ def connect
45
+ case adapter
46
+ when "postgresql"
47
+ ActiveRecord::Base.establish_connection(Mihari.config.database)
48
+ else
49
+ ActiveRecord::Base.establish_connection(
50
+ adapter: adapter,
51
+ database: Mihari.config.database
52
+ )
53
+ end
54
+
55
+ ActiveRecord::Migration.verbose = false
56
+ InitialSchema.migrate(:up)
57
+ rescue StandardError
58
+ # Do nothing
59
+ end
60
+
61
+ def destroy!
62
+ InitialSchema.migrate(:down) if ActiveRecord::Base.connected?
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ Mihari::Database.connect
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mihari
4
4
  module Emitters
5
- class SQLite < Base
5
+ class Database < Base
6
6
  def valid?
7
7
  true
8
8
  end
@@ -35,7 +35,7 @@ module Mihari
35
35
  private
36
36
 
37
37
  def config_keys
38
- [Mihari.config.misp_api_endpoint, Mihari.config.misp_api_key]
38
+ %w(misp_api_endpoint misp_api_key)
39
39
  end
40
40
 
41
41
  def build_attribute(artifact)
@@ -135,7 +135,7 @@ module Mihari
135
135
  private
136
136
 
137
137
  def config_keys
138
- [Mihari.config.slack_webhook_url]
138
+ %w(slack_webhook_url)
139
139
  end
140
140
  end
141
141
  end
@@ -27,7 +27,7 @@ module Mihari
27
27
  private
28
28
 
29
29
  def config_keys
30
- [Mihari.config.thehive_api_endpoint, Mihari.config.thehive_api_key]
30
+ %w(thehive_api_endpoint thehive_api_key)
31
31
  end
32
32
 
33
33
  def api
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "1.0.1"
4
+ VERSION = "1.1.0"
5
5
  end
data/mihari.gemspec CHANGED
@@ -31,7 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "pre-commit", "~> 0.39"
32
32
  spec.add_development_dependency "rake", "~> 13.0"
33
33
  spec.add_development_dependency "rspec", "~> 3.9"
34
- spec.add_development_dependency "rubocop", "~> 0.82"
35
34
  spec.add_development_dependency "rubocop-performance", "~> 1.5"
36
35
  spec.add_development_dependency "timecop", "~> 0.9"
37
36
  spec.add_development_dependency "vcr", "~> 5.1"
@@ -55,6 +54,7 @@ Gem::Specification.new do |spec|
55
54
  spec.add_dependency "parallel", "~> 1.19"
56
55
  spec.add_dependency "passive_circl", "~> 0.1"
57
56
  spec.add_dependency "passivetotalx", "~> 0.1"
57
+ spec.add_dependency "pg", "~> 1.2"
58
58
  spec.add_dependency "public_suffix", "~> 4.0"
59
59
  spec.add_dependency "pulsedive", "~> 0.1"
60
60
  spec.add_dependency "securitytrails", "~> 1.0"
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: 1.0.1
4
+ version: 1.1.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: 2020-05-03 00:00:00.000000000 Z
11
+ date: 2020-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3.9'
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.82'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.82'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: rubocop-performance
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -430,6 +416,20 @@ dependencies:
430
416
  - - "~>"
431
417
  - !ruby/object:Gem::Version
432
418
  version: '0.1'
419
+ - !ruby/object:Gem::Dependency
420
+ name: pg
421
+ requirement: !ruby/object:Gem::Requirement
422
+ requirements:
423
+ - - "~>"
424
+ - !ruby/object:Gem::Version
425
+ version: '1.2'
426
+ type: :runtime
427
+ prerelease: false
428
+ version_requirements: !ruby/object:Gem::Requirement
429
+ requirements:
430
+ - - "~>"
431
+ - !ruby/object:Gem::Version
432
+ version: '1.2'
433
433
  - !ruby/object:Gem::Dependency
434
434
  name: public_suffix
435
435
  requirement: !ruby/object:Gem::Requirement
@@ -622,9 +622,9 @@ files:
622
622
  - lib/mihari/configurable.rb
623
623
  - lib/mihari/database.rb
624
624
  - lib/mihari/emitters/base.rb
625
+ - lib/mihari/emitters/database.rb
625
626
  - lib/mihari/emitters/misp.rb
626
627
  - lib/mihari/emitters/slack.rb
627
- - lib/mihari/emitters/sqlite.rb
628
628
  - lib/mihari/emitters/stdout.rb
629
629
  - lib/mihari/emitters/the_hive.rb
630
630
  - lib/mihari/errors.rb