mihari 5.1.2 → 5.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5415ee0f5bb820e8073383e4771589bbbaa39fc313af3aa434c5754f34bb9056
4
- data.tar.gz: a4da4ce859fa718c900572b865518110f92649698a76ca64c55e38ebad2f9856
3
+ metadata.gz: 52425b89ab9cc2d25fcfd1391661446b938b35596fb5b3a68647f90038a3f848
4
+ data.tar.gz: 3ae2917e1de1e89e08089e40629eb8652a173cf03dd790137b55c1eb80d35706
5
5
  SHA512:
6
- metadata.gz: c0b95e672f17d5ba0035624b035da278c863dc0b1a0860e3393cd8f001125964270233da7bf5ffb08c9057889b4a51698829de059089ed4d31a0f4fd7d0aa3e8
7
- data.tar.gz: 30cbba0170104212e9244dfeac820a1a223468bae940719c242778d5bffd95b147f482548aebcc2386713fe43cc0c1b97bf2d71d08d318ad62a4b1a707f3e605
6
+ metadata.gz: f06c60e30e815c2634c6309b86b323199393d3c6b02e416244d884c60916584fdbe2250a0366ddf002957b240eadce64c2dc25b740ce80ecce126a78eab29b87
7
+ data.tar.gz: 2e2e71da88d3ba33b58861b97b3987fb8f64fe581cc7f15cf488227df4621ec03d3c91968e126f787c3b23c65141a81817d4b0785f5aa9065e6fcfa396a99ed5
@@ -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
 
@@ -45,10 +45,10 @@ module Mihari
45
45
 
46
46
  client.create_event({
47
47
  Event: {
48
- info: rule.title
49
- },
50
- Attribute: artifacts.map { |artifact| build_attribute(artifact) },
51
- Tag: rule.tags.map { |tag| { name: tag } }
48
+ info: rule.title,
49
+ Attribute: artifacts.map { |artifact| build_attribute(artifact) },
50
+ Tag: rule.tags.map { |tag| { name: tag } }
51
+ }
52
52
  })
53
53
  end
54
54
 
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.4"
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.4
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-28 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