mihari 5.0.0 → 5.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: 41784cbe3811a8f5f2a6a4de663ceaa03e2635c329c455b523e5fc55fda0c9e7
4
- data.tar.gz: '052987fcb8805a8f71a0716d5e0970b0c4c7451059dded4b5149679ccda6c999'
3
+ metadata.gz: 9481229c15756515053bbc91453db90d914e40e5f536d0b5aaad0f2b8fff5868
4
+ data.tar.gz: 1ea1f9caa3dbb1f945f4a3ba9f9af17c80c786594692de1564ca4f76692fa628
5
5
  SHA512:
6
- metadata.gz: f16447e83adb4630baf9587eecea0dbb6f580de23894d70fa2c1729483faa6dc1c86fe5de2bd782100f8cba89e2a50e7ce2f0ab675de822fe5fb767fb2c6f45f
7
- data.tar.gz: af70fcc510ed4fd6a434481a8372c56d20a54b605ee0b49425a1315531d2261db6df9588f1961ba34796728ff40f0ce188ad58e6c542f4c3644a8c8251b37eb5
6
+ metadata.gz: f13bb894b69d4c92b03afc30fcce1be95ba1af1b0cb963c553a328fb85f771c852ee5526af751a098dd4f1b69c60592f021a0e3ee7e40004856d1d4eabc53aba
7
+ data.tar.gz: 751ad7fc17f2db38961e835f8c9b2a325cbf82692df65ef29c638bcf3eec9cbc17905a39bcbcf5a53bcf477adbf6080a23aa40702b3fb5a55727038eefe9b09d
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --format documentation
1
+ --format Fuubar
2
2
  --color
3
3
  --require spec_helper
data/docker/Dockerfile CHANGED
@@ -3,7 +3,7 @@ FROM ruby:3.1.3-alpine3.17
3
3
  RUN apk --no-cache add git build-base ruby-dev sqlite-dev postgresql-dev mysql-client mysql-dev && \
4
4
  gem install pg mysql2
5
5
 
6
- ARG MIHARI_VERSION=4.11.0
6
+ ARG MIHARI_VERSION=5.1.0
7
7
 
8
8
  RUN gem install mihari -v ${MIHARI_VERSION}
9
9
 
@@ -9,7 +9,6 @@ module Mihari
9
9
 
10
10
  include Mixins::AutonomousSystem
11
11
  include Mixins::Configurable
12
- include Mixins::Database
13
12
  include Mixins::Retriable
14
13
 
15
14
  # @return [Mihari::Structs::Rule, nil]
@@ -42,16 +41,14 @@ module Mihari
42
41
  raise ConfigurationError, "#{class_name} is not configured correctly"
43
42
  end
44
43
 
45
- with_db_connection do
46
- set_enriched_artifacts
44
+ set_enriched_artifacts
47
45
 
48
- responses = Parallel.map(valid_emitters) do |emitter|
49
- run_emitter emitter
50
- end
51
-
52
- # returns Mihari::Alert created by the database emitter
53
- responses.find { |res| res.is_a?(Mihari::Alert) }
46
+ responses = Parallel.map(valid_emitters) do |emitter|
47
+ run_emitter emitter
54
48
  end
49
+
50
+ # returns Mihari::Alert created by the database emitter
51
+ responses.find { |res| res.is_a?(Mihari::Alert) }
55
52
  end
56
53
 
57
54
  #
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mihari/commands/database"
4
+
5
+ module Mihari
6
+ module CLI
7
+ class Database < Base
8
+ include Mihari::Commands::Database
9
+ end
10
+ end
11
+ end
@@ -3,23 +3,29 @@
3
3
  require "thor"
4
4
 
5
5
  # Commands
6
- require "mihari/commands/initializer"
7
6
  require "mihari/commands/searcher"
8
- require "mihari/commands/validator"
9
7
  require "mihari/commands/version"
10
8
  require "mihari/commands/web"
9
+ require "mihari/commands/database"
11
10
 
12
11
  # CLIs
13
12
  require "mihari/cli/base"
14
13
 
14
+ require "mihari/cli/database"
15
+ require "mihari/cli/rule"
16
+
15
17
  module Mihari
16
18
  module CLI
17
19
  class Main < Base
18
20
  include Mihari::Commands::Searcher
19
21
  include Mihari::Commands::Version
20
22
  include Mihari::Commands::Web
21
- include Mihari::Commands::Validator
22
- include Mihari::Commands::Initializer
23
+
24
+ desc "db", "Sub commands for DB"
25
+ subcommand "db", Database
26
+
27
+ desc "rule", "Sub commands for rule"
28
+ subcommand "rule", Rule
23
29
  end
24
30
  end
25
31
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mihari/commands/rule"
4
+
5
+ module Mihari
6
+ module CLI
7
+ class Rule < Base
8
+ include Mihari::Commands::Rule
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ module Commands
5
+ module Database
6
+ include Mixins::Database
7
+
8
+ def self.included(thor)
9
+ thor.class_eval do
10
+ desc "migrate", "Migrate DB schemas"
11
+ method_option :verbose, type: :boolean, default: true
12
+ #
13
+ # @param [String] direction
14
+ #
15
+ #
16
+ def migrate(direction = "up")
17
+ verbose = options["verbose"]
18
+ ActiveRecord::Migration.verbose = verbose
19
+
20
+ with_db_connection do
21
+ Mihari::Database.migrate(direction.to_sym)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,20 +4,41 @@ require "pathname"
4
4
 
5
5
  module Mihari
6
6
  module Commands
7
- module Initializer
7
+ module Rule
8
8
  def self.included(thor)
9
9
  thor.class_eval do
10
- desc "init", "Initialize a new rule"
11
- method_option :path, type: :string, default: "./rule.yml"
12
- def init
13
- path = options["path"]
10
+ desc "validate [PATH]", "Validate a rule file"
11
+ #
12
+ # Validate format of a rule
13
+ #
14
+ # @param [String] path
15
+ #
16
+ def validate(path)
17
+ rule = Structs::Rule.from_path_or_id(path)
14
18
 
19
+ begin
20
+ rule.validate!
21
+ Mihari.logger.info "Valid format. The input is parsed as the following:"
22
+ Mihari.logger.info rule.data.to_yaml
23
+ rescue RuleValidationError
24
+ nil
25
+ end
26
+ end
27
+
28
+ desc "init [PATH]", "Initialize a new rule file"
29
+ #
30
+ # Initialize a new rule file
31
+ #
32
+ # @param [String] path
33
+ #
34
+ #
35
+ def init(path = "./rule.yml")
15
36
  warning = "#{path} exists. Do you want to overwrite it? (y/n)"
16
37
  return if Pathname(path).exist? && !(yes? warning)
17
38
 
18
39
  initialize_rule path
19
40
 
20
- Mihari.logger.info "A new rule is initialized as #{path}."
41
+ Mihari.logger.info "A new rule is initialized: #{path}."
21
42
  end
22
43
 
23
44
  no_commands do
@@ -9,39 +9,49 @@ module Mihari
9
9
  def self.included(thor)
10
10
  thor.class_eval do
11
11
  desc "search [PATH]", "Search by a rule"
12
- method_option :yes, type: :boolean, aliases: "-y", desc: "yes to overwrite the rule in the database"
12
+ method_option :force_overwrite, type: :boolean, aliases: "-f", desc: "Force an overwrite the rule"
13
+ #
14
+ # Search by a rule
15
+ #
16
+ # @param [String] path_or_id
17
+ #
13
18
  def search(path_or_id)
14
- rule = Structs::Rule.from_path_or_id path_or_id
19
+ with_db_connection do
20
+ rule = Structs::Rule.from_path_or_id path_or_id
15
21
 
16
- # validate
17
- begin
18
- rule.validate!
19
- rescue RuleValidationError
20
- return
21
- end
22
+ # validate
23
+ begin
24
+ rule.validate!
25
+ rescue RuleValidationError
26
+ return
27
+ end
28
+
29
+ force_overwrite = options["force_overwrite"] || false
30
+
31
+ begin
32
+ rule_model = Mihari::Rule.find(rule.id)
33
+ has_change = rule_model.data != rule.data.deep_stringify_keys
34
+ has_change_and_not_force_overwrite = has_change & !force_overwrite
22
35
 
23
- # check update
24
- yes = options["yes"] || false
25
- unless yes
26
- with_db_connection do
27
- next if Mihari::Rule.find(rule.id).data == rule.data.deep_stringify_keys
28
- unless yes?("This operation will overwrite the rule in the database (Rule ID: #{rule.id}). Are you sure you want to update the rule? (y/n)")
36
+ if has_change_and_not_force_overwrite && !yes?("This operation will overwrite the rule in the database (Rule ID: #{rule.id}). Are you sure you want to update the rule? (y/n)")
29
37
  return
30
38
  end
39
+
40
+ # update the rule
41
+ rule.model.save
31
42
  rescue ActiveRecord::RecordNotFound
32
- next
43
+ # create a new rule
44
+ rule.model.save
33
45
  end
34
- end
35
- # update rule model
36
- rule.model.save
37
-
38
- with_error_notification do
39
- alert = rule.analyzer.run
40
- if alert
41
- data = Mihari::Entities::Alert.represent(alert)
42
- puts JSON.pretty_generate(data.as_json)
43
- else
44
- Mihari.logger.info "There is no new alert created in the database"
46
+
47
+ with_error_notification do
48
+ alert = rule.analyzer.run
49
+ if alert
50
+ data = Mihari::Entities::Alert.represent(alert)
51
+ puts JSON.pretty_generate(data.as_json)
52
+ else
53
+ Mihari.logger.info "There is no new alert created in the database"
54
+ end
45
55
  end
46
56
  end
47
57
  end
@@ -9,10 +9,6 @@ def env
9
9
  ENV["APP_ENV"] || ENV["RACK_ENV"]
10
10
  end
11
11
 
12
- def test_env?
13
- env == "test"
14
- end
15
-
16
12
  def development_env?
17
13
  env == "development"
18
14
  end
@@ -121,22 +117,24 @@ def adapter
121
117
  "sqlite3"
122
118
  end
123
119
 
120
+ #
121
+ # @return [Array<ActiveRecord::Migration>] schemas
122
+ #
123
+ def schemas
124
+ [V5Schema]
125
+ end
126
+
124
127
  module Mihari
125
128
  class Database
126
129
  class << self
127
- include Memist::Memoizable
128
-
129
130
  #
130
131
  # DB migraration
131
132
  #
132
133
  # @param [Symbol] direction
133
134
  #
134
135
  def migrate(direction)
135
- ActiveRecord::Migration.verbose = false
136
-
137
- [V5Schema].each { |schema| schema.migrate direction }
136
+ schemas.each { |schema| schema.migrate direction }
138
137
  end
139
- memoize :migrate unless test_env?
140
138
 
141
139
  #
142
140
  # Establish DB connection
@@ -153,10 +151,7 @@ module Mihari
153
151
  database: Mihari.config.database_url.path[1..]
154
152
  )
155
153
  end
156
-
157
154
  ActiveRecord::Base.logger = Logger.new($stdout) if development_env?
158
-
159
- migrate :up
160
155
  rescue StandardError => e
161
156
  Mihari.logger.error e
162
157
  end
@@ -169,15 +164,6 @@ module Mihari
169
164
 
170
165
  ActiveRecord::Base.clear_active_connections!
171
166
  end
172
-
173
- #
174
- # Destory DB
175
- #
176
- def destroy!
177
- return unless ActiveRecord::Base.connected?
178
-
179
- migrate :down
180
- end
181
167
  end
182
168
  end
183
169
  end
@@ -6,6 +6,8 @@ module Mihari
6
6
  def with_db_connection
7
7
  Mihari::Database.connect
8
8
  yield
9
+ rescue ActiveRecord::StatementInvalid
10
+ Mihari.logger.error("You haven't finished the DB migration! Please run 'mihari db migrate'.")
9
11
  ensure
10
12
  Mihari::Database.close
11
13
  end
@@ -164,8 +164,6 @@ module Mihari
164
164
  end
165
165
 
166
166
  class << self
167
- include Mixins::Database
168
-
169
167
  #
170
168
  # Load rule from YAML string
171
169
  #
@@ -209,11 +207,9 @@ module Mihari
209
207
  # @return [Mihari::Structs::Rule, nil]
210
208
  #
211
209
  def from_id(id)
212
- with_db_connection do
213
- return nil unless Mihari::Rule.exists?(id)
210
+ return nil unless Mihari::Rule.exists?(id)
214
211
 
215
- Structs::Rule.from_model Mihari::Rule.find(id)
216
- end
212
+ Structs::Rule.from_model Mihari::Rule.find(id)
217
213
  end
218
214
 
219
215
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "5.0.0"
4
+ VERSION = "5.1.0"
5
5
  end
data/mihari.gemspec CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "bundler", "~> 2.4"
31
31
  spec.add_development_dependency "coveralls_reborn", "~> 0.27"
32
32
  spec.add_development_dependency "fakefs", "~> 2.4"
33
+ spec.add_development_dependency "fuubar", "~> 2.5"
33
34
  spec.add_development_dependency "mysql2", "~> 0.5"
34
35
  spec.add_development_dependency "overcommit", "~> 0.60"
35
36
  spec.add_development_dependency "pg", "~> 1.4"
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: 5.0.0
4
+ version: 5.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: 2023-02-19 00:00:00.000000000 Z
11
+ date: 2023-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fuubar
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.5'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: mysql2
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -1066,10 +1080,12 @@ files:
1066
1080
  - lib/mihari/analyzers/virustotal_intelligence.rb
1067
1081
  - lib/mihari/analyzers/zoomeye.rb
1068
1082
  - lib/mihari/cli/base.rb
1083
+ - lib/mihari/cli/database.rb
1069
1084
  - lib/mihari/cli/main.rb
1070
- - lib/mihari/commands/initializer.rb
1085
+ - lib/mihari/cli/rule.rb
1086
+ - lib/mihari/commands/database.rb
1087
+ - lib/mihari/commands/rule.rb
1071
1088
  - lib/mihari/commands/searcher.rb
1072
- - lib/mihari/commands/validator.rb
1073
1089
  - lib/mihari/commands/version.rb
1074
1090
  - lib/mihari/commands/web.rb
1075
1091
  - lib/mihari/constants.rb
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mihari
4
- module Commands
5
- module Validator
6
- def self.included(thor)
7
- thor.class_eval do
8
- desc "validate [PATH]", "Validate a rule file"
9
- #
10
- # Validate format of a rule
11
- #
12
- # @param [String] path
13
- #
14
- # @return [nil]
15
- #
16
- def validate(path)
17
- rule = Structs::Rule.from_path_or_id(path)
18
-
19
- begin
20
- rule.validate!
21
- Mihari.logger.info "Valid format. The input is parsed as the following:"
22
- Mihari.logger.info rule.data.to_yaml
23
- rescue RuleValidationError
24
- nil
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end