mihari 5.1.1 → 5.1.3

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/.rubocop.yml +6 -0
  4. data/README.md +0 -1
  5. data/lib/mihari/analyzers/base.rb +32 -27
  6. data/lib/mihari/analyzers/binaryedge.rb +8 -2
  7. data/lib/mihari/analyzers/censys.rb +10 -61
  8. data/lib/mihari/analyzers/circl.rb +13 -19
  9. data/lib/mihari/analyzers/crtsh.rb +6 -0
  10. data/lib/mihari/analyzers/dnstwister.rb +12 -19
  11. data/lib/mihari/analyzers/feed.rb +21 -0
  12. data/lib/mihari/analyzers/greynoise.rb +5 -28
  13. data/lib/mihari/analyzers/onyphe.rb +8 -33
  14. data/lib/mihari/analyzers/otx.rb +11 -17
  15. data/lib/mihari/analyzers/passivetotal.rb +13 -19
  16. data/lib/mihari/analyzers/pulsedive.rb +3 -1
  17. data/lib/mihari/analyzers/rule.rb +0 -1
  18. data/lib/mihari/analyzers/securitytrails.rb +18 -29
  19. data/lib/mihari/analyzers/shodan.rb +13 -92
  20. data/lib/mihari/analyzers/urlscan.rb +12 -4
  21. data/lib/mihari/analyzers/virustotal.rb +4 -0
  22. data/lib/mihari/analyzers/virustotal_intelligence.rb +9 -6
  23. data/lib/mihari/analyzers/zoomeye.rb +9 -0
  24. data/lib/mihari/clients/binaryedge.rb +5 -0
  25. data/lib/mihari/clients/censys.rb +4 -4
  26. data/lib/mihari/clients/circl.rb +3 -3
  27. data/lib/mihari/clients/greynoise.rb +6 -1
  28. data/lib/mihari/clients/misp.rb +8 -1
  29. data/lib/mihari/clients/onyphe.rb +13 -1
  30. data/lib/mihari/clients/otx.rb +20 -0
  31. data/lib/mihari/clients/passivetotal.rb +6 -2
  32. data/lib/mihari/clients/publsedive.rb +18 -1
  33. data/lib/mihari/clients/securitytrails.rb +94 -0
  34. data/lib/mihari/clients/shodan.rb +14 -3
  35. data/lib/mihari/clients/the_hive.rb +6 -1
  36. data/lib/mihari/clients/urlscan.rb +3 -1
  37. data/lib/mihari/clients/virustotal.rb +9 -3
  38. data/lib/mihari/clients/zoomeye.rb +7 -1
  39. data/lib/mihari/commands/database.rb +1 -6
  40. data/lib/mihari/commands/searcher.rb +1 -2
  41. data/lib/mihari/database.rb +9 -0
  42. data/lib/mihari/http.rb +14 -18
  43. data/lib/mihari/structs/censys.rb +62 -0
  44. data/lib/mihari/structs/greynoise.rb +43 -0
  45. data/lib/mihari/structs/onyphe.rb +45 -0
  46. data/lib/mihari/structs/shodan.rb +83 -0
  47. data/lib/mihari/version.rb +1 -1
  48. data/lib/mihari/web/middleware/connection_adapter.rb +1 -3
  49. data/lib/mihari/web/public/assets/{index-63900d73.js → index-7d0fb8c4.js} +2 -2
  50. data/lib/mihari/web/public/index.html +1 -1
  51. data/lib/mihari/web/public/redoc-static.html +2 -2
  52. data/lib/mihari.rb +1 -3
  53. data/mihari.gemspec +2 -3
  54. metadata +8 -24
  55. data/lib/mihari/analyzers/dnpedia.rb +0 -33
  56. data/lib/mihari/clients/dnpedia.rb +0 -64
  57. data/lib/mihari/mixins/database.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e19317302956178dc4302543d81a0920018aa384595f91c69dd70110086d575a
4
- data.tar.gz: 80d6314c2df13a4a28ec71a0d4b358e74ab0ee9778d818658a997c1fd821f062
3
+ metadata.gz: dd278975834369b3274b38b590f12d4f2fed97d7626363ff3cfbc9845195b386
4
+ data.tar.gz: 864ee1deae0bdb0390d9e330eb76c993860c37189dce0d23c9793b012f338275
5
5
  SHA512:
6
- metadata.gz: b54bffc456bc114a2a8b52e5acbcc3f30d7571124fc9431fbda209bb57910eabe7950d86c50ef750c41d5df604a5aa08c9affb25d434db8a4f53d85ba8ae4921
7
- data.tar.gz: 4bce535d8d6d2573102b0197984854b84628a08ab37855c2a7f7fb1574b701e6b4ca816d3b23b3719d7cde0b7de89753af3b386d43af39e422c7c06b1d65448c
6
+ metadata.gz: 258731713400cb40f6da8f24e6ce0213b883eeff98a22a16a88c84568633ad02ad3e18f4e70e6faea428a29bdcdc257b6ec3c86ebea7979065ec2e42ab445c47
7
+ data.tar.gz: 6c8beea0c3f4aa42f8fb8217a05c6256a6a8ea10daceb05d05ed2884d8b53c86195c765fa70cf35ea19c41d959fd6df114fa2b609893e828def028f5b16b5fc4
data/.gitmodules CHANGED
@@ -1,3 +0,0 @@
1
- [submodule "vendor/rbs/gem_rbs_collection"]
2
- path = vendor/rbs/gem_rbs_collection
3
- url = https://github.com/ruby/gem_rbs_collection.git
data/.rubocop.yml CHANGED
@@ -2,3 +2,9 @@ Style/HashSyntax:
2
2
  EnforcedShorthandSyntax: either
3
3
  Style/StringLiterals:
4
4
  EnforcedStyle: double_quotes
5
+ Metrics/BlockLength:
6
+ Exclude:
7
+ - "spec/**/*"
8
+ - "*.gemspec"
9
+ Metrics/ClassLength:
10
+ Enabled: false
data/README.md CHANGED
@@ -45,7 +45,6 @@ Mihari supports the following services by default.
45
45
  - [Censys](http://censys.io)
46
46
  - [CIRCL passive DNS](https://www.circl.lu/services/passive-dns/) / [passive SSL](https://www.circl.lu/services/passive-ssl/)
47
47
  - [crt.sh](https://crt.sh/)
48
- - [DN Pedia](https://dnpedia.com/)
49
48
  - [dnstwister](https://dnstwister.report/)
50
49
  - [GreyNoise](https://www.greynoise.io/)
51
50
  - [Onyphe](https://onyphe.io)
@@ -7,7 +7,6 @@ module Mihari
7
7
 
8
8
  option :rule, default: proc {}
9
9
 
10
- include Mixins::AutonomousSystem
11
10
  include Mixins::Configurable
12
11
  include Mixins::Retriable
13
12
 
@@ -20,6 +19,15 @@ module Mihari
20
19
  @base_time = Time.now.utc
21
20
  end
22
21
 
22
+ #
23
+ # Load/overwrite rule
24
+ #
25
+ # @param [String] path_or_id
26
+ #
27
+ def load_rule(path_or_id)
28
+ @rule = Structs::Rule.from_path_or_id path_or_id
29
+ end
30
+
23
31
  # @return [Array<String>, Array<Mihari::Artifact>]
24
32
  def artifacts
25
33
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
@@ -30,35 +38,41 @@ module Mihari
30
38
  self.class.to_s.split("::").last.to_s
31
39
  end
32
40
 
41
+ # @return [String]
42
+ def class_name
43
+ self.class.to_s.split("::").last
44
+ end
45
+
33
46
  #
34
47
  # Set artifacts & run emitters in parallel
35
48
  #
36
49
  # @return [Mihari::Alert, nil]
37
50
  #
38
51
  def run
39
- unless configured?
40
- class_name = self.class.to_s.split("::").last
41
- raise ConfigurationError, "#{class_name} is not configured correctly"
42
- end
43
-
44
- set_enriched_artifacts
45
-
46
- responses = Parallel.map(valid_emitters) do |emitter|
47
- run_emitter emitter
48
- end
52
+ raise ConfigurationError, "#{class_name} is not configured correctly" unless configured?
49
53
 
54
+ alert_or_something = bulk_emit
50
55
  # returns Mihari::Alert created by the database emitter
51
- responses.find { |res| res.is_a?(Mihari::Alert) }
56
+ alert_or_something.find { |res| res.is_a?(Mihari::Alert) }
52
57
  end
53
58
 
54
59
  #
55
- # Run emitter
60
+ # Bulk emit
61
+ #
62
+ # @return [Array<Mihari::Alert>]
63
+ #
64
+ def bulk_emit
65
+ Parallel.map(valid_emitters) { |emitter| emit emitter }.compact
66
+ end
67
+
68
+ #
69
+ # Emit an alert
56
70
  #
57
71
  # @param [Mihari::Emitters::Base] emitter
58
72
  #
59
73
  # @return [Mihari::Alert, nil]
60
74
  #
61
- def run_emitter(emitter)
75
+ def emit(emitter)
62
76
  return if enriched_artifacts.empty?
63
77
 
64
78
  alert_or_something = emitter.run(artifacts: enriched_artifacts, rule: rule)
@@ -80,6 +94,7 @@ module Mihari
80
94
  #
81
95
  # Normalize artifacts
82
96
  # - Convert data (string) into an artifact
97
+ # - Set rule ID
83
98
  # - Reject an invalid artifact
84
99
  # - Uniquefy artifacts by data
85
100
  #
@@ -89,17 +104,16 @@ module Mihari
89
104
  @normalized_artifacts ||= artifacts.compact.sort.map do |artifact|
90
105
  # No need to set data_type manually
91
106
  # It is set automatically in #initialize
92
- artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact, source: source)
93
- end.select(&:valid?).uniq(&:data).map do |artifact|
107
+ artifact = artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact, source: source)
94
108
  artifact.rule_id = rule&.id
95
109
  artifact
96
- end
110
+ end.select(&:valid?).uniq(&:data)
97
111
  end
98
112
 
99
113
  private
100
114
 
101
115
  #
102
- # Uniquefy artifacts
116
+ # Uniquefy artifacts (assure rule level uniqueness)
103
117
  #
104
118
  # @return [Array<Mihari::Artifact>]
105
119
  #
@@ -121,15 +135,6 @@ module Mihari
121
135
  end
122
136
  end
123
137
 
124
- #
125
- # Set enriched artifacts
126
- #
127
- # @return [nil]
128
- #
129
- def set_enriched_artifacts
130
- retry_on_error { enriched_artifacts }
131
- end
132
-
133
138
  #
134
139
  # Select valid emitters
135
140
  #
@@ -10,6 +10,12 @@ module Mihari
10
10
  # @return [String, nil]
11
11
  attr_reader :api_key
12
12
 
13
+ # @return [String]
14
+ attr_reader :query
15
+
16
+ # @return [Integer]
17
+ attr_reader :interval
18
+
13
19
  def initialize(*args, **kwargs)
14
20
  super(*args, **kwargs)
15
21
 
@@ -41,7 +47,7 @@ module Mihari
41
47
  #
42
48
  # @return [Hash]
43
49
  #
44
- def search_with_page(query, page: 1)
50
+ def search_with_page(page: 1)
45
51
  client.search(query, page: page)
46
52
  rescue UnsuccessfulStatusCodeError => e
47
53
  raise RetryableError, e if e.message.include?("Request time limit exceeded")
@@ -57,7 +63,7 @@ module Mihari
57
63
  def search
58
64
  responses = []
59
65
  (1..500).each do |page|
60
- res = search_with_page(query, page: page)
66
+ res = search_with_page(page: page)
61
67
  total = res["total"].to_i
62
68
 
63
69
  responses << res
@@ -13,6 +13,12 @@ module Mihari
13
13
  # @return [String, nil]
14
14
  attr_reader :secret
15
15
 
16
+ # @return [Integer]
17
+ attr_reader :interval
18
+
19
+ # @return [String]
20
+ attr_reader :query
21
+
16
22
  def initialize(*args, **kwargs)
17
23
  super(*args, **kwargs)
18
24
 
@@ -21,30 +27,12 @@ module Mihari
21
27
  end
22
28
 
23
29
  def artifacts
24
- search
25
- end
26
-
27
- def configured?
28
- configuration_keys.all? { |key| Mihari.config.send(key) } || (id? && secret?)
29
- end
30
-
31
- private
32
-
33
- #
34
- # Search
35
- #
36
- # @return [Array<String>]
37
- #
38
- def search
39
30
  artifacts = []
40
31
 
41
32
  cursor = nil
42
33
  loop do
43
34
  response = client.search(query, cursor: cursor)
44
- response = Structs::Censys::Response.from_dynamic!(response)
45
-
46
- artifacts << response_to_artifacts(response)
47
-
35
+ artifacts << response.result.to_artifacts(source)
48
36
  cursor = response.result.links.next
49
37
  break if cursor == ""
50
38
 
@@ -55,50 +43,11 @@ module Mihari
55
43
  artifacts.flatten.uniq(&:data)
56
44
  end
57
45
 
58
- #
59
- # Extract IPv4s from Censys search API response
60
- #
61
- # @param [Structs::Censys::Response] response
62
- #
63
- # @return [Array<String>]
64
- #
65
- def response_to_artifacts(response)
66
- response.result.hits.map { |hit| build_artifact(hit) }
46
+ def configured?
47
+ configuration_keys.all? { |key| Mihari.config.send(key) } || (id? && secret?)
67
48
  end
68
49
 
69
- #
70
- # Build an artifact from a Shodan search API response
71
- #
72
- # @param [Structs::Censys::Hit] hit
73
- #
74
- # @return [Artifact]
75
- #
76
- def build_artifact(hit)
77
- as = AutonomousSystem.new(asn: normalize_asn(hit.autonomous_system.asn))
78
-
79
- # sometimes Censys overlooks country
80
- # then set geolocation as nil
81
- geolocation = nil
82
- unless hit.location.country.nil?
83
- geolocation = Geolocation.new(
84
- country: hit.location.country,
85
- country_code: hit.location.country_code
86
- )
87
- end
88
-
89
- ports = hit.services.map(&:port).map do |port|
90
- Port.new(port: port)
91
- end
92
-
93
- Artifact.new(
94
- data: hit.ip,
95
- source: source,
96
- metadata: hit.metadata,
97
- autonomous_system: as,
98
- geolocation: geolocation,
99
- ports: ports
100
- )
101
- end
50
+ private
102
51
 
103
52
  def configuration_keys
104
53
  %w[censys_id censys_secret]
@@ -16,6 +16,9 @@ module Mihari
16
16
  # @return [String, nil]
17
17
  attr_reader :password
18
18
 
19
+ # @return [String]
20
+ attr_reader :query
21
+
19
22
  def initialize(*args, **kwargs)
20
23
  super
21
24
 
@@ -27,7 +30,14 @@ module Mihari
27
30
  end
28
31
 
29
32
  def artifacts
30
- search || []
33
+ case type
34
+ when "domain"
35
+ passive_dns_search
36
+ when "hash"
37
+ passive_ssl_search
38
+ else
39
+ raise InvalidInputError, "#{@query}(type: #{@type || "unknown"}) is not supported."
40
+ end
31
41
  end
32
42
 
33
43
  def configured?
@@ -44,29 +54,13 @@ module Mihari
44
54
  @client ||= Clients::CIRCL.new(username: username, password: password)
45
55
  end
46
56
 
47
- #
48
- # Passive DNS/SSL search
49
- #
50
- # @return [Array<String>]
51
- #
52
- def search
53
- case @type
54
- when "domain"
55
- passive_dns_search
56
- when "hash"
57
- passive_ssl_search
58
- else
59
- raise InvalidInputError, "#{@query}(type: #{@type || "unknown"}) is not supported."
60
- end
61
- end
62
-
63
57
  #
64
58
  # Passive DNS search
65
59
  #
66
60
  # @return [Array<String>]
67
61
  #
68
62
  def passive_dns_search
69
- results = client.dns_query(@query)
63
+ results = client.dns_query(query)
70
64
  results.filter_map do |result|
71
65
  type = result["rrtype"]
72
66
  (type == "A") ? result["rdata"] : nil
@@ -79,7 +73,7 @@ module Mihari
79
73
  # @return [Array<String>]
80
74
  #
81
75
  def passive_ssl_search
82
- result = client.ssl_cquery(@query)
76
+ result = client.ssl_cquery(query)
83
77
  seen = result["seen"] || []
84
78
  seen.uniq
85
79
  end
@@ -7,6 +7,12 @@ module Mihari
7
7
 
8
8
  option :exclude_expired, default: proc { true }
9
9
 
10
+ # @return [Boolean]
11
+ attr_reader :exclude_expired
12
+
13
+ # @return [String]
14
+ attr_reader :query
15
+
10
16
  def artifacts
11
17
  results = search
12
18
  results.map do |result|
@@ -7,10 +7,12 @@ module Mihari
7
7
 
8
8
  param :query
9
9
 
10
- option :tags, default: proc { [] }
11
-
10
+ # @return [String]
12
11
  attr_reader :type
13
12
 
13
+ # @return [String]
14
+ attr_reader :query
15
+
14
16
  def initialize(*args, **kwargs)
15
17
  super
16
18
 
@@ -19,7 +21,14 @@ module Mihari
19
21
  end
20
22
 
21
23
  def artifacts
22
- search || []
24
+ raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
25
+
26
+ res = client.fuzz(query)
27
+ fuzzy_domains = res["fuzzy_domains"] || []
28
+ domains = fuzzy_domains.map { |domain| domain["domain"] }
29
+ Parallel.map(domains) do |domain|
30
+ resolvable?(domain) ? domain : nil
31
+ end.compact
23
32
  end
24
33
 
25
34
  private
@@ -50,22 +59,6 @@ module Mihari
50
59
  rescue Resolv::ResolvError => _e
51
60
  false
52
61
  end
53
-
54
- #
55
- # Search
56
- #
57
- # @return [Array<String>]
58
- #
59
- def search
60
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
61
-
62
- res = client.fuzz(query)
63
- fuzzy_domains = res["fuzzy_domains"] || []
64
- domains = fuzzy_domains.map { |domain| domain["domain"] }
65
- Parallel.map(domains) do |domain|
66
- resolvable?(domain) ? domain : nil
67
- end.compact
68
- end
69
62
  end
70
63
  end
71
64
  end
@@ -16,6 +16,27 @@ module Mihari
16
16
 
17
17
  option :selector, default: proc { "" }
18
18
 
19
+ # @return [Hash, nil]
20
+ attr_reader :data
21
+
22
+ # @return [Hash, nil]
23
+ attr_reader :json
24
+
25
+ # @return [Hash, nil]
26
+ attr_reader :params
27
+
28
+ # @return [Hash, nil]
29
+ attr_reader :headers
30
+
31
+ # @return [String]
32
+ attr_reader :method
33
+
34
+ # @return [String]
35
+ attr_reader :selector
36
+
37
+ # @return [String]
38
+ attr_reader :query
39
+
19
40
  def artifacts
20
41
  Mihari::Feed::Parser.new(results).parse selector
21
42
  end
@@ -8,6 +8,9 @@ module Mihari
8
8
  # @return [String, nil]
9
9
  attr_reader :api_key
10
10
 
11
+ # @return [String]
12
+ attr_reader :query
13
+
11
14
  def initialize(*args, **kwargs)
12
15
  super(*args, **kwargs)
13
16
 
@@ -15,10 +18,8 @@ module Mihari
15
18
  end
16
19
 
17
20
  def artifacts
18
- res = Structs::GreyNoise::Response.from_dynamic!(search)
19
- res.data.map do |datum|
20
- build_artifact datum
21
- end
21
+ res = search
22
+ res.to_artifacts
22
23
  end
23
24
 
24
25
  private
@@ -41,30 +42,6 @@ module Mihari
41
42
  def search
42
43
  client.gnql_search(query, size: PAGE_SIZE)
43
44
  end
44
-
45
- #
46
- # Build an artifact from a GreyNoise search API response
47
- #
48
- # @param [Structs::GreyNoise::Datum] datum
49
- #
50
- # @return [Artifact]
51
- #
52
- def build_artifact(datum)
53
- as = AutonomousSystem.new(asn: normalize_asn(datum.metadata.asn))
54
-
55
- geolocation = Geolocation.new(
56
- country: datum.metadata.country,
57
- country_code: datum.metadata.country_code
58
- )
59
-
60
- Artifact.new(
61
- data: datum.ip,
62
- source: source,
63
- metadata: datum.metadata_,
64
- autonomous_system: as,
65
- geolocation: geolocation
66
- )
67
- end
68
45
  end
69
46
  end
70
47
  end
@@ -12,6 +12,12 @@ module Mihari
12
12
  # @return [String, nil]
13
13
  attr_reader :api_key
14
14
 
15
+ # @return [String]
16
+ attr_reader :query
17
+
18
+ # @return [Integer]
19
+ attr_reader :interval
20
+
15
21
  def initialize(*args, **kwargs)
16
22
  super(*args, **kwargs)
17
23
 
@@ -22,10 +28,7 @@ module Mihari
22
28
  responses = search
23
29
  return [] unless responses
24
30
 
25
- results = responses.map(&:results).flatten
26
- results.map do |result|
27
- build_artifact result
28
- end
31
+ responses.map { |response| response.to_artifacts(source) }.flatten
29
32
  end
30
33
 
31
34
  private
@@ -49,8 +52,7 @@ module Mihari
49
52
  # @return [Structs::Onyphe::Response]
50
53
  #
51
54
  def search_with_page(query, page: 1)
52
- res = client.datascan(query, page: page)
53
- Structs::Onyphe::Response.from_dynamic!(res)
55
+ client.datascan(query, page: page)
54
56
  end
55
57
 
56
58
  #
@@ -72,33 +74,6 @@ module Mihari
72
74
  end
73
75
  responses
74
76
  end
75
-
76
- #
77
- # Build an artifact from an Onyphe search API result
78
- #
79
- # @param [Structs::Onyphe::Result] result
80
- #
81
- # @return [Artifact]
82
- #
83
- def build_artifact(result)
84
- as = AutonomousSystem.new(asn: normalize_asn(result.asn))
85
-
86
- geolocation = nil
87
- unless result.country_code.nil?
88
- geolocation = Geolocation.new(
89
- country: NormalizeCountry(result.country_code, to: :short),
90
- country_code: result.country_code
91
- )
92
- end
93
-
94
- Artifact.new(
95
- data: result.ip,
96
- source: source,
97
- metadata: result.metadata,
98
- autonomous_system: as,
99
- geolocation: geolocation
100
- )
101
- end
102
77
  end
103
78
  end
104
79
  end
@@ -13,6 +13,9 @@ module Mihari
13
13
  # @return [String, nil]
14
14
  attr_reader :api_key
15
15
 
16
+ # @return [String]
17
+ attr_reader :query
18
+
16
19
  def initialize(*args, **kwargs)
17
20
  super
18
21
 
@@ -23,7 +26,14 @@ module Mihari
23
26
  end
24
27
 
25
28
  def artifacts
26
- search || []
29
+ case type
30
+ when "domain"
31
+ domain_search
32
+ when "ip"
33
+ ip_search
34
+ else
35
+ raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
36
+ end
27
37
  end
28
38
 
29
39
  private
@@ -45,22 +55,6 @@ module Mihari
45
55
  %w[ip domain].include? type
46
56
  end
47
57
 
48
- #
49
- # IP/domain search
50
- #
51
- # @return [Array<String>]
52
- #
53
- def search
54
- case type
55
- when "domain"
56
- domain_search
57
- when "ip"
58
- ip_search
59
- else
60
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
61
- end
62
- end
63
-
64
58
  #
65
59
  # Domain search
66
60
  #
@@ -16,6 +16,9 @@ module Mihari
16
16
  # @return [String, nil]
17
17
  attr_reader :api_key
18
18
 
19
+ # @return [String]
20
+ attr_reader :query
21
+
19
22
  def initialize(*args, **kwargs)
20
23
  super(*args, **kwargs)
21
24
 
@@ -27,7 +30,16 @@ module Mihari
27
30
  end
28
31
 
29
32
  def artifacts
30
- search || []
33
+ case type
34
+ when "domain", "ip"
35
+ passive_dns_search
36
+ when "mail"
37
+ reverse_whois_search
38
+ when "hash"
39
+ ssl_search
40
+ else
41
+ raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
42
+ end
31
43
  end
32
44
 
33
45
  def configured?
@@ -53,24 +65,6 @@ module Mihari
53
65
  %w[ip domain mail hash].include? type
54
66
  end
55
67
 
56
- #
57
- # Passive DNS/SSL, reverse whois search
58
- #
59
- # @return [Array<String>]
60
- #
61
- def search
62
- case type
63
- when "domain", "ip"
64
- passive_dns_search
65
- when "mail"
66
- reverse_whois_search
67
- when "hash"
68
- ssl_search
69
- else
70
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
71
- end
72
- end
73
-
74
68
  #
75
69
  # Passive DNS search
76
70
  #
@@ -13,6 +13,9 @@ module Mihari
13
13
  # @return [String, nil]
14
14
  attr_reader :api_key
15
15
 
16
+ # @return [Integer]
17
+ attr_reader :query
18
+
16
19
  def initialize(*args, **kwargs)
17
20
  super
18
21
 
@@ -55,7 +58,6 @@ module Mihari
55
58
 
56
59
  indicator = client.get_indicator(query)
57
60
  iid = indicator["iid"]
58
-
59
61
  properties = client.get_properties(iid)
60
62
  (properties["dns"] || []).filter_map do |property|
61
63
  if %w[A PTR].include?(property["name"])
@@ -7,7 +7,6 @@ module Mihari
7
7
  "censys" => Censys,
8
8
  "circl" => CIRCL,
9
9
  "crtsh" => Crtsh,
10
- "dnpedia" => DNPedia,
11
10
  "dnstwister" => DNSTwister,
12
11
  "feed" => Feed,
13
12
  "greynoise" => GreyNoise,