mihari 5.6.0 → 5.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/binaryedge.md +1 -1
  3. data/docs/analyzers/censys.md +1 -1
  4. data/docs/analyzers/circl.md +1 -1
  5. data/docs/analyzers/crtsh.md +1 -1
  6. data/docs/analyzers/dnstwister.md +1 -1
  7. data/docs/analyzers/greynoise.md +1 -1
  8. data/docs/analyzers/hunterhow.md +1 -1
  9. data/docs/analyzers/index.md +29 -15
  10. data/docs/analyzers/onyphe.md +1 -1
  11. data/docs/analyzers/otx.md +2 -2
  12. data/docs/analyzers/passivetotal.md +2 -2
  13. data/docs/analyzers/pulsedive.md +2 -2
  14. data/docs/analyzers/securitytrails.md +2 -2
  15. data/docs/analyzers/shodan.md +1 -1
  16. data/docs/analyzers/urlscan.md +3 -3
  17. data/docs/analyzers/virustotal.md +2 -2
  18. data/docs/analyzers/virustotal_intelligence.md +4 -4
  19. data/docs/analyzers/zoomeye.md +5 -0
  20. data/docs/enrichers/google_public_dns.md +1 -1
  21. data/docs/enrichers/ipinfo.md +2 -2
  22. data/docs/enrichers/shodan.md +4 -4
  23. data/docs/enrichers/whois.md +1 -1
  24. data/frontend/package-lock.json +176 -179
  25. data/frontend/package.json +9 -9
  26. data/lib/mihari/{base.rb → actor.rb} +16 -2
  27. data/lib/mihari/analyzers/base.rb +5 -10
  28. data/lib/mihari/analyzers/censys.rb +1 -1
  29. data/lib/mihari/analyzers/circl.rb +1 -1
  30. data/lib/mihari/analyzers/crtsh.rb +1 -1
  31. data/lib/mihari/analyzers/dnstwister.rb +1 -1
  32. data/lib/mihari/analyzers/hunterhow.rb +1 -1
  33. data/lib/mihari/analyzers/otx.rb +1 -1
  34. data/lib/mihari/analyzers/passivetotal.rb +2 -2
  35. data/lib/mihari/analyzers/pulsedive.rb +2 -2
  36. data/lib/mihari/analyzers/securitytrails.rb +2 -2
  37. data/lib/mihari/analyzers/urlscan.rb +1 -1
  38. data/lib/mihari/analyzers/virustotal.rb +5 -5
  39. data/lib/mihari/analyzers/zoomeye.rb +3 -3
  40. data/lib/mihari/clients/base.rb +2 -2
  41. data/lib/mihari/clients/binaryedge.rb +3 -5
  42. data/lib/mihari/clients/censys.rb +3 -3
  43. data/lib/mihari/clients/circl.rb +5 -4
  44. data/lib/mihari/clients/crtsh.rb +5 -4
  45. data/lib/mihari/clients/dnstwister.rb +3 -2
  46. data/lib/mihari/clients/greynoise.rb +2 -2
  47. data/lib/mihari/clients/hunterhow.rb +2 -2
  48. data/lib/mihari/clients/misp.rb +1 -1
  49. data/lib/mihari/clients/onyphe.rb +2 -2
  50. data/lib/mihari/clients/otx.rb +4 -3
  51. data/lib/mihari/clients/passivetotal.rb +9 -8
  52. data/lib/mihari/clients/publsedive.rb +4 -3
  53. data/lib/mihari/clients/securitytrails.rb +8 -6
  54. data/lib/mihari/clients/shodan.rb +2 -2
  55. data/lib/mihari/clients/the_hive.rb +1 -1
  56. data/lib/mihari/clients/urlscan.rb +4 -4
  57. data/lib/mihari/clients/virustotal.rb +2 -2
  58. data/lib/mihari/clients/zoomeye.rb +2 -2
  59. data/lib/mihari/commands/rule.rb +2 -11
  60. data/lib/mihari/commands/search.rb +1 -1
  61. data/lib/mihari/emitters/base.rb +13 -24
  62. data/lib/mihari/emitters/database.rb +7 -9
  63. data/lib/mihari/emitters/misp.rb +14 -38
  64. data/lib/mihari/emitters/slack.rb +14 -11
  65. data/lib/mihari/emitters/the_hive.rb +16 -44
  66. data/lib/mihari/emitters/webhook.rb +31 -21
  67. data/lib/mihari/enrichers/base.rb +1 -6
  68. data/lib/mihari/enrichers/whois.rb +1 -1
  69. data/lib/mihari/models/alert.rb +75 -73
  70. data/lib/mihari/models/artifact.rb +182 -180
  71. data/lib/mihari/models/autonomous_system.rb +22 -20
  72. data/lib/mihari/models/cpe.rb +21 -19
  73. data/lib/mihari/models/dns.rb +24 -22
  74. data/lib/mihari/models/geolocation.rb +22 -20
  75. data/lib/mihari/models/port.rb +21 -19
  76. data/lib/mihari/models/reverse_dns.rb +21 -19
  77. data/lib/mihari/models/rule.rb +67 -65
  78. data/lib/mihari/models/tag.rb +5 -3
  79. data/lib/mihari/models/tagging.rb +5 -3
  80. data/lib/mihari/models/whois.rb +18 -16
  81. data/lib/mihari/rule.rb +352 -0
  82. data/lib/mihari/schemas/analyzer.rb +94 -87
  83. data/lib/mihari/schemas/emitter.rb +9 -5
  84. data/lib/mihari/schemas/enricher.rb +8 -4
  85. data/lib/mihari/schemas/mixins.rb +15 -0
  86. data/lib/mihari/schemas/rule.rb +3 -10
  87. data/lib/mihari/services/alert_builder.rb +1 -1
  88. data/lib/mihari/services/alert_proxy.rb +10 -6
  89. data/lib/mihari/services/alert_runner.rb +4 -4
  90. data/lib/mihari/services/rule_builder.rb +3 -3
  91. data/lib/mihari/services/rule_runner.rb +5 -5
  92. data/lib/mihari/structs/binaryedge.rb +1 -1
  93. data/lib/mihari/structs/censys.rb +6 -6
  94. data/lib/mihari/structs/config.rb +1 -1
  95. data/lib/mihari/structs/greynoise.rb +5 -5
  96. data/lib/mihari/structs/hunterhow.rb +3 -3
  97. data/lib/mihari/structs/onyphe.rb +5 -5
  98. data/lib/mihari/structs/shodan.rb +6 -6
  99. data/lib/mihari/structs/urlscan.rb +3 -3
  100. data/lib/mihari/structs/virustotal_intelligence.rb +3 -3
  101. data/lib/mihari/version.rb +1 -1
  102. data/lib/mihari/web/endpoints/alerts.rb +4 -4
  103. data/lib/mihari/web/endpoints/artifacts.rb +6 -6
  104. data/lib/mihari/web/endpoints/rules.rb +10 -17
  105. data/lib/mihari/web/endpoints/tags.rb +2 -2
  106. data/lib/mihari/web/public/assets/{index-9cc489e6.js → index-28d4c79d.js} +48 -48
  107. data/lib/mihari/web/public/index.html +1 -1
  108. data/lib/mihari.rb +6 -8
  109. data/mihari.gemspec +1 -2
  110. data/mkdocs.yml +0 -3
  111. data/requirements.txt +1 -1
  112. metadata +8 -22
  113. data/lib/mihari/analyzers/rule.rb +0 -232
  114. data/lib/mihari/services/rule_proxy.rb +0 -182
@@ -1,88 +1,90 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- class Alert < ActiveRecord::Base
5
- has_many :taggings, dependent: :destroy
6
- has_many :artifacts, dependent: :destroy
7
- has_many :tags, through: :taggings
8
-
9
- belongs_to :rule
10
-
11
- class << self
12
- #
13
- # Search alerts
14
- #
15
- # @param [Structs::Filters::Alert::SearchFilterWithPagination] filter
16
- #
17
- # @return [Array<Alert>]
18
- #
19
- def search(filter)
20
- limit = filter.limit.to_i
21
- raise ArgumentError, "limit should be bigger than zero" unless limit.positive?
22
-
23
- page = filter.page.to_i
24
- raise ArgumentError, "page should be bigger than zero" unless page.positive?
25
-
26
- offset = (page - 1) * limit
27
-
28
- relation = build_relation(filter.without_pagination)
29
-
30
- alert_ids = relation.limit(limit).offset(offset).order(id: :desc).pluck(:id).uniq
31
- eager_load(:artifacts, :tags).where(id: [alert_ids]).order(id: :desc)
32
- end
33
-
34
- #
35
- # Count alerts
36
- #
37
- # @param [String, nil] artifact_data
38
- #
39
- # @return [Integer]
40
- #
41
- def count(filter)
42
- relation = build_relation(filter)
43
- relation.distinct("alerts.id").count
44
- end
4
+ module Models
5
+ class Alert < ActiveRecord::Base
6
+ has_many :taggings, dependent: :destroy
7
+ has_many :artifacts, dependent: :destroy
8
+ has_many :tags, through: :taggings
9
+
10
+ belongs_to :rule
11
+
12
+ class << self
13
+ #
14
+ # Search alerts
15
+ #
16
+ # @param [Structs::Filters::Alert::SearchFilterWithPagination] filter
17
+ #
18
+ # @return [Array<Alert>]
19
+ #
20
+ def search(filter)
21
+ limit = filter.limit.to_i
22
+ raise ArgumentError, "limit should be bigger than zero" unless limit.positive?
23
+
24
+ page = filter.page.to_i
25
+ raise ArgumentError, "page should be bigger than zero" unless page.positive?
26
+
27
+ offset = (page - 1) * limit
28
+
29
+ relation = build_relation(filter.without_pagination)
30
+
31
+ alert_ids = relation.limit(limit).offset(offset).order(id: :desc).pluck(:id).uniq
32
+ eager_load(:artifacts, :tags).where(id: [alert_ids]).order(id: :desc)
33
+ end
45
34
 
46
- private
47
-
48
- #
49
- # @param [Structs::Filters::Alert::SearchFilter] filter
50
- #
51
- # @return [Array<Integer>]
52
- #
53
- def get_artifact_ids_by_filter(filter)
54
- artifact_ids = []
55
-
56
- if filter.artifact_data
57
- artifact = Artifact.where(data: filter.artifact_data)
58
- artifact_ids = artifact.pluck(:id)
59
- # set invalid ID if nothing is matched with the filters
60
- artifact_ids = [-1] if artifact_ids.empty?
35
+ #
36
+ # Count alerts
37
+ #
38
+ # @param [String, nil] artifact_data
39
+ #
40
+ # @return [Integer]
41
+ #
42
+ def count(filter)
43
+ relation = build_relation(filter)
44
+ relation.distinct("alerts.id").count
61
45
  end
62
46
 
63
- artifact_ids
64
- end
47
+ private
65
48
 
66
- #
67
- # @param [Structs::Filters::Alert::SearchFilter] filter
68
- #
69
- # @return [Mihari::Alert]
70
- #
71
- def build_relation(filter)
72
- artifact_ids = get_artifact_ids_by_filter(filter)
49
+ #
50
+ # @param [Structs::Filters::Alert::SearchFilter] filter
51
+ #
52
+ # @return [Array<Integer>]
53
+ #
54
+ def get_artifact_ids_by_filter(filter)
55
+ artifact_ids = []
73
56
 
74
- relation = self
75
- relation = relation.includes(:artifacts, :tags)
57
+ if filter.artifact_data
58
+ artifact = Artifact.where(data: filter.artifact_data)
59
+ artifact_ids = artifact.pluck(:id)
60
+ # set invalid ID if nothing is matched with the filters
61
+ artifact_ids = [-1] if artifact_ids.empty?
62
+ end
76
63
 
77
- relation = relation.where(artifacts: { id: artifact_ids }) unless artifact_ids.empty?
78
- relation = relation.where(tags: { name: filter.tag_name }) if filter.tag_name
64
+ artifact_ids
65
+ end
66
+
67
+ #
68
+ # @param [Structs::Filters::Alert::SearchFilter] filter
69
+ #
70
+ # @return [Mihari::Models::Alert]
71
+ #
72
+ def build_relation(filter)
73
+ artifact_ids = get_artifact_ids_by_filter(filter)
74
+
75
+ relation = self
76
+ relation = relation.includes(:artifacts, :tags)
79
77
 
80
- relation = relation.where(rule_id: filter.rule_id) if filter.rule_id
78
+ relation = relation.where(artifacts: { id: artifact_ids }) unless artifact_ids.empty?
79
+ relation = relation.where(tags: { name: filter.tag_name }) if filter.tag_name
81
80
 
82
- relation = relation.where("alerts.created_at >= ?", filter.from_at) if filter.from_at
83
- relation = relation.where("alerts.created_at <= ?", filter.to_at) if filter.to_at
81
+ relation = relation.where(rule_id: filter.rule_id) if filter.rule_id
84
82
 
85
- relation
83
+ relation = relation.where("alerts.created_at >= ?", filter.from_at) if filter.from_at
84
+ relation = relation.where("alerts.created_at <= ?", filter.to_at) if filter.to_at
85
+
86
+ relation
87
+ end
86
88
  end
87
89
  end
88
90
  end
@@ -1,229 +1,231 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ArtifactValidator < ActiveModel::Validator
4
- def validate(record)
5
- return if record.data_type
6
-
7
- record.errors.add :data, "#{record.data} is not supported"
8
- end
9
- end
10
-
11
3
  module Mihari
12
- class Artifact < ActiveRecord::Base
13
- belongs_to :alert
4
+ module Models
5
+ class ArtifactValidator < ActiveModel::Validator
6
+ def validate(record)
7
+ return if record.data_type
14
8
 
15
- has_one :autonomous_system, dependent: :destroy
16
- has_one :geolocation, dependent: :destroy
17
- has_one :whois_record, dependent: :destroy
9
+ record.errors.add :data, "#{record.data} is not supported"
10
+ end
11
+ end
18
12
 
19
- has_many :cpes, dependent: :destroy
20
- has_many :dns_records, dependent: :destroy
21
- has_many :ports, dependent: :destroy
22
- has_many :reverse_dns_names, dependent: :destroy
13
+ class Artifact < ActiveRecord::Base
14
+ belongs_to :alert
23
15
 
24
- include ActiveModel::Validations
16
+ has_one :autonomous_system, dependent: :destroy
17
+ has_one :geolocation, dependent: :destroy
18
+ has_one :whois_record, dependent: :destroy
25
19
 
26
- validates_with ArtifactValidator
20
+ has_many :cpes, dependent: :destroy
21
+ has_many :dns_records, dependent: :destroy
22
+ has_many :ports, dependent: :destroy
23
+ has_many :reverse_dns_names, dependent: :destroy
27
24
 
28
- # @return [Array<Mihari::Tag>] Tags
29
- attr_accessor :tags
25
+ include ActiveModel::Validations
30
26
 
31
- # @return [String, nil] Rule ID
32
- attr_accessor :rule_id
27
+ validates_with ArtifactValidator
33
28
 
34
- def initialize(*args, **kwargs)
35
- attrs = args.first || kwargs
36
- data_ = attrs[:data]
29
+ # @return [Array<Mihari::Tag>] Tags
30
+ attr_accessor :tags
37
31
 
38
- raise TypeError if data_.is_a?(Array) || data_.is_a?(Hash)
32
+ # @return [String, nil] Rule ID
33
+ attr_accessor :rule_id
39
34
 
40
- super(*args, **kwargs)
35
+ def initialize(*args, **kwargs)
36
+ attrs = args.first || kwargs
37
+ data_ = attrs[:data]
41
38
 
42
- self.data_type = TypeChecker.type(data)
39
+ raise TypeError if data_.is_a?(Array) || data_.is_a?(Hash)
43
40
 
44
- @tags = []
45
- @rule_id = ""
46
- end
41
+ super(*args, **kwargs)
47
42
 
48
- #
49
- # Check uniqueness of artifact
50
- #
51
- # @param [Time, nil] base_time Base time to check decaying
52
- # @param [Integer, nil] artifact_lifetime Artifact lifetime (TTL) in seconds
53
- #
54
- # @return [Boolean] true if it is unique. Otherwise false.
55
- #
56
- def unique?(base_time: nil, artifact_lifetime: nil)
57
- artifact = self.class.joins(:alert).where(
58
- data: data,
59
- alert: { rule_id: rule_id }
60
- ).order(created_at: :desc).first
61
- return true if artifact.nil?
62
-
63
- # check whether the artifact is decayed or not
64
- return false if artifact_lifetime.nil?
65
-
66
- # use the current UTC time if base_time is not given (for testing)
67
- base_time ||= Time.now.utc
68
-
69
- decayed_at = base_time - (artifact_lifetime || -1).seconds
70
- artifact.created_at < decayed_at
71
- end
43
+ self.data_type = TypeChecker.type(data)
72
44
 
73
- #
74
- # Enrich(add) whois record
75
- #
76
- # @param [Mihari::Enrichers::Whois] enricher
77
- #
78
- def enrich_whois(enricher = Enrichers::Whois.new)
79
- return unless can_enrich_whois?
45
+ @tags = []
46
+ @rule_id = ""
47
+ end
80
48
 
81
- self.whois_record = WhoisRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
82
- end
49
+ #
50
+ # Check uniqueness of artifact
51
+ #
52
+ # @param [Time, nil] base_time Base time to check decaying
53
+ # @param [Integer, nil] artifact_lifetime Artifact lifetime (TTL) in seconds
54
+ #
55
+ # @return [Boolean] true if it is unique. Otherwise false.
56
+ #
57
+ def unique?(base_time: nil, artifact_lifetime: nil)
58
+ artifact = self.class.joins(:alert).where(
59
+ data: data,
60
+ alert: { rule_id: rule_id }
61
+ ).order(created_at: :desc).first
62
+ return true if artifact.nil?
63
+
64
+ # check whether the artifact is decayed or not
65
+ return false if artifact_lifetime.nil?
66
+
67
+ # use the current UTC time if base_time is not given (for testing)
68
+ base_time ||= Time.now.utc
69
+
70
+ decayed_at = base_time - (artifact_lifetime || -1).seconds
71
+ artifact.created_at < decayed_at
72
+ end
83
73
 
84
- #
85
- # Enrich(add) DNS records
86
- #
87
- # @param [Mihari::Enrichers::GooglePublicDNS] enricher
88
- #
89
- def enrich_dns(enricher = Enrichers::GooglePublicDNS.new)
90
- return unless can_enrich_dns?
74
+ #
75
+ # Enrich(add) whois record
76
+ #
77
+ # @param [Mihari::Enrichers::Whois] enricher
78
+ #
79
+ def enrich_whois(enricher = Enrichers::Whois.new)
80
+ return unless can_enrich_whois?
91
81
 
92
- self.dns_records = DnsRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
93
- end
82
+ self.whois_record = WhoisRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
83
+ end
94
84
 
95
- #
96
- # Enrich(add) reverse DNS names
97
- #
98
- # @param [Mihari::Enrichers::Shodan] enricher
99
- #
100
- def enrich_reverse_dns(enricher = Enrichers::Shodan.new)
101
- return unless can_enrich_revese_dns?
85
+ #
86
+ # Enrich(add) DNS records
87
+ #
88
+ # @param [Mihari::Enrichers::GooglePublicDNS] enricher
89
+ #
90
+ def enrich_dns(enricher = Enrichers::GooglePublicDNS.new)
91
+ return unless can_enrich_dns?
102
92
 
103
- self.reverse_dns_names = ReverseDnsName.build_by_ip(data, enricher: enricher)
104
- end
93
+ self.dns_records = DnsRecord.build_by_domain(normalize_as_domain(data), enricher: enricher)
94
+ end
105
95
 
106
- #
107
- # Enrich(add) geolocation
108
- #
109
- # @param [Mihari::Enrichers::IPInfo] enricher
110
- #
111
- def enrich_geolocation(enricher = Enrichers::IPInfo.new)
112
- return unless can_enrich_geolocation?
96
+ #
97
+ # Enrich(add) reverse DNS names
98
+ #
99
+ # @param [Mihari::Enrichers::Shodan] enricher
100
+ #
101
+ def enrich_reverse_dns(enricher = Enrichers::Shodan.new)
102
+ return unless can_enrich_revese_dns?
113
103
 
114
- self.geolocation = Geolocation.build_by_ip(data, enricher: enricher)
115
- end
104
+ self.reverse_dns_names = ReverseDnsName.build_by_ip(data, enricher: enricher)
105
+ end
116
106
 
117
- #
118
- # Enrich AS
119
- #
120
- # @param [Mihari::Enrichers::IPInfo] enricher
121
- #
122
- def enrich_autonomous_system(enricher = Enrichers::IPInfo.new)
123
- return unless can_enrich_autonomous_system?
107
+ #
108
+ # Enrich(add) geolocation
109
+ #
110
+ # @param [Mihari::Enrichers::IPInfo] enricher
111
+ #
112
+ def enrich_geolocation(enricher = Enrichers::IPInfo.new)
113
+ return unless can_enrich_geolocation?
124
114
 
125
- self.autonomous_system = AutonomousSystem.build_by_ip(data, enricher: enricher)
126
- end
115
+ self.geolocation = Geolocation.build_by_ip(data, enricher: enricher)
116
+ end
127
117
 
128
- #
129
- # Enrich ports
130
- #
131
- # @param [Mihari::Enrichers::Shodan] enricher
132
- #
133
- def enrich_ports(enricher = Enrichers::Shodan.new)
134
- return unless can_enrich_ports?
118
+ #
119
+ # Enrich AS
120
+ #
121
+ # @param [Mihari::Enrichers::IPInfo] enricher
122
+ #
123
+ def enrich_autonomous_system(enricher = Enrichers::IPInfo.new)
124
+ return unless can_enrich_autonomous_system?
135
125
 
136
- self.ports = Port.build_by_ip(data, enricher: enricher)
137
- end
126
+ self.autonomous_system = AutonomousSystem.build_by_ip(data, enricher: enricher)
127
+ end
138
128
 
139
- #
140
- # Enrich CPEs
141
- #
142
- # @param [Mihari::Enrichers::Shodan] enricher
143
- #
144
- def enrich_cpes(enricher = Enrichers::Shodan.new)
145
- return unless can_enrich_cpes?
129
+ #
130
+ # Enrich ports
131
+ #
132
+ # @param [Mihari::Enrichers::Shodan] enricher
133
+ #
134
+ def enrich_ports(enricher = Enrichers::Shodan.new)
135
+ return unless can_enrich_ports?
146
136
 
147
- self.cpes = CPE.build_by_ip(data, enricher: enricher)
148
- end
137
+ self.ports = Port.build_by_ip(data, enricher: enricher)
138
+ end
149
139
 
150
- #
151
- # Enrich all the enrichable relationships of the artifact
152
- #
153
- def enrich_all
154
- enrich_autonomous_system
155
- enrich_dns
156
- enrich_geolocation
157
- enrich_reverse_dns
158
- enrich_whois
159
- enrich_ports
160
- enrich_cpes
161
- end
140
+ #
141
+ # Enrich CPEs
142
+ #
143
+ # @param [Mihari::Enrichers::Shodan] enricher
144
+ #
145
+ def enrich_cpes(enricher = Enrichers::Shodan.new)
146
+ return unless can_enrich_cpes?
162
147
 
163
- ENRICH_METHODS_BY_ENRICHER = {
164
- Enrichers::Whois => %i[
165
- enrich_whois
166
- ],
167
- Enrichers::IPInfo => %i[
148
+ self.cpes = CPE.build_by_ip(data, enricher: enricher)
149
+ end
150
+
151
+ #
152
+ # Enrich all the enrichable relationships of the artifact
153
+ #
154
+ def enrich_all
168
155
  enrich_autonomous_system
156
+ enrich_dns
169
157
  enrich_geolocation
170
- ],
171
- Enrichers::Shodan => %i[
158
+ enrich_reverse_dns
159
+ enrich_whois
172
160
  enrich_ports
173
161
  enrich_cpes
174
- enrich_reverse_dns
175
- ],
176
- Enrichers::GooglePublicDNS => %i[
177
- enrich_dns
178
- ]
179
- }.freeze
180
-
181
- #
182
- # Enrich by name of enricher
183
- #
184
- # @param [Mihari::Enrichers::Base] enricher
185
- #
186
- def enrich_by_enricher(enricher)
187
- methods = ENRICH_METHODS_BY_ENRICHER[enricher.class] || []
188
- methods.each do |method|
189
- send(method, enricher) if respond_to?(method)
190
162
  end
191
- end
192
163
 
193
- private
164
+ ENRICH_METHODS_BY_ENRICHER = {
165
+ Enrichers::Whois => %i[
166
+ enrich_whois
167
+ ],
168
+ Enrichers::IPInfo => %i[
169
+ enrich_autonomous_system
170
+ enrich_geolocation
171
+ ],
172
+ Enrichers::Shodan => %i[
173
+ enrich_ports
174
+ enrich_cpes
175
+ enrich_reverse_dns
176
+ ],
177
+ Enrichers::GooglePublicDNS => %i[
178
+ enrich_dns
179
+ ]
180
+ }.freeze
181
+
182
+ #
183
+ # Enrich by name of enricher
184
+ #
185
+ # @param [Mihari::Enrichers::Base] enricher
186
+ #
187
+ def enrich_by_enricher(enricher)
188
+ methods = ENRICH_METHODS_BY_ENRICHER[enricher.class] || []
189
+ methods.each do |method|
190
+ send(method, enricher) if respond_to?(method)
191
+ end
192
+ end
194
193
 
195
- def normalize_as_domain(url_or_domain)
196
- return url_or_domain if data_type == "domain"
194
+ private
197
195
 
198
- Addressable::URI.parse(url_or_domain).host
199
- end
196
+ def normalize_as_domain(url_or_domain)
197
+ return url_or_domain if data_type == "domain"
200
198
 
201
- def can_enrich_whois?
202
- %w[domain url].include?(data_type) && whois_record.nil?
203
- end
199
+ Addressable::URI.parse(url_or_domain).host
200
+ end
204
201
 
205
- def can_enrich_dns?
206
- %w[domain url].include?(data_type) && dns_records.empty?
207
- end
202
+ def can_enrich_whois?
203
+ %w[domain url].include?(data_type) && whois_record.nil?
204
+ end
208
205
 
209
- def can_enrich_revese_dns?
210
- data_type == "ip" && reverse_dns_names.empty?
211
- end
206
+ def can_enrich_dns?
207
+ %w[domain url].include?(data_type) && dns_records.empty?
208
+ end
212
209
 
213
- def can_enrich_geolocation?
214
- data_type == "ip" && geolocation.nil?
215
- end
210
+ def can_enrich_revese_dns?
211
+ data_type == "ip" && reverse_dns_names.empty?
212
+ end
216
213
 
217
- def can_enrich_autonomous_system?
218
- data_type == "ip" && autonomous_system.nil?
219
- end
214
+ def can_enrich_geolocation?
215
+ data_type == "ip" && geolocation.nil?
216
+ end
220
217
 
221
- def can_enrich_ports?
222
- data_type == "ip" && ports.empty?
223
- end
218
+ def can_enrich_autonomous_system?
219
+ data_type == "ip" && autonomous_system.nil?
220
+ end
224
221
 
225
- def can_enrich_cpes?
226
- data_type == "ip" && cpes.empty?
222
+ def can_enrich_ports?
223
+ data_type == "ip" && ports.empty?
224
+ end
225
+
226
+ def can_enrich_cpes?
227
+ data_type == "ip" && cpes.empty?
228
+ end
227
229
  end
228
230
  end
229
231
  end
@@ -1,30 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- class AutonomousSystem < ActiveRecord::Base
5
- belongs_to :artifact
4
+ module Models
5
+ class AutonomousSystem < ActiveRecord::Base
6
+ belongs_to :artifact
6
7
 
7
- class << self
8
- include Dry::Monads[:result]
8
+ class << self
9
+ include Dry::Monads[:result]
9
10
 
10
- #
11
- # Build AS
12
- #
13
- # @param [String] ip
14
- # @param [Mihari::Enrichers::IPInfo] enricher
15
- #
16
- # @return [Mihari::AutonomousSystem, nil]
17
- #
18
- def build_by_ip(ip, enricher: Enrichers::IPInfo.new)
19
- result = enricher.query_result(ip).bind do |res|
20
- value = res&.asn
21
- if value.nil?
22
- Success nil
23
- else
24
- Success new(asn: value)
11
+ #
12
+ # Build AS
13
+ #
14
+ # @param [String] ip
15
+ # @param [Mihari::Enrichers::IPInfo] enricher
16
+ #
17
+ # @return [Mihari::AutonomousSystem, nil]
18
+ #
19
+ def build_by_ip(ip, enricher: Enrichers::IPInfo.new)
20
+ result = enricher.query_result(ip).bind do |res|
21
+ value = res&.asn
22
+ if value.nil?
23
+ Success nil
24
+ else
25
+ Success new(asn: value)
26
+ end
25
27
  end
28
+ result.value_or nil
26
29
  end
27
- result.value_or nil
28
30
  end
29
31
  end
30
32
  end