mihari 5.1.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5415ee0f5bb820e8073383e4771589bbbaa39fc313af3aa434c5754f34bb9056
4
- data.tar.gz: a4da4ce859fa718c900572b865518110f92649698a76ca64c55e38ebad2f9856
3
+ metadata.gz: dd278975834369b3274b38b590f12d4f2fed97d7626363ff3cfbc9845195b386
4
+ data.tar.gz: 864ee1deae0bdb0390d9e330eb76c993860c37189dce0d23c9793b012f338275
5
5
  SHA512:
6
- metadata.gz: c0b95e672f17d5ba0035624b035da278c863dc0b1a0860e3393cd8f001125964270233da7bf5ffb08c9057889b4a51698829de059089ed4d31a0f4fd7d0aa3e8
7
- data.tar.gz: 30cbba0170104212e9244dfeac820a1a223468bae940719c242778d5bffd95b147f482548aebcc2386713fe43cc0c1b97bf2d71d08d318ad62a4b1a707f3e605
6
+ metadata.gz: 258731713400cb40f6da8f24e6ce0213b883eeff98a22a16a88c84568633ad02ad3e18f4e70e6faea428a29bdcdc257b6ec3c86ebea7979065ec2e42ab445c47
7
+ data.tar.gz: 6c8beea0c3f4aa42f8fb8217a05c6256a6a8ea10daceb05d05ed2884d8b53c86195c765fa70cf35ea19c41d959fd6df114fa2b609893e828def028f5b16b5fc4
@@ -27,21 +27,6 @@ module Mihari
27
27
  end
28
28
 
29
29
  def artifacts
30
- search
31
- end
32
-
33
- def configured?
34
- configuration_keys.all? { |key| Mihari.config.send(key) } || (id? && secret?)
35
- end
36
-
37
- private
38
-
39
- #
40
- # Search
41
- #
42
- # @return [Array<String>]
43
- #
44
- def search
45
30
  artifacts = []
46
31
 
47
32
  cursor = nil
@@ -58,6 +43,12 @@ module Mihari
58
43
  artifacts.flatten.uniq(&:data)
59
44
  end
60
45
 
46
+ def configured?
47
+ configuration_keys.all? { |key| Mihari.config.send(key) } || (id? && secret?)
48
+ end
49
+
50
+ private
51
+
61
52
  def configuration_keys
62
53
  %w[censys_id censys_secret]
63
54
  end
@@ -30,7 +30,14 @@ module Mihari
30
30
  end
31
31
 
32
32
  def artifacts
33
- 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
34
41
  end
35
42
 
36
43
  def configured?
@@ -47,22 +54,6 @@ module Mihari
47
54
  @client ||= Clients::CIRCL.new(username: username, password: password)
48
55
  end
49
56
 
50
- #
51
- # Passive DNS/SSL search
52
- #
53
- # @return [Array<String>]
54
- #
55
- def search
56
- case @type
57
- when "domain"
58
- passive_dns_search
59
- when "hash"
60
- passive_ssl_search
61
- else
62
- raise InvalidInputError, "#{@query}(type: #{@type || "unknown"}) is not supported."
63
- end
64
- end
65
-
66
57
  #
67
58
  # Passive DNS search
68
59
  #
@@ -21,7 +21,14 @@ module Mihari
21
21
  end
22
22
 
23
23
  def artifacts
24
- 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
25
32
  end
26
33
 
27
34
  private
@@ -52,22 +59,6 @@ module Mihari
52
59
  rescue Resolv::ResolvError => _e
53
60
  false
54
61
  end
55
-
56
- #
57
- # Search
58
- #
59
- # @return [Array<String>]
60
- #
61
- def search
62
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
63
-
64
- res = client.fuzz(query)
65
- fuzzy_domains = res["fuzzy_domains"] || []
66
- domains = fuzzy_domains.map { |domain| domain["domain"] }
67
- Parallel.map(domains) do |domain|
68
- resolvable?(domain) ? domain : nil
69
- end.compact
70
- end
71
62
  end
72
63
  end
73
64
  end
@@ -26,7 +26,14 @@ module Mihari
26
26
  end
27
27
 
28
28
  def artifacts
29
- 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
30
37
  end
31
38
 
32
39
  private
@@ -48,22 +55,6 @@ module Mihari
48
55
  %w[ip domain].include? type
49
56
  end
50
57
 
51
- #
52
- # IP/domain search
53
- #
54
- # @return [Array<String>]
55
- #
56
- def search
57
- case type
58
- when "domain"
59
- domain_search
60
- when "ip"
61
- ip_search
62
- else
63
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
64
- end
65
- end
66
-
67
58
  #
68
59
  # Domain search
69
60
  #
@@ -30,7 +30,16 @@ module Mihari
30
30
  end
31
31
 
32
32
  def artifacts
33
- 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
34
43
  end
35
44
 
36
45
  def configured?
@@ -56,24 +65,6 @@ module Mihari
56
65
  %w[ip domain mail hash].include? type
57
66
  end
58
67
 
59
- #
60
- # Passive DNS/SSL, reverse whois search
61
- #
62
- # @return [Array<String>]
63
- #
64
- def search
65
- case type
66
- when "domain", "ip"
67
- passive_dns_search
68
- when "mail"
69
- reverse_whois_search
70
- when "hash"
71
- ssl_search
72
- else
73
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
74
- end
75
- end
76
-
77
68
  #
78
69
  # Passive DNS search
79
70
  #
@@ -58,7 +58,6 @@ module Mihari
58
58
 
59
59
  indicator = client.get_indicator(query)
60
60
  iid = indicator["iid"]
61
-
62
61
  properties = client.get_properties(iid)
63
62
  (properties["dns"] || []).filter_map do |property|
64
63
  if %w[A PTR].include?(property["name"])
@@ -26,7 +26,16 @@ module Mihari
26
26
  end
27
27
 
28
28
  def artifacts
29
- search || []
29
+ case type
30
+ when "domain"
31
+ domain_search
32
+ when "ip"
33
+ ip_search
34
+ when "mail"
35
+ mail_search
36
+ else
37
+ raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
38
+ end
30
39
  end
31
40
 
32
41
  private
@@ -48,24 +57,6 @@ module Mihari
48
57
  %w[ip domain mail].include? type
49
58
  end
50
59
 
51
- #
52
- # IP/domain/mail search
53
- #
54
- # @return [Array<String>, Array<Mihari::Artifact>]
55
- #
56
- def search
57
- case type
58
- when "domain"
59
- domain_search
60
- when "ip"
61
- ip_search
62
- when "mail"
63
- mail_search
64
- else
65
- raise InvalidInputError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
66
- end
67
- end
68
-
69
60
  #
70
61
  # Domain search
71
62
  #
@@ -73,17 +73,6 @@ module Mihari
73
73
  end
74
74
  responses
75
75
  end
76
-
77
- #
78
- # Build an artifact from a Shodan search API response
79
- #
80
- # @param [Structs::Shodan::Match] match
81
- # @param [Array<Structs::Shodan::Match>] matches
82
- #
83
- # @return [Artifact]
84
- #
85
- def build_artifact(match, matches)
86
- end
87
76
  end
88
77
  end
89
78
  end
@@ -27,9 +27,8 @@ module Mihari
27
27
  def initialize(*args, **kwargs)
28
28
  super
29
29
 
30
- unless valid_alllowed_data_types?
31
- raise InvalidInputError,
32
- "allowed_data_types should be any of url, domain and ip."
30
+ unless valid_allowed_data_types?
31
+ raise InvalidInputError, "allowed_data_types should be any of url, domain and ip."
33
32
  end
34
33
 
35
34
  @api_key = kwargs[:api_key] || Mihari.config.urlscan_api_key
@@ -97,7 +96,7 @@ module Mihari
97
96
  #
98
97
  # @return [Boolean]
99
98
  #
100
- def valid_alllowed_data_types?
99
+ def valid_allowed_data_types?
101
100
  allowed_data_types.all? { |type| SUPPORTED_DATA_TYPES.include? type }
102
101
  end
103
102
  end
@@ -58,14 +58,11 @@ module Mihari
58
58
  responses = []
59
59
 
60
60
  loop do
61
- response = Structs::VirusTotalIntelligence::Response.from_dynamic!(client.intel_search(query,
62
- cursor: cursor))
61
+ response = Structs::VirusTotalIntelligence::Response.from_dynamic!(client.intel_search(query, cursor: cursor))
63
62
  responses << response
64
-
65
63
  break if response.meta.cursor.nil?
66
64
 
67
65
  cursor = response.meta.cursor
68
-
69
66
  # sleep #{interval} seconds to avoid the rate limitation (if it is set)
70
67
  sleep interval
71
68
  end
@@ -12,6 +12,8 @@ module Mihari
12
12
  raise(ArgumentError, "'api_key' argument is required") unless api_key
13
13
 
14
14
  headers["authorization"] = api_key
15
+ headers["accept"] = "application/json"
16
+
15
17
  super(base_url, headers: headers)
16
18
  end
17
19
 
data/lib/mihari/http.rb CHANGED
@@ -4,7 +4,7 @@ require "insensitive_hash"
4
4
 
5
5
  module Mihari
6
6
  class HTTP
7
- # @return [String]
7
+ # @return [URI]
8
8
  attr_reader :url
9
9
 
10
10
  # @return [Hash]
@@ -26,12 +26,12 @@ module Mihari
26
26
  new_url = url.deep_dup
27
27
  new_url.query = Addressable::URI.form_encode(params) unless (params || {}).empty?
28
28
 
29
- get = Net::HTTP::Get.new(new_url)
29
+ get = Net::HTTP::Get.new(new_url, headers)
30
30
  request get
31
31
  end
32
32
 
33
33
  #
34
- # Make a POST requesti
34
+ # Make a POST request
35
35
  #
36
36
  # @param [Hash, nil] params
37
37
  # @param [Hash, nil] json
@@ -43,10 +43,17 @@ module Mihari
43
43
  new_url = url.deep_dup
44
44
  new_url.query = Addressable::URI.form_encode(params) unless (params || {}).empty?
45
45
 
46
- post = Net::HTTP::Post.new(new_url)
46
+ post = Net::HTTP::Post.new(new_url, headers)
47
47
 
48
- post.body = JSON.generate(json) if json
49
- post.set_form_data(data) if data
48
+ if json
49
+ post.body = JSON.generate(json) if json
50
+ post.content_type = "application/json"
51
+ end
52
+
53
+ if data
54
+ post.set_form_data(data) if data
55
+ post.content_type = "application/x-www-form-urlencoded"
56
+ end
50
57
 
51
58
  request post
52
59
  end
@@ -65,10 +72,6 @@ module Mihari
65
72
 
66
73
  private
67
74
 
68
- def content_type
69
- headers["content-type"] || "application/json"
70
- end
71
-
72
75
  #
73
76
  # Get options for HTTP request
74
77
  #
@@ -89,16 +92,9 @@ module Mihari
89
92
  #
90
93
  def request(req)
91
94
  Net::HTTP.start(url.host, url.port, https_options) do |http|
92
- # set headers
93
- headers.each do |k, v|
94
- req[k] = v
95
- end
96
-
97
95
  res = http.request(req)
98
-
99
96
  unless res.is_a?(Net::HTTPSuccess)
100
- code = res.code.to_i
101
- raise UnsuccessfulStatusCodeError, "Unsuccessful response code returned: #{code}"
97
+ raise UnsuccessfulStatusCodeError, "Unsuccessful response code returned: #{res.code}"
102
98
  end
103
99
 
104
100
  res
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "5.1.2"
4
+ VERSION = "5.1.3"
5
5
  end
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: 5.1.2
4
+ version: 5.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-18 00:00:00.000000000 Z
11
+ date: 2023-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -994,7 +994,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
994
994
  - !ruby/object:Gem::Version
995
995
  version: '0'
996
996
  requirements: []
997
- rubygems_version: 3.3.26
997
+ rubygems_version: 3.4.1
998
998
  signing_key:
999
999
  specification_version: 4
1000
1000
  summary: A framework for continuous OSINT based threat hunting