mihari 5.1.1 → 5.1.3

Sign up to get free protection for your applications and to get access to all the features.
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,