mihari 3.10.1 → 3.11.0

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: 0fcea779559f641125a388f63f0aa2d39979842f9b66f116194c36fe6410c56c
4
- data.tar.gz: ceefe0fa86e5d3c8066bab202f7dc1dfb2b21017554a2b63c5a18f567e45aadb
3
+ metadata.gz: 2c8fda839e1bb1ec4733b7da17e20e3b47bd5795d5aca25371d09e5a0fa9a575
4
+ data.tar.gz: a4551c61c625bd08167608051750bf1785a31ad5215e95e857753fc5fed31d00
5
5
  SHA512:
6
- metadata.gz: 834c4c815ddf9c14b9047c9a8d9ed8ce56e3f115c16b797c4ebf40205529f7c94fe7ddda8f9c7f5cc0675c65123ac0957d28a0bfe51108d2492efc230f509dd8
7
- data.tar.gz: 03ed05a672e17bfce72706de94aa2a339053f9b6545907c1e71cf60987be047e1af6bc6d4e95a16f6b6bb371de2ff3b65602ae4c3c9eb2eab3f70c2ace0735cf
6
+ metadata.gz: 81a1ca91b65b03f98bb3504a85c8113b2cf189a4911109e113da1058fb9a1bd61c8807e6f3bec72484786b89e68d0027782d38013676bd6ae78aa57434315972
7
+ data.tar.gz: b42b1658310a7ee87940fbebb6507edca2187d6be92957a149f9234af8bf32ba06e702c401d321b553901dc56094964e78ff602549734f51abbf24b4b7a1fa4d
data/docker/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:3.0.2-alpine3.13
1
+ FROM ruby:3.0.3-alpine3.13
2
2
 
3
3
  RUN apk --no-cache add git build-base ruby-dev sqlite-dev postgresql-dev mysql-client mysql-dev \
4
4
  && gem install pg mysql2 \
@@ -10,6 +10,8 @@ module Mihari
10
10
  option :description, default: proc { "query = #{query}" }
11
11
  option :tags, default: proc { [] }
12
12
 
13
+ option :interval, default: proc { 0 }
14
+
13
15
  def artifacts
14
16
  results = search
15
17
  return [] unless results || results.empty?
@@ -55,6 +57,9 @@ module Mihari
55
57
 
56
58
  responses << res
57
59
  break if total <= page * PAGE_SIZE
60
+
61
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
62
+ sleep interval
58
63
  end
59
64
  responses
60
65
  end
@@ -10,6 +10,8 @@ module Mihari
10
10
  option :description, default: proc { "query = #{query}" }
11
11
  option :tags, default: proc { [] }
12
12
 
13
+ option :interval, default: proc { 0 }
14
+
13
15
  def artifacts
14
16
  search
15
17
  end
@@ -33,6 +35,9 @@ module Mihari
33
35
 
34
36
  cursor = response.result.links.next
35
37
  break if cursor == ""
38
+
39
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
40
+ sleep interval
36
41
  end
37
42
 
38
43
  artifacts.flatten.uniq(&:data)
@@ -11,6 +11,8 @@ module Mihari
11
11
  option :description, default: proc { "query = #{query}" }
12
12
  option :tags, default: proc { [] }
13
13
 
14
+ option :interval, default: proc { 0 }
15
+
14
16
  def artifacts
15
17
  responses = search
16
18
  return [] unless responses
@@ -59,6 +61,9 @@ module Mihari
59
61
 
60
62
  total = res.total
61
63
  break if total <= page * PAGE_SIZE
64
+
65
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
66
+ sleep interval
62
67
  end
63
68
  responses
64
69
  end
@@ -64,6 +64,12 @@ module Mihari
64
64
  klass = get_analyzer_class(analyzer_name)
65
65
 
66
66
  query = params[:query]
67
+
68
+ # set interval in the top level
69
+ options = params[:options] || {}
70
+ interval = options[:interval]
71
+ params[:interval] = interval
72
+
67
73
  analyzer = klass.new(query, **params)
68
74
 
69
75
  # Use #normalized_artifacts method to get atrifacts as Array<Mihari::Artifact>
@@ -10,6 +10,8 @@ module Mihari
10
10
  option :description, default: proc { "query = #{query}" }
11
11
  option :tags, default: proc { [] }
12
12
 
13
+ option :interval, default: proc { 0 }
14
+
13
15
  def artifacts
14
16
  results = search
15
17
  return [] unless results || results.empty?
@@ -63,6 +65,9 @@ module Mihari
63
65
 
64
66
  responses << res
65
67
  break if res["total"].to_i <= page * PAGE_SIZE
68
+
69
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
70
+ sleep interval
66
71
  rescue JSON::ParserError
67
72
  # ignore JSON::ParserError
68
73
  # ref. https://github.com/ninoseki/mihari/issues/197
@@ -2,8 +2,6 @@
2
2
 
3
3
  require "urlscan"
4
4
 
5
- SUPPORTED_DATA_TYPES = %w[url domain ip].freeze
6
-
7
5
  module Mihari
8
6
  module Analyzers
9
7
  class Urlscan < Base
@@ -12,7 +10,11 @@ module Mihari
12
10
  option :description, default: proc { "query = #{query}" }
13
11
  option :tags, default: proc { [] }
14
12
  option :allowed_data_types, default: proc { SUPPORTED_DATA_TYPES }
15
- option :use_similarity, default: proc { false }
13
+
14
+ option :interval, default: proc { 0 }
15
+
16
+ SUPPORTED_DATA_TYPES = %w[url domain ip].freeze
17
+ SIZE = 1000
16
18
 
17
19
  def initialize(*args, **kwargs)
18
20
  super
@@ -21,16 +23,15 @@ module Mihari
21
23
  end
22
24
 
23
25
  def artifacts
24
- result = search
25
- return [] unless result
26
-
27
- results = result["results"] || []
26
+ responses = search
27
+ results = responses.map(&:results).flatten
28
28
 
29
29
  allowed_data_types.map do |type|
30
- results.filter_map do |match|
31
- match.dig "page", type
30
+ results.filter_map do |result|
31
+ page = result.page
32
+ page.send(type.to_sym)
32
33
  end.uniq
33
- end.flatten
34
+ end.flatten.compact
34
35
  end
35
36
 
36
37
  private
@@ -43,15 +44,38 @@ module Mihari
43
44
  @api ||= ::UrlScan::API.new(Mihari.config.urlscan_api_key)
44
45
  end
45
46
 
47
+ #
48
+ # Search with search_after option
49
+ #
50
+ # @return [Structs::Urlscan::Response]
51
+ #
52
+ def search_with_search_after(search_after: nil)
53
+ res = api.search(query, size: SIZE, search_after: search_after)
54
+ Structs::Urlscan::Response.from_dynamic! res
55
+ end
56
+
46
57
  #
47
58
  # Search
48
59
  #
49
- # @return [Array<Hash>]
60
+ # @return [Array<Structs::Urlscan::Response>]
50
61
  #
51
62
  def search
52
- return api.pro.similar(query) if use_similarity
63
+ responses = []
64
+
65
+ search_after = nil
66
+ loop do
67
+ res = search_with_search_after(search_after: search_after)
68
+ responses << res
69
+
70
+ break if res.results.length < SIZE
71
+
72
+ search_after = res.results.last.sort.join(",")
73
+
74
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
75
+ sleep interval
76
+ end
53
77
 
54
- api.search(query, size: 10_000)
78
+ responses
55
79
  end
56
80
 
57
81
  #
@@ -10,6 +10,8 @@ module Mihari
10
10
  option :description, default: proc { "query = #{query}" }
11
11
  option :tags, default: proc { [] }
12
12
 
13
+ option :interval, default: proc { 0 }
14
+
13
15
  def initialize(*args, **kwargs)
14
16
  super
15
17
 
@@ -54,6 +56,9 @@ module Mihari
54
56
  break if response.meta.cursor.nil?
55
57
 
56
58
  cursor = response.meta.cursor
59
+
60
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
61
+ sleep interval
57
62
  end
58
63
 
59
64
  responses
@@ -11,6 +11,8 @@ module Mihari
11
11
  option :tags, default: proc { [] }
12
12
  option :type, default: proc { "host" }
13
13
 
14
+ option :interval, default: proc { 0 }
15
+
14
16
  def artifacts
15
17
  case type
16
18
  when "host"
@@ -87,6 +89,9 @@ module Mihari
87
89
  total = res["total"].to_i
88
90
  responses << res
89
91
  break if total <= page * PAGE_SIZE
92
+
93
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
94
+ sleep interval
90
95
  end
91
96
  convert_responses responses.compact
92
97
  end
@@ -119,6 +124,9 @@ module Mihari
119
124
  total = res["total"].to_i
120
125
  responses << res
121
126
  break if total <= page * PAGE_SIZE
127
+
128
+ # sleep #{interval} seconds to avoid the rate limitation (if it is set)
129
+ sleep interval
122
130
  end
123
131
  convert_responses responses.compact
124
132
  end
@@ -26,6 +26,7 @@ module Mihari
26
26
  class Analyzer < Base
27
27
  class_option :ignore_old_artifacts, type: :boolean, default: false, desc: "Whether to ignore old artifacts from checking or not."
28
28
  class_option :ignore_threshold, type: :numeric, default: 0, desc: "Number of days to define whether an artifact is old or not."
29
+ class_option :interval, type: :numeric, default: 0, desc: "Seconds of the interval while calling API in a row."
29
30
  class_option :config, type: :string, desc: "Path to the config file"
30
31
 
31
32
  include Mihari::Commands::BinaryEdge
@@ -9,8 +9,7 @@ module Mihari
9
9
  method_option :title, type: :string, desc: "title"
10
10
  method_option :description, type: :string, desc: "description"
11
11
  method_option :tags, type: :array, desc: "tags"
12
- method_option :target_type, type: :string, default: "url", desc: "target type to fetch from search results (target type should be 'url', 'domain' or 'ip')"
13
- method_option :use_similarity, type: :boolean, default: false, desc: "use similarity API or not"
12
+ method_option :allowed_data_types, type: :array, default: ["url", "ip", "domain"], desc: "types to fetch from search results ('url', 'domain' or 'ip')"
14
13
  def urlscan(query)
15
14
  with_error_handling do
16
15
  run_analyzer Analyzers::Urlscan, query: query, options: options
@@ -7,33 +7,41 @@ require "mihari/schemas/macros"
7
7
 
8
8
  module Mihari
9
9
  module Schemas
10
+ AnalyzerOptions = Dry::Schema.Params do
11
+ optional(:interval).value(:integer)
12
+ end
13
+
10
14
  Analyzer = Dry::Schema.Params do
11
15
  required(:analyzer).value(Types::AnalyzerTypes)
12
16
  required(:query).value(:string)
17
+ optional(:options).hash(AnalyzerOptions)
13
18
  end
14
19
 
15
20
  Spyse = Dry::Schema.Params do
16
21
  required(:analyzer).value(Types::String.enum("spyse"))
17
22
  required(:query).value(:string)
18
23
  required(:type).value(Types::String.enum("ip", "domain"))
24
+ optional(:options).hash(AnalyzerOptions)
19
25
  end
20
26
 
21
27
  ZoomEye = Dry::Schema.Params do
22
28
  required(:analyzer).value(Types::String.enum("zoomeye"))
23
29
  required(:query).value(:string)
24
30
  required(:type).value(Types::String.enum("host", "web"))
31
+ optional(:options).hash(AnalyzerOptions)
25
32
  end
26
33
 
27
34
  Crtsh = Dry::Schema.Params do
28
35
  required(:analyzer).value(Types::String.enum("crtsh"))
29
36
  required(:query).value(:string)
30
37
  optional(:exclude_expired).value(:bool).default(true)
38
+ optional(:options).hash(AnalyzerOptions)
31
39
  end
32
40
 
33
41
  Urlscan = Dry::Schema.Params do
34
42
  required(:analyzer).value(Types::String.enum("urlscan"))
35
43
  required(:query).value(:string)
36
- optional(:use_similarity).value(:bool).default(true)
44
+ optional(:options).hash(AnalyzerOptions)
37
45
  end
38
46
 
39
47
  Rule = Dry::Schema.Params do
@@ -0,0 +1,51 @@
1
+ require "json"
2
+ require "dry/struct"
3
+
4
+ module Mihari
5
+ module Structs
6
+ module Urlscan
7
+ class Page < Dry::Struct
8
+ attribute :domain, Types::String.optional
9
+ attribute :ip, Types::String.optional
10
+ attribute :url, Types::String
11
+
12
+ def self.from_dynamic!(d)
13
+ d = Types::Hash[d]
14
+ new(
15
+ domain: d["domain"],
16
+ ip: d["ip"],
17
+ url: d.fetch("url")
18
+ )
19
+ end
20
+ end
21
+
22
+ class Result < Dry::Struct
23
+ attribute :page, Page
24
+ attribute :id, Types::String
25
+ attribute :sort, Types.Array(Types::String | Types::Integer)
26
+
27
+ def self.from_dynamic!(d)
28
+ d = Types::Hash[d]
29
+ new(
30
+ page: Page.from_dynamic!(d.fetch("page")),
31
+ id: d.fetch("_id"),
32
+ sort: d.fetch("sort")
33
+ )
34
+ end
35
+ end
36
+
37
+ class Response < Dry::Struct
38
+ attribute :results, Types.Array(Result)
39
+ attribute :has_more, Types::Bool
40
+
41
+ def self.from_dynamic!(d)
42
+ d = Types::Hash[d]
43
+ new(
44
+ results: d.fetch("results").map { |x| Result.from_dynamic!(x) },
45
+ has_more: d.fetch("has_more")
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/mihari/types.rb CHANGED
@@ -8,11 +8,14 @@ module Mihari
8
8
  Nil = Strict::Nil
9
9
  Hash = Strict::Hash
10
10
  String = Strict::String
11
+ Bool = Strict::Bool
11
12
  Double = Strict::Float | Strict::Integer
12
13
  DateTime = Strict::DateTime
13
14
 
14
15
  DataTypes = Types::String.enum(*ALLOWED_DATA_TYPES)
15
16
 
17
+ UrlscanDataTypes = Types::String.enum("ip", "domain", "url")
18
+
16
19
  AnalyzerTypes = Types::String.enum(
17
20
  "binaryedge",
18
21
  "censys",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "3.10.1"
4
+ VERSION = "3.11.0"
5
5
  end
data/lib/mihari.rb CHANGED
@@ -117,6 +117,7 @@ require "mihari/structs/greynoise"
117
117
  require "mihari/structs/ipinfo"
118
118
  require "mihari/structs/onyphe"
119
119
  require "mihari/structs/shodan"
120
+ require "mihari/structs/urlscan"
120
121
  require "mihari/structs/virustotal_intelligence"
121
122
 
122
123
  # Schemas
data/mihari.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_development_dependency "bundler", "~> 2.2"
29
29
  spec.add_development_dependency "coveralls_reborn", "~> 0.23"
30
- spec.add_development_dependency "fakefs", "~> 1.3"
30
+ spec.add_development_dependency "fakefs", "~> 1.4"
31
31
  spec.add_development_dependency "mysql2", "~> 0.5"
32
32
  spec.add_development_dependency "overcommit", "~> 0.58"
33
33
  spec.add_development_dependency "pg", "~> 1.2"
@@ -36,8 +36,8 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "rb-fsevent", "~> 0.11"
37
37
  spec.add_development_dependency "rerun", "~> 0.13"
38
38
  spec.add_development_dependency "rspec", "~> 3.10"
39
- spec.add_development_dependency "standard", "~> 1.3"
40
- spec.add_development_dependency "steep", "~> 0.46"
39
+ spec.add_development_dependency "standard", "~> 1.5"
40
+ spec.add_development_dependency "steep", "~> 0.47"
41
41
  spec.add_development_dependency "timecop", "~> 0.9"
42
42
  spec.add_development_dependency "vcr", "~> 6.0"
43
43
  spec.add_development_dependency "webmock", "~> 3.14"
@@ -94,7 +94,7 @@ Gem::Specification.new do |spec|
94
94
  spec.add_dependency "sqlite3", "~> 1.4"
95
95
  spec.add_dependency "thor", "~> 1.1"
96
96
  spec.add_dependency "thread_safe", "~> 0.3"
97
- spec.add_dependency "urlscan", "~> 0.7"
97
+ spec.add_dependency "urlscan", "~> 0.8"
98
98
  spec.add_dependency "uuidtools", "~> 2.2"
99
99
  spec.add_dependency "virustotalx", "~> 1.2"
100
100
  spec.add_dependency "whois", "~> 5.0"
@@ -7,6 +7,8 @@ module Mihari
7
7
  attr_reader description: String
8
8
  attr_reader tags: Array[String]
9
9
 
10
+ attr_reader interval: ::Integer
11
+
10
12
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
11
13
 
12
14
  private
@@ -6,6 +6,8 @@ module Mihari
6
6
  attr_reader description: String
7
7
  attr_reader tags: Array[String]
8
8
 
9
+ attr_reader interval: ::Integer
10
+
9
11
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
10
12
 
11
13
  private
@@ -6,6 +6,8 @@ module Mihari
6
6
  attr_reader description: String
7
7
  attr_reader tags: Array[String]
8
8
 
9
+ attr_reader interval: ::Integer
10
+
9
11
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
10
12
 
11
13
  private
@@ -6,6 +6,8 @@ module Mihari
6
6
  attr_reader description: String
7
7
  attr_reader tags: Array[String]
8
8
 
9
+ attr_reader interval: ::Integer
10
+
9
11
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
10
12
 
11
13
  private
@@ -8,7 +8,8 @@ module Mihari
8
8
  attr_reader description: String
9
9
  attr_reader tags: Array[String]
10
10
  attr_reader allowed_data_types: Array[String]
11
- attr_reader use_similarity: bool
11
+
12
+ attr_reader interval: ::Integer
12
13
 
13
14
  def initialize: (*untyped args, **untyped kwargs) -> void
14
15
 
@@ -20,7 +21,9 @@ module Mihari
20
21
 
21
22
  def api: () -> untyped
22
23
 
23
- def search: () -> Array[Hash[(String | Symbol), untyped]]
24
+ def search_with_search_after: (search_after: String?) -> Array[Hash[(String | Symbol), untyped]]
25
+
26
+ def search: () -> Array[Mihari::Structs::Urlscan::Response]
24
27
 
25
28
  def valid_alllowed_data_types?: () -> bool
26
29
  end
@@ -6,6 +6,8 @@ module Mihari
6
6
  attr_reader description: String
7
7
  attr_reader tags: Array[String]
8
8
 
9
+ attr_reader interval: ::Integer
10
+
9
11
  def initialize: (*untyped args, **untyped kwargs) -> void
10
12
 
11
13
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
@@ -7,6 +7,8 @@ module Mihari
7
7
  attr_reader tags: Array[String]
8
8
  attr_reader type: String
9
9
 
10
+ attr_reader interval: ::Integer
11
+
10
12
  def artifacts: () -> (Array[String] | Array[Mihari::Artifact])
11
13
 
12
14
  private
@@ -6,14 +6,14 @@ module Mihari
6
6
  attr_reader country_code: String
7
7
  attr_reader asn: String
8
8
 
9
- def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> untyped
9
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::GreyNoise::Metadata
10
10
  end
11
11
 
12
12
  class Datum < Dry::Struct
13
13
  attr_reader ip: String
14
14
  attr_reader metadata: Mihari::Structs::GreyNoise::Metadata
15
15
 
16
- def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> untyped
16
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::GreyNoise::Datum
17
17
  end
18
18
 
19
19
  class Response < Dry::Struct
@@ -23,7 +23,7 @@ module Mihari
23
23
  attr_reader message: String
24
24
  attr_reader query: String
25
25
 
26
- def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> untyped
26
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::GreyNoise::Response
27
27
  end
28
28
  end
29
29
  end
@@ -0,0 +1,28 @@
1
+ module Mihari
2
+ module Structs
3
+ module Urlscan
4
+ class Page < Dry::Struct
5
+ attr_reader domain: String?
6
+ attr_reader ip: String?
7
+ attr_reader url: String
8
+
9
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::Urlscan::Page
10
+ end
11
+
12
+ class Result < Dry::Struct
13
+ attr_reader page: Mihari::Structs::Urlscan::Page
14
+ attr_reader id: String
15
+ attr_reader sort: Array[Integer | String]
16
+
17
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::Urlscan::Result
18
+ end
19
+
20
+ class Response < Dry::Struct
21
+ attr_reader results: Array[Mihari::Structs::Urlscan::Result]
22
+ attr_reader has_more: Boolean
23
+
24
+ def self.from_dynamic!: (Hash[(String | Symbol), untyped] d) -> Mihari::Structs::Urlscan::Response
25
+ end
26
+ end
27
+ end
28
+ 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: 3.10.1
4
+ version: 3.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-28 00:00:00.000000000 Z
11
+ date: 2021-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.3'
47
+ version: '1.4'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.3'
54
+ version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mysql2
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -170,28 +170,28 @@ dependencies:
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '1.3'
173
+ version: '1.5'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '1.3'
180
+ version: '1.5'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: steep
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '0.46'
187
+ version: '0.47'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '0.46'
194
+ version: '0.47'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: timecop
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -968,14 +968,14 @@ dependencies:
968
968
  requirements:
969
969
  - - "~>"
970
970
  - !ruby/object:Gem::Version
971
- version: '0.7'
971
+ version: '0.8'
972
972
  type: :runtime
973
973
  prerelease: false
974
974
  version_requirements: !ruby/object:Gem::Requirement
975
975
  requirements:
976
976
  - - "~>"
977
977
  - !ruby/object:Gem::Version
978
- version: '0.7'
978
+ version: '0.8'
979
979
  - !ruby/object:Gem::Dependency
980
980
  name: uuidtools
981
981
  requirement: !ruby/object:Gem::Requirement
@@ -1177,6 +1177,7 @@ files:
1177
1177
  - lib/mihari/structs/ipinfo.rb
1178
1178
  - lib/mihari/structs/onyphe.rb
1179
1179
  - lib/mihari/structs/shodan.rb
1180
+ - lib/mihari/structs/urlscan.rb
1180
1181
  - lib/mihari/structs/virustotal_intelligence.rb
1181
1182
  - lib/mihari/templates/rule.yml.erb
1182
1183
  - lib/mihari/type_checker.rb
@@ -1351,6 +1352,7 @@ files:
1351
1352
  - sig/lib/mihari/structs/ipinfo.rbs
1352
1353
  - sig/lib/mihari/structs/onyphe.rbs
1353
1354
  - sig/lib/mihari/structs/shodan.rbs
1355
+ - sig/lib/mihari/structs/urlscan.rbs
1354
1356
  - sig/lib/mihari/structs/virustotal_intelligence.rbs
1355
1357
  - sig/lib/mihari/type_checker.rbs
1356
1358
  - sig/lib/mihari/types.rbs