mihari 5.2.3 → 5.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/build_frontend.sh +1 -9
  3. data/frontend/.browserslistrc +3 -0
  4. data/frontend/.eslintrc.js +33 -0
  5. data/frontend/.gitignore +25 -0
  6. data/frontend/README.md +3 -0
  7. data/frontend/babel.config.js +3 -0
  8. data/frontend/index.html +21 -0
  9. data/frontend/jest.config.js +9 -0
  10. data/frontend/package-lock.json +13216 -0
  11. data/frontend/package.json +54 -0
  12. data/frontend/public/favicon.ico +0 -0
  13. data/frontend/scripts/swagger_doc_to_yaml.rb +23 -0
  14. data/frontend/src/App.vue +27 -0
  15. data/frontend/src/api-helper.ts +113 -0
  16. data/frontend/src/api.ts +105 -0
  17. data/frontend/src/components/ErrorMessage.vue +32 -0
  18. data/frontend/src/components/Loading.vue +15 -0
  19. data/frontend/src/components/Navbar.vue +59 -0
  20. data/frontend/src/components/Pagination.vue +126 -0
  21. data/frontend/src/components/alert/Alert.vue +92 -0
  22. data/frontend/src/components/alert/Alerts.vue +66 -0
  23. data/frontend/src/components/alert/AlertsWithPagination.vue +91 -0
  24. data/frontend/src/components/alert/AlertsWrapper.vue +141 -0
  25. data/frontend/src/components/alert/Form.vue +185 -0
  26. data/frontend/src/components/artifact/AS.vue +29 -0
  27. data/frontend/src/components/artifact/Artifact.vue +321 -0
  28. data/frontend/src/components/artifact/ArtifactTag.vue +70 -0
  29. data/frontend/src/components/artifact/ArtifactTags.vue +29 -0
  30. data/frontend/src/components/artifact/ArtifactWrapper.vue +62 -0
  31. data/frontend/src/components/artifact/CPEs.vue +23 -0
  32. data/frontend/src/components/artifact/DnsRecords.vue +38 -0
  33. data/frontend/src/components/artifact/Ports.vue +23 -0
  34. data/frontend/src/components/artifact/ReverseDnsNames.vue +31 -0
  35. data/frontend/src/components/artifact/Tags.vue +29 -0
  36. data/frontend/src/components/artifact/WhoisRecord.vue +49 -0
  37. data/frontend/src/components/config/Configs.vue +68 -0
  38. data/frontend/src/components/config/ConfigsWrapper.vue +40 -0
  39. data/frontend/src/components/link/Link.vue +32 -0
  40. data/frontend/src/components/link/Links.vue +47 -0
  41. data/frontend/src/components/rule/EditRule.vue +74 -0
  42. data/frontend/src/components/rule/EditRuleWrapper.vue +56 -0
  43. data/frontend/src/components/rule/Form.vue +160 -0
  44. data/frontend/src/components/rule/InputForm.vue +80 -0
  45. data/frontend/src/components/rule/NewRule.vue +60 -0
  46. data/frontend/src/components/rule/Rule.vue +108 -0
  47. data/frontend/src/components/rule/RuleWrapper.vue +62 -0
  48. data/frontend/src/components/rule/Rules.vue +88 -0
  49. data/frontend/src/components/rule/RulesWrapper.vue +130 -0
  50. data/frontend/src/components/rule/YAML.vue +47 -0
  51. data/frontend/src/components/tag/Tag.vue +73 -0
  52. data/frontend/src/components/tag/Tags.vue +37 -0
  53. data/frontend/src/countries.ts +350 -0
  54. data/frontend/src/index.ts +23 -0
  55. data/frontend/src/links/anyrun.ts +19 -0
  56. data/frontend/src/links/base.ts +14 -0
  57. data/frontend/src/links/censys.ts +20 -0
  58. data/frontend/src/links/crtsh.ts +20 -0
  59. data/frontend/src/links/dnslytics.ts +38 -0
  60. data/frontend/src/links/greynoise.ts +20 -0
  61. data/frontend/src/links/index.ts +40 -0
  62. data/frontend/src/links/intezer.ts +20 -0
  63. data/frontend/src/links/otx.ts +33 -0
  64. data/frontend/src/links/securitytrails.ts +38 -0
  65. data/frontend/src/links/shodan.ts +20 -0
  66. data/frontend/src/links/urlscan.ts +50 -0
  67. data/frontend/src/links/virustotal.ts +72 -0
  68. data/frontend/src/main.ts +11 -0
  69. data/frontend/src/router/index.ts +57 -0
  70. data/frontend/src/rule.ts +14 -0
  71. data/frontend/src/shims-vue.d.ts +6 -0
  72. data/frontend/src/swagger.yaml +737 -0
  73. data/frontend/src/types.ts +188 -0
  74. data/frontend/src/utils.ts +60 -0
  75. data/frontend/src/views/Alerts.vue +20 -0
  76. data/frontend/src/views/Artifact.vue +44 -0
  77. data/frontend/src/views/Configs.vue +20 -0
  78. data/frontend/src/views/EditRule.vue +44 -0
  79. data/frontend/src/views/NewRule.vue +26 -0
  80. data/frontend/src/views/Rule.vue +44 -0
  81. data/frontend/src/views/Rules.vue +20 -0
  82. data/frontend/tests/unit/utils.spec.ts +7 -0
  83. data/frontend/tsconfig.json +40 -0
  84. data/frontend/vite.config.js +24 -0
  85. data/lefthook.yml +10 -0
  86. data/lib/mihari/analyzers/base.rb +22 -5
  87. data/lib/mihari/analyzers/rule.rb +8 -29
  88. data/lib/mihari/commands/search.rb +16 -7
  89. data/lib/mihari/entities/rule.rb +1 -1
  90. data/lib/mihari/entities/tag.rb +1 -1
  91. data/lib/mihari/schemas/analyzer.rb +2 -7
  92. data/lib/mihari/schemas/rule.rb +1 -1
  93. data/lib/mihari/structs/config.rb +39 -16
  94. data/lib/mihari/structs/rule.rb +1 -1
  95. data/lib/mihari/version.rb +1 -1
  96. data/lib/mihari/web/public/assets/index-ac4e5ffa.js +50 -0
  97. data/lib/mihari/web/public/index.html +1 -1
  98. data/mihari.gemspec +5 -5
  99. metadata +97 -16
  100. data/.gitmodules +0 -0
  101. data/.overcommit.yml +0 -12
  102. data/lib/mihari/web/public/assets/index-cbe1734c.js +0 -50
@@ -13,7 +13,7 @@ module Mihari
13
13
  # @return [Boolean]
14
14
  attr_reader :force_overwrite
15
15
 
16
- def initialize(rule:, force_overwrite:)
16
+ def initialize(rule, force_overwrite:)
17
17
  @rule = rule
18
18
  @force_overwrite = force_overwrite
19
19
  end
@@ -37,14 +37,23 @@ module Mihari
37
37
  end
38
38
 
39
39
  def run
40
+ begin
41
+ analyzer = rule.analyzer
42
+ rescue ConfigurationError => e
43
+ # if there is a configuration error, output that error without the stack trace
44
+ Mihari.logger.error e.to_s
45
+ return
46
+ end
47
+
40
48
  with_error_notification do
41
- alert = rule.analyzer.run
42
- if alert
43
- data = Mihari::Entities::Alert.represent(alert)
44
- puts JSON.pretty_generate(data.as_json)
45
- else
49
+ alert = analyzer.run
50
+ if alert.nil?
46
51
  Mihari.logger.info "There is no new artifact found"
52
+ return
47
53
  end
54
+
55
+ data = Mihari::Entities::Alert.represent(alert)
56
+ puts JSON.pretty_generate(data.as_json)
48
57
  end
49
58
  end
50
59
  end
@@ -69,7 +78,7 @@ module Mihari
69
78
  end
70
79
 
71
80
  force_overwrite = options["force_overwrite"] || false
72
- wrapper = RuleWrapper.new(rule: rule, force_overwrite: force_overwrite)
81
+ wrapper = RuleWrapper.new(rule, force_overwrite: force_overwrite)
73
82
 
74
83
  if wrapper.diff? && !force_overwrite
75
84
  message = "There is diff in the rule (#{rule.id}). Are you sure you want to overwrite the rule? (y/n)"
@@ -31,7 +31,7 @@ module Mihari
31
31
  end
32
32
 
33
33
  class RuleIDs < Grape::Entity
34
- expose :rule_ids, documentation: { type: Array[String], required: true }, as: :ruleIds
34
+ expose :rule_ids, documentation: { type: [String], required: true }, as: :ruleIds
35
35
  end
36
36
  end
37
37
  end
@@ -7,7 +7,7 @@ module Mihari
7
7
  end
8
8
 
9
9
  class Tags < Grape::Entity
10
- expose :tags, documentation: { type: Array[String], required: true }
10
+ expose :tags, documentation: { type: [String], required: true }
11
11
  end
12
12
  end
13
13
  end
@@ -7,7 +7,7 @@ module Mihari
7
7
  end
8
8
 
9
9
  AnalyzerWithoutAPIKey = Dry::Schema.Params do
10
- required(:analyzer).value(Types::String.enum("crtsh", "dnpedia", "dnstwister"))
10
+ required(:analyzer).value(Types::String.enum("dnstwister"))
11
11
  required(:query).value(:string)
12
12
  optional(:options).hash(AnalyzerOptions)
13
13
  end
@@ -23,6 +23,7 @@ module Mihari
23
23
  "securitytrails",
24
24
  "shodan",
25
25
  "st",
26
+ "urlscan",
26
27
  "virustotal_intelligence",
27
28
  "virustotal",
28
29
  "vt_intel",
@@ -72,12 +73,6 @@ module Mihari
72
73
  optional(:options).hash(AnalyzerOptions)
73
74
  end
74
75
 
75
- Urlscan = Dry::Schema.Params do
76
- required(:analyzer).value(Types::String.enum("urlscan"))
77
- required(:query).value(:string)
78
- optional(:options).hash(AnalyzerOptions)
79
- end
80
-
81
76
  Feed = Dry::Schema.Params do
82
77
  required(:analyzer).value(Types::String.enum("feed"))
83
78
  required(:query).value(:string)
@@ -22,7 +22,7 @@ module Mihari
22
22
  optional(:updated_on).value(:date)
23
23
 
24
24
  required(:queries).value(:array).each do
25
- AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | ZoomEye | Urlscan | Crtsh | Feed
25
+ AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | ZoomEye | Crtsh | Feed
26
26
  end
27
27
 
28
28
  optional(:emitters).value(:array).each { Database | MISP | TheHive | Slack | Webhook }.default(DEFAULT_EMITTERS)
@@ -38,30 +38,53 @@ module Mihari
38
38
 
39
39
  class << self
40
40
  #
41
- # @param [Class<Mihari::Analyzers::Base>, Class<Mihari::Emitters::Base>] klass
41
+ # Get a type of a class
42
+ #
43
+ # @param [Class<Mihari::Analyzers::Base>, Class<Mihari::Emitters::Base>, Class<Mihari::Enrichers::Base>] klass
44
+ #
45
+ # @return [String, nil]
46
+ #
47
+ def get_type(klass)
48
+ return "Analyzer" if klass.ancestors.include?(Mihari::Analyzers::Base)
49
+ return "Emitter" if klass.ancestors.include?(Mihari::Emitters::Base)
50
+ return "Enricher" if klass.ancestors.include?(Mihari::Enrichers::Base)
51
+
52
+ nil
53
+ end
54
+
55
+ #
56
+ # Get a dummy instance
57
+ #
58
+ # @param [Class<Mihari::Analyzers::Base>, Class<Mihari::Emitters::Base>, Class<Mihari::Enrichers::Base>] klass
59
+ #
60
+ # @return [Mihari::Analyzers::Base, Mihari::Emitter::Base, Mihari::Enricher::Base] dummy
61
+ #
62
+ def get_dummy(klass)
63
+ type = get_type(klass)
64
+ is_analyzer = type == "Analyzer"
65
+ is_analyzer ? klass.new("dummy") : klass.new(artifacts: [], rule: nil)
66
+ end
67
+
68
+ #
69
+ # @param [Class<Mihari::Analyzers::Base>, Class<Mihari::Emitters::Base>, Class<Mihari::Enrichers::Base>] klass
42
70
  #
43
71
  # @return [Mihari::Structs::Config, nil] config
44
72
  #
45
73
  def from_class(klass)
46
74
  return nil if klass == Mihari::Analyzers::Rule
47
75
 
48
- name = klass.to_s.split("::").last.to_s
49
-
50
- is_analyzer = klass.ancestors.include?(Mihari::Analyzers::Base)
51
- is_emitter = klass.ancestors.include?(Mihari::Emitters::Base)
52
- is_enricher = klass.ancestors.include?(Mihari::Enrichers::Base)
53
-
54
- type = "Analyzer"
55
- type = "Emitter" if is_emitter
56
- type = "Enricher" if is_enricher
76
+ type = get_type(klass)
77
+ return nil if type.nil?
57
78
 
58
79
  begin
59
- instance = is_analyzer ? klass.new("dummy") : klass.new(artifacts: [], rule: nil)
60
- is_configured = instance.configured?
61
- values = instance.configuration_values
62
-
63
- new(name: name, values: values, is_configured: is_configured, type: type)
64
- rescue ArgumentError => _e
80
+ instance = get_dummy(klass)
81
+ new(
82
+ name: klass.to_s.split("::").last.to_s,
83
+ values: instance.configuration_values,
84
+ is_configured: instance.configured?,
85
+ type: type
86
+ )
87
+ rescue ArgumentError
65
88
  nil
66
89
  end
67
90
  end
@@ -162,7 +162,7 @@ module Mihari
162
162
  # @return [Mihari::Analyzers::Rule]
163
163
  #
164
164
  def analyzer
165
- Mihari::Analyzers::Rule.new(rule: self)
165
+ Mihari::Analyzers::Rule.new(self)
166
166
  end
167
167
 
168
168
  class << self
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "5.2.3"
4
+ VERSION = "5.2.4"
5
5
  end