mihari 3.2.0 → 3.3.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: eeee7ec511b59cc1e6d07f47df8b2edc29860dbeeeafebc79ba876efe17f2954
4
- data.tar.gz: e3c4fe0b49b20efa5ebdafaecdadbfb35135cbbdf3ff41dd36c68d2eaae644f8
3
+ metadata.gz: 56538b2cc9269fa7e92a2c8cd98746caae7a480b7961fb83482a2189f5318992
4
+ data.tar.gz: 9c4561c9e820a42b9b4d65b1e0ad02901034cc7eb124d7c5409418cab43bc5bd
5
5
  SHA512:
6
- metadata.gz: eff2de53ad20576849a81a5ebe96155c6b8747ab4b1775b26816ae6eff7eeb8324f2ad360755e867741a1b6cc778f1dec63d80bbb5439b9e8894536988971183
7
- data.tar.gz: 2b1effec63ad4119f7cb521db866e0e9deb2dca7971036530d4cb16ea4a8669d591981ad5517784da13b98b7a3d3aa732538d040b53590b371d8f51acde849e0
6
+ metadata.gz: 0b43cf2ee5e73607593e2c140dbc4ec70dcc8ad1eb436914a016f852f8dabed7f1aafd2f048565356f3fbed865540488e0766bc7f3a86bd6845c722419472abe
7
+ data.tar.gz: 485bbcd01bcd8016b3a50b5e61fcac4cef8f527812570c734eff8a0fe6a75fc3b8e79e50d2a147c4edc20eee0370609ec5c2021bd28172bedff484bd04707379
data/README.md CHANGED
@@ -14,11 +14,12 @@ Mihari is a framework for continuous OSINT based threat hunting.
14
14
 
15
15
  ## How it works
16
16
 
17
- ![img](https://github.com/ninoseki/mihari/raw/master/images/overview.png)
17
+ ![img](https://github.com/ninoseki/mihari/raw/master/images/overview.jpg)
18
18
 
19
19
  - Mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts (IP addresses, domains, URLs or hashes).
20
- - Mihari checks whether a DB (SQLite3, PostgreSQL or MySQL) contains the artifacts or not.
20
+ - Mihari checks whether the database (SQLite3, PostgreSQL or MySQL) contains the artifacts or not.
21
21
  - If it doesn't contain the artifacts:
22
+ - Mihari saves artifacts in the database.
22
23
  - Mihari creates an alert on TheHive.
23
24
  - Mihari sends a notification to Slack.
24
25
  - Mihari creates an event on MISP.
data/config.ru ADDED
@@ -0,0 +1,6 @@
1
+ require "./lib/mihari"
2
+
3
+ # set rack env as development
4
+ ENV["RACK_ENV"] ||= "development"
5
+
6
+ run Mihari::App
Binary file
data/lib/mihari.rb CHANGED
@@ -9,6 +9,7 @@ require "yaml"
9
9
  # Mixins
10
10
  require "mihari/mixins/configurable"
11
11
  require "mihari/mixins/configuration"
12
+ require "mihari/mixins/disallowed_data_value"
12
13
  require "mihari/mixins/hash"
13
14
  require "mihari/mixins/refang"
14
15
  require "mihari/mixins/retriable"
@@ -5,6 +5,8 @@ require "uuidtools"
5
5
  module Mihari
6
6
  module Analyzers
7
7
  class Rule < Base
8
+ include Mihari::Mixins::DisallowedDataValue
9
+
8
10
  option :title
9
11
  option :description
10
12
  option :queries
@@ -12,6 +14,7 @@ module Mihari
12
14
  option :id, default: proc {}
13
15
  option :tags, default: proc { [] }
14
16
  option :allowed_data_types, default: proc { ALLOWED_DATA_TYPES }
17
+ option :disallowed_data_values, default: proc { [] }
15
18
 
16
19
  attr_reader :source
17
20
 
@@ -68,12 +71,36 @@ module Mihari
68
71
  # - Uniquefy artifacts by #uniq(&:data)
69
72
  # - Reject an invalid artifact (for just in case)
70
73
  # - Select artifacts with allowed data types
74
+ # - Reject artifacts with disallowed data values
71
75
  #
72
76
  # @return [Array<Mihari::Artifact>]
73
77
  #
74
78
  def normalized_artifacts
75
79
  @normalized_artifacts ||= artifacts.uniq(&:data).select(&:valid?).select do |artifact|
76
80
  allowed_data_types.include? artifact.data_type
81
+ end.reject do |artifact|
82
+ disallowed_data_value? artifact.data
83
+ end
84
+ end
85
+
86
+ #
87
+ # Normalized disallowed data values
88
+ #
89
+ # @return [Array<Regexp, String>]
90
+ #
91
+ def normalized_disallowed_data_values
92
+ @normalized_disallowed_data_values ||= disallowed_data_values.map { |v| normalize_disallowed_data_value v }
93
+ end
94
+
95
+ #
96
+ # Check whether a value is a disallowed data value or not
97
+ #
98
+ # @return [Boolean]
99
+ #
100
+ def disallowed_data_value?(value)
101
+ normalized_disallowed_data_values.any? do |disallowed_data_value|
102
+ return value == disallowed_data_value if disallowed_data_value.is_a?(String)
103
+ return disallowed_data_value.match?(value) if disallowed_data_value.is_a?(Regexp)
77
104
  end
78
105
  end
79
106
 
@@ -37,13 +37,15 @@ module Mihari
37
37
  # @param [Array<Hash>] queries
38
38
  # @param [Array<String>, nil] tags
39
39
  # @param [Array<String>, nil] allowed_data_types
40
+ # @param [Array<String>, nil] disallowed_data_values
40
41
  # @param [String, nil] source
41
42
  #
42
43
  # @return [Mihari::Analyzers::Rule]
43
44
  #
44
- def build_rule_analyzer(title:, description:, queries:, tags: nil, allowed_data_types: nil, source: nil)
45
+ def build_rule_analyzer(title:, description:, queries:, tags: nil, allowed_data_types: nil, disallowed_data_values: nil, source: nil)
45
46
  tags = [] if tags.nil?
46
47
  allowed_data_types = ALLOWED_DATA_TYPES if allowed_data_types.nil?
48
+ disallowed_data_values = [] if disallowed_data_values.nil?
47
49
 
48
50
  Analyzers::Rule.new(
49
51
  title: title,
@@ -51,6 +53,7 @@ module Mihari
51
53
  tags: tags,
52
54
  queries: queries,
53
55
  allowed_data_types: allowed_data_types,
56
+ disallowed_data_values: disallowed_data_values,
54
57
  source: source
55
58
  )
56
59
  end
@@ -13,6 +13,10 @@ module Mihari
13
13
  host = options["host"] || "localhost"
14
14
 
15
15
  load_configuration
16
+
17
+ # set rack env as production
18
+ ENV["RACK_ENV"] ||= "production"
19
+
16
20
  Mihari::App.run!(port: port, host: host)
17
21
  end
18
22
  end
@@ -0,0 +1,42 @@
1
+ require "mem"
2
+
3
+ module Mihari
4
+ module Mixins
5
+ module DisallowedDataValue
6
+ include Mem
7
+
8
+ #
9
+ # Normalize a value as a disallowed data value
10
+ #
11
+ # @param [String] value Data value
12
+ #
13
+ # @return [String, Regexp] Normalized value
14
+ #
15
+ def normalize_disallowed_data_value(value)
16
+ return value if !value.start_with?("/") || !value.end_with?("/")
17
+
18
+ # if a value is surrounded by slashes, take it as a regexp
19
+ value_without_slashes = value[1..-2]
20
+ Regexp.compile value_without_slashes
21
+ end
22
+
23
+ memoize :normalize_disallowed_data_value
24
+
25
+ #
26
+ # Check whetehr a value is valid format as a disallowed data value
27
+ #
28
+ # @param [String] value Data value
29
+ #
30
+ # @return [Boolean] true if it is valid, otherwise false
31
+ #
32
+ def valid_disallowed_data_value?(value)
33
+ begin
34
+ normalize_disallowed_data_value value
35
+ rescue RegexpError
36
+ return false
37
+ end
38
+ true
39
+ end
40
+ end
41
+ end
42
+ end
@@ -63,10 +63,21 @@ module Mihari
63
63
  required(:queries).value(:array).each { Analyzer | Spyse | ZoomEye | Urlscan | Crtsh }
64
64
 
65
65
  optional(:allowed_data_types).value(array[DataTypes]).default(ALLOWED_DATA_TYPES)
66
+ optional(:disallowed_data_values).value(array[:string]).default([])
66
67
  end
67
68
 
68
69
  class RuleContract < Dry::Validation::Contract
70
+ include Mihari::Mixins::DisallowedDataValue
71
+
69
72
  params(Rule)
73
+
74
+ rule(:disallowed_data_values) do
75
+ value.each do |v|
76
+ unless valid_disallowed_data_value?(v)
77
+ key.failure("#{v} is not a valid format.")
78
+ end
79
+ end
80
+ end
70
81
  end
71
82
  end
72
83
  end
@@ -2,7 +2,7 @@ title: ... # String (required)
2
2
  description: ... # String (required)
3
3
 
4
4
  id: ... # String (optional)
5
- author: .. # String (optional)
5
+ author: ... # String (optional)
6
6
  created_on: <%= Date.today %> # Date (optional)
7
7
  updated_on: <%= Date.today %> # Date (optional)
8
8
 
@@ -13,6 +13,7 @@ allowed_data_types: # Array<String> (Optional, defaults to ["hash", "ip", "domai
13
13
  - domain
14
14
  - url
15
15
  - mail
16
+ disallowed_data_values: [] # Array<String> (Optional, defaults to [])
16
17
 
17
18
  queries: # Array<Hash> (required)
18
19
  - analyzer: shodan # String (required)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "3.2.0"
4
+ VERSION = "3.3.0"
5
5
  end
@@ -16,6 +16,7 @@ require "mihari/web/controllers/command_controller"
16
16
  require "mihari/web/controllers/config_controller"
17
17
  require "mihari/web/controllers/sources_controller"
18
18
  require "mihari/web/controllers/tags_controller"
19
+
19
20
  module Mihari
20
21
  class App < Sinatra::Base
21
22
  set :root, File.dirname(__FILE__)
data/mihari.gemspec CHANGED
@@ -68,7 +68,7 @@ Gem::Specification.new do |spec|
68
68
  spec.add_dependency "passivetotalx", "~> 0.1"
69
69
  spec.add_dependency "public_suffix", "~> 4.0"
70
70
  spec.add_dependency "pulsedive", "~> 0.1"
71
- spec.add_dependency "puma", "~> 5.3"
71
+ spec.add_dependency "puma", "~> 5.4"
72
72
  spec.add_dependency "rack", "~> 2.2"
73
73
  spec.add_dependency "rack-contrib", "~> 2.3"
74
74
  spec.add_dependency "safe_shell", "~> 1.1"
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: 3.2.0
4
+ version: 3.3.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: 2021-07-25 00:00:00.000000000 Z
11
+ date: 2021-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -604,14 +604,14 @@ dependencies:
604
604
  requirements:
605
605
  - - "~>"
606
606
  - !ruby/object:Gem::Version
607
- version: '5.3'
607
+ version: '5.4'
608
608
  type: :runtime
609
609
  prerelease: false
610
610
  version_requirements: !ruby/object:Gem::Requirement
611
611
  requirements:
612
612
  - - "~>"
613
613
  - !ruby/object:Gem::Version
614
- version: '5.3'
614
+ version: '5.4'
615
615
  - !ruby/object:Gem::Dependency
616
616
  name: rack
617
617
  requirement: !ruby/object:Gem::Requirement
@@ -872,6 +872,7 @@ files:
872
872
  - bin/console
873
873
  - bin/setup
874
874
  - build_frontend.sh
875
+ - config.ru
875
876
  - config/pre_commit.yml
876
877
  - docker/Dockerfile
877
878
  - examples/ipinfo_hosted_domains.rb
@@ -879,7 +880,7 @@ files:
879
880
  - images/alert.png
880
881
  - images/logo.png
881
882
  - images/misp.png
882
- - images/overview.png
883
+ - images/overview.jpg
883
884
  - images/slack.png
884
885
  - images/tines.png
885
886
  - images/web_alerts.png
@@ -943,6 +944,7 @@ files:
943
944
  - lib/mihari/errors.rb
944
945
  - lib/mihari/mixins/configurable.rb
945
946
  - lib/mihari/mixins/configuration.rb
947
+ - lib/mihari/mixins/disallowed_data_value.rb
946
948
  - lib/mihari/mixins/hash.rb
947
949
  - lib/mihari/mixins/refang.rb
948
950
  - lib/mihari/mixins/retriable.rb
data/images/overview.png DELETED
Binary file