miteru 1.1.0 → 1.2.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: 050c27599e75745a7c215f08b7ed190b43c70388d974a68945702eefdb25b7c2
4
- data.tar.gz: 64c7429a4178febf6984fe3d79d3970781634971405c5d9fdb0748c61b663a32
3
+ metadata.gz: c858dd689d566a4a12270d7474b9174d60deeabb23f61e1a62440040558f0a3c
4
+ data.tar.gz: 0f53873e358ab18712c0e9d7c5fc6b6cd863464b467d78e82983ca2386834115
5
5
  SHA512:
6
- metadata.gz: ff780a0db3fafdded94261c38272dc0537462ae195f646cceafc2223cd62e61fb8d809ee172f953344314a93f9e6f746b9d3b6b66efdf9b48cda2c5d8c645eb7
7
- data.tar.gz: c55dfad5120175ebf43bd01a30b42517a9a5bfd6fddd12d8c6ad07acd3ae02bba67a1bc9101d26fab74406f374f16fbeb3f51e791c678dce749a403e9477f82a
6
+ metadata.gz: 76359bf3d5883acdfdef815045d634a286be8985f21408f9f91349a7e048077309ab468d095d4b49e9e26b19018b4d280b2290beb8620b5d7729e1b9fc5d9586
7
+ data.tar.gz: 9bb8d92dbb325a74c38a8f05a4ed5967831a70601597d6d45235d9a1571228dcfcc543e255628b763b977bf2a649b3976779a2765c8ba19dd174dc988d275320
@@ -42,18 +42,17 @@ jobs:
42
42
  ruby: [2.7, "3.0"]
43
43
 
44
44
  steps:
45
- - uses: actions/checkout@v2
45
+ - uses: actions/checkout@v3
46
46
  - name: Set up Ruby
47
47
  uses: ruby/setup-ruby@v1
48
48
  with:
49
49
  ruby-version: ${{ matrix.ruby }}
50
+ bundler: latest
50
51
  bundler-cache: true
51
52
 
52
53
  - name: Install dependencies
53
54
  run: |
54
55
  sudo apt-get -yqq install libpq-dev libmysqlclient-dev
55
- gem install bundler
56
- bundle install
57
56
 
58
57
  - name: Test with PostgreSQL
59
58
  env:
@@ -47,7 +47,7 @@ module Miteru
47
47
  end
48
48
 
49
49
  def defanged_url
50
- @defanged_url ||= url.to_s.gsub /\./, "[.]"
50
+ @defanged_url ||= url.to_s.gsub(/\./, "[.]")
51
51
  end
52
52
 
53
53
  def domain
@@ -37,12 +37,21 @@ module Miteru
37
37
  # @return [String]
38
38
  attr_accessor :slack_channel
39
39
 
40
+ # @return [String]
41
+ attr_accessor :urlscan_api_key
42
+
43
+ # @return [String]
44
+ attr_accessor :urlscan_submit_visibility
45
+
40
46
  # @return [Array<String>]
41
47
  attr_reader :valid_extensions
42
48
 
43
49
  # @return [Array<String>]
44
50
  attr_reader :valid_mime_types
45
51
 
52
+ # @return [Integer]
53
+ attr_reader :file_maxsize
54
+
46
55
  def initialize
47
56
  @auto_download = false
48
57
  @ayashige = false
@@ -52,10 +61,14 @@ module Miteru
52
61
  @size = 100
53
62
  @threads = Parallel.processor_count
54
63
  @verbose = false
55
- @database = ENV["MITERU_DATABASE"] || "miteru.db"
64
+ @database = ENV.fetch("MITERU_DATABASE", "miteru.db")
65
+ @file_maxsize = ENV.fetch("FILE_MAXSIZE", 1024 * 1024 * 100).to_i
66
+
67
+ @slack_webhook_url = ENV.fetch("SLACK_WEBHOOK_URL", nil)
68
+ @slack_channel = ENV.fetch("SLACK_CHANNEL", "#general")
56
69
 
57
- @slack_webhook_url = ENV["SLACK_WEBHOOK_URL"]
58
- @slack_channel = ENV["SLACK_CHANNEL"] || "#general"
70
+ @urlscan_api_key = ENV.fetch("URLSCAN_API_KEY", nil)
71
+ @urlscan_submit_visibility = ENV.fetch("URLSCAN_SUBMIT_VISIBILITY", "public")
59
72
 
60
73
  @valid_extensions = [".zip", ".rar", ".7z", ".tar", ".gz"].freeze
61
74
  @valid_mime_types = ["application/zip", "application/vnd.rar", "application/x-7z-compressed", "application/x-tar", "application/gzip"]
@@ -82,7 +95,11 @@ module Miteru
82
95
  end
83
96
 
84
97
  def slack_webhook_url?
85
- @slack_webhook_url
98
+ !@slack_webhook_url.nil?
99
+ end
100
+
101
+ def urlscan_api_key?
102
+ !@urlscan_api_key.nil?
86
103
  end
87
104
  end
88
105
 
@@ -11,7 +11,6 @@ module Miteru
11
11
  def initialize
12
12
  @downloader = Downloader.new(Miteru.configuration.download_to)
13
13
  @feeds = Feeds.new
14
- @notifier = Notifier.new
15
14
  end
16
15
 
17
16
  def crawl(entry)
@@ -24,7 +23,7 @@ module Miteru
24
23
 
25
24
  def execute
26
25
  suspicious_entries = feeds.suspicious_entries
27
- puts "Loaded #{suspicious_entries.length} URLs to crawl. (crawling in #{threads} threads)" if verbose?
26
+ Miteru.logger.info "Loaded #{suspicious_entries.length} URLs to crawl. (crawling in #{threads} threads)" if verbose?
28
27
 
29
28
  Parallel.each(suspicious_entries, in_threads: threads) do |entry|
30
29
  crawl entry
@@ -36,7 +35,9 @@ module Miteru
36
35
  end
37
36
 
38
37
  def notify(website)
39
- @notifier.notify(url: website.url, kits: website.kits, message: website.message)
38
+ Parallel.each(notifiers) do |notifier|
39
+ notifier.notify website
40
+ end
40
41
  end
41
42
 
42
43
  def auto_download?
@@ -47,6 +48,12 @@ module Miteru
47
48
  Miteru.configuration.verbose?
48
49
  end
49
50
 
51
+ private
52
+
53
+ def notifiers
54
+ @notifiers ||= [Notifiers::Slack.new, Notifiers::UrlScan.new].select(&:notifiable?)
55
+ end
56
+
50
57
  class << self
51
58
  def execute
52
59
  new.execute
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "active_record"
4
4
 
5
- class InitialSchema < ActiveRecord::Migration[6.1]
5
+ class InitialSchema < ActiveRecord::Migration[7.0]
6
6
  def change
7
7
  create_table :records, if_not_exists: true do |t|
8
8
  t.string :hash, null: false, index: { unique: true }
@@ -19,7 +19,7 @@ class InitialSchema < ActiveRecord::Migration[6.1]
19
19
  end
20
20
  end
21
21
 
22
- class V11Schema < ActiveRecord::Migration[6.1]
22
+ class V11Schema < ActiveRecord::Migration[7.0]
23
23
  def change
24
24
  add_column :records, :source, :string, if_not_exists: true
25
25
  end
@@ -26,7 +26,15 @@ module Miteru
26
26
  begin
27
27
  downloaded_as = HTTPClient.download(kit.url, destination)
28
28
  rescue Down::Error => e
29
- puts "Failed to download: #{kit.url} (#{e})"
29
+ Miteru.logger.error "Failed to download: #{kit.url} (#{e})"
30
+ return
31
+ end
32
+
33
+ # check filesize
34
+ size = File.size downloaded_as
35
+ if size > Miteru.configuration.file_maxsize
36
+ Miteru.logger.info "#{kit.url}'s filesize exceeds the limit: #{size}"
37
+ FileUtils.rm downloaded_as
30
38
  return
31
39
  end
32
40
 
@@ -35,14 +43,14 @@ module Miteru
35
43
  ActiveRecord::Base.connection_pool.with_connection do
36
44
  # Remove a downloaded file if it is not unique
37
45
  unless Record.unique_hash?(hash)
38
- puts "Don't download #{kit.url}. The same hash is already recorded. (SHA256: #{hash})."
46
+ Miteru.logger.info "Don't download #{kit.url}. The same hash is already recorded. (SHA256: #{hash})."
39
47
  FileUtils.rm downloaded_as
40
48
  return
41
49
  end
42
50
 
43
51
  # Record a kit in DB
44
52
  Record.create_by_kit_and_hash(kit, hash)
45
- puts "Download #{kit.url} as #{downloaded_as}"
53
+ Miteru.logger.info "Download #{kit.url} as #{downloaded_as}"
46
54
  end
47
55
  end
48
56
 
@@ -21,7 +21,7 @@ module Miteru
21
21
  ]
22
22
  end.flatten
23
23
  rescue HTTPResponseError, HTTP::Error, JSON::ParserError => e
24
- puts "Failed to load ayashige feed (#{e})"
24
+ Miteru.logger.error "Failed to load ayashige feed (#{e})"
25
25
  []
26
26
  end
27
27
 
@@ -12,7 +12,7 @@ module Miteru
12
12
  body = get(URL)
13
13
  body.to_s.lines.map(&:chomp)
14
14
  rescue HTTPResponseError, HTTP::Error, JSON::ParserError => e
15
- puts "Failed to load phishing database feed (#{e})"
15
+ info "Failed to load phishing database feed (#{e})"
16
16
  []
17
17
  end
18
18
  end
@@ -14,7 +14,7 @@ module Miteru
14
14
  entry["url"]
15
15
  end
16
16
  rescue HTTPResponseError, HTTP::Error, JSON::ParserError => e
17
- puts "Failed to load PhishStats feed (#{e})"
17
+ Miteru.logger.error "Failed to load PhishStats feed (#{e})"
18
18
  []
19
19
  end
20
20
 
@@ -13,13 +13,13 @@ module Miteru
13
13
  end
14
14
 
15
15
  def api
16
- @api ||= ::UrlScan::API.new
16
+ @api ||= ::UrlScan::API.new(Miteru.configuration.urlscan_api_key)
17
17
  end
18
18
 
19
19
  def urls
20
20
  urls_from_community_feed
21
21
  rescue ::UrlScan::ResponseError => e
22
- puts "Failed to load urlscan.io feed (#{e})"
22
+ Miteru.logger.error "Failed to load urlscan.io feed (#{e})"
23
23
  []
24
24
  end
25
25
 
@@ -6,20 +6,20 @@ module Miteru
6
6
  class Feeds
7
7
  class UrlScanPro < Feed
8
8
  def api
9
- @api ||= ::UrlScan::API.new
9
+ @api ||= ::UrlScan::API.new(Miteru.configuration.urlscan_api_key)
10
10
  end
11
11
 
12
12
  def urls
13
13
  urls_from_pro_feed
14
14
  rescue ::UrlScan::ResponseError => e
15
- puts "Failed to load urlscan.io pro feed (#{e})"
15
+ Miteru.logger.error "Failed to load urlscan.io pro feed (#{e})"
16
16
  []
17
17
  end
18
18
 
19
19
  private
20
20
 
21
21
  def api_key?
22
- ENV.key? "URLSCAN_API_KEY"
22
+ Miteru.configuration.urlscan_api_key?
23
23
  end
24
24
 
25
25
  def urls_from_pro_feed
@@ -7,7 +7,7 @@ require "uri"
7
7
  module Miteru
8
8
  class HTTPClient
9
9
  DEFAULT_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
10
- URLSCAN_UA = "miteru/#{Miteru::VERSION}".freeze
10
+ URLSCAN_UA = "miteru/#{Miteru::VERSION}"
11
11
 
12
12
  attr_reader :ssl_context
13
13
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Miteru
4
+ module Notifiers
5
+ class Base
6
+ def notify(website)
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def notifiable?
11
+ raise NotImplementedError
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Miteru
4
+ module Notifiers
5
+ class Slack < Base
6
+ #
7
+ # Notifiy to Slack
8
+ #
9
+ # @param [Miteru::Website website
10
+ #
11
+ def notify(website)
12
+ attachement = Attachement.new(website.url)
13
+ kits = website.kits.select(&:downloaded?)
14
+
15
+ if notifiable? && kits.any?
16
+ notifier = Slack::Notifier.new(Miteru.configuration.slack_webhook_url, channel: Miteru.configuration.slack_channel)
17
+ notifier.post(text: website.message.capitalize, attachments: attachement.to_a)
18
+ end
19
+
20
+ message = kits.any? ? website.message.colorize(:light_red) : website.message
21
+ Miteru.logger.info "#{website.url}: #{message}"
22
+ end
23
+
24
+ def notifiable?
25
+ Miteru.configuration.slack_webhook_url? && Miteru.configuration.post_to_slack?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "urlscan"
4
+
5
+ module Miteru
6
+ module Notifiers
7
+ class UrlScan < Base
8
+ #
9
+ # Notifiy to urlscan.io
10
+ #
11
+ # @param [Miteru::Website website
12
+ #
13
+ def notify(website)
14
+ kits = website.kits.select(&:downloaded?)
15
+ return unless notifiable? && kits.any?
16
+
17
+ kits.each { |kit| submit(kit.url) }
18
+ end
19
+
20
+ def notifiable?
21
+ Miteru.configuration.urlscan_api_key?
22
+ end
23
+
24
+ private
25
+
26
+ def api
27
+ @api ||= ::UrlScan::API.new(Miteru.configuration.urlscan_api_key)
28
+ end
29
+
30
+ def submit(url)
31
+ api.submit(url, tags: ["miteru", "phishkit"], visibility: Miteru.configuration.urlscan_submit_visibility)
32
+ rescue StandardError
33
+ # do nothing
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Miteru
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
data/lib/miteru.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "memist"
4
+ require "semantic_logger"
5
+
3
6
  require "miteru/version"
4
7
 
5
8
  require "miteru/configuration"
@@ -9,6 +12,10 @@ require "miteru/record"
9
12
 
10
13
  require "miteru/mixin"
11
14
 
15
+ require "miteru/notifiers/base"
16
+ require "miteru/notifiers/slack"
17
+ require "miteru/notifiers/urlscan"
18
+
12
19
  require "miteru/error"
13
20
  require "miteru/http_client"
14
21
  require "miteru/kit"
@@ -16,8 +23,20 @@ require "miteru/website"
16
23
  require "miteru/downloader"
17
24
  require "miteru/feeds"
18
25
  require "miteru/attachement"
19
- require "miteru/notifier"
20
26
  require "miteru/crawler"
21
27
  require "miteru/cli"
22
28
 
23
- module Miteru; end
29
+ # Load .env
30
+ require "dotenv/load"
31
+
32
+ module Miteru
33
+ class << self
34
+ include Memist::Memoizable
35
+ def logger
36
+ SemanticLogger.default_level = :info
37
+ SemanticLogger.add_appender(io: $stderr, formatter: :color)
38
+ SemanticLogger["Miteru"]
39
+ end
40
+ memoize :logger
41
+ end
42
+ end
data/miteru.gemspec CHANGED
@@ -9,6 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.version = Miteru::VERSION
10
10
  spec.authors = ["Manabu Niseki"]
11
11
  spec.email = ["manabu.niseki@gmail.com"]
12
+ spec.metadata["rubygems_mfa_required"] = "true"
12
13
 
13
14
  spec.summary = "An experimental phishing kit detector"
14
15
  spec.description = "An experimental phishing kit detector"
@@ -24,28 +25,31 @@ Gem::Specification.new do |spec|
24
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
26
  spec.require_paths = ["lib"]
26
27
 
27
- spec.add_development_dependency "bundler", "~> 2.2"
28
- spec.add_development_dependency "coveralls_reborn", "~> 0.22"
28
+ spec.add_development_dependency "bundler", "~> 2.3"
29
+ spec.add_development_dependency "coveralls_reborn", "~> 0.25"
29
30
  spec.add_development_dependency "glint", "~> 0.1"
30
31
  spec.add_development_dependency "mysql2", "~> 0.5"
31
- spec.add_development_dependency "overcommit", "~> 0.58"
32
- spec.add_development_dependency "pg", "~> 1.2"
32
+ spec.add_development_dependency "overcommit", "~> 0.59"
33
+ spec.add_development_dependency "pg", "~> 1.4"
33
34
  spec.add_development_dependency "rake", "~> 13.0"
34
- spec.add_development_dependency "rspec", "~> 3.10"
35
- spec.add_development_dependency "standard", "~> 1.3"
36
- spec.add_development_dependency "vcr", "~> 6.0"
37
- spec.add_development_dependency "webmock", "~> 3.14"
35
+ spec.add_development_dependency "rspec", "~> 3.11"
36
+ spec.add_development_dependency "standard", "~> 1.14"
37
+ spec.add_development_dependency "vcr", "~> 6.1"
38
+ spec.add_development_dependency "webmock", "~> 3.17"
38
39
  spec.add_development_dependency "webrick", "~> 1.7.0"
39
40
 
40
- spec.add_dependency "activerecord", "~> 6.1"
41
+ spec.add_dependency "activerecord", "~> 7.0"
41
42
  spec.add_dependency "colorize", "~> 0.8"
42
- spec.add_dependency "down", "~> 5.2"
43
- spec.add_dependency "http", "~> 5.0"
44
- spec.add_dependency "oga", "~> 3.3"
45
- spec.add_dependency "parallel", "~> 1.20"
43
+ spec.add_dependency "dotenv", "2.8.1"
44
+ spec.add_dependency "down", "~> 5.3"
45
+ spec.add_dependency "http", "~> 5.1"
46
+ spec.add_dependency "memist", "2.0.2"
47
+ spec.add_dependency "oga", "~> 3.4"
48
+ spec.add_dependency "parallel", "~> 1.22"
49
+ spec.add_dependency "semantic_logger", "4.11.0"
46
50
  spec.add_dependency "slack-notifier", "~> 2.4"
47
51
  spec.add_dependency "sqlite3", "~> 1.4"
48
- spec.add_dependency "thor", "~> 1.1"
49
- spec.add_dependency "urlscan", "~> 0.7"
52
+ spec.add_dependency "thor", "~> 1.2"
53
+ spec.add_dependency "urlscan", "~> 0.8"
50
54
  spec.add_dependency "uuidtools", "~> 2.2"
51
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miteru
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.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-09-12 00:00:00.000000000 Z
11
+ date: 2022-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.2'
19
+ version: '2.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.2'
26
+ version: '2.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: coveralls_reborn
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.22'
33
+ version: '0.25'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.22'
40
+ version: '0.25'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: glint
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,28 +72,28 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.58'
75
+ version: '0.59'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.58'
82
+ version: '0.59'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pg
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.2'
89
+ version: '1.4'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '1.2'
96
+ version: '1.4'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,56 +114,56 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.10'
117
+ version: '3.11'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '3.10'
124
+ version: '3.11'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: standard
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '1.3'
131
+ version: '1.14'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '1.3'
138
+ version: '1.14'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: vcr
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '6.0'
145
+ version: '6.1'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '6.0'
152
+ version: '6.1'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: webmock
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '3.14'
159
+ version: '3.17'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '3.14'
166
+ version: '3.17'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: webrick
169
169
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '6.1'
187
+ version: '7.0'
188
188
  type: :runtime
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: '6.1'
194
+ version: '7.0'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: colorize
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -206,62 +206,104 @@ dependencies:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0.8'
209
+ - !ruby/object:Gem::Dependency
210
+ name: dotenv
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - '='
214
+ - !ruby/object:Gem::Version
215
+ version: 2.8.1
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - '='
221
+ - !ruby/object:Gem::Version
222
+ version: 2.8.1
209
223
  - !ruby/object:Gem::Dependency
210
224
  name: down
211
225
  requirement: !ruby/object:Gem::Requirement
212
226
  requirements:
213
227
  - - "~>"
214
228
  - !ruby/object:Gem::Version
215
- version: '5.2'
229
+ version: '5.3'
216
230
  type: :runtime
217
231
  prerelease: false
218
232
  version_requirements: !ruby/object:Gem::Requirement
219
233
  requirements:
220
234
  - - "~>"
221
235
  - !ruby/object:Gem::Version
222
- version: '5.2'
236
+ version: '5.3'
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: http
225
239
  requirement: !ruby/object:Gem::Requirement
226
240
  requirements:
227
241
  - - "~>"
228
242
  - !ruby/object:Gem::Version
229
- version: '5.0'
243
+ version: '5.1'
230
244
  type: :runtime
231
245
  prerelease: false
232
246
  version_requirements: !ruby/object:Gem::Requirement
233
247
  requirements:
234
248
  - - "~>"
235
249
  - !ruby/object:Gem::Version
236
- version: '5.0'
250
+ version: '5.1'
251
+ - !ruby/object:Gem::Dependency
252
+ name: memist
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - '='
256
+ - !ruby/object:Gem::Version
257
+ version: 2.0.2
258
+ type: :runtime
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - '='
263
+ - !ruby/object:Gem::Version
264
+ version: 2.0.2
237
265
  - !ruby/object:Gem::Dependency
238
266
  name: oga
239
267
  requirement: !ruby/object:Gem::Requirement
240
268
  requirements:
241
269
  - - "~>"
242
270
  - !ruby/object:Gem::Version
243
- version: '3.3'
271
+ version: '3.4'
244
272
  type: :runtime
245
273
  prerelease: false
246
274
  version_requirements: !ruby/object:Gem::Requirement
247
275
  requirements:
248
276
  - - "~>"
249
277
  - !ruby/object:Gem::Version
250
- version: '3.3'
278
+ version: '3.4'
251
279
  - !ruby/object:Gem::Dependency
252
280
  name: parallel
253
281
  requirement: !ruby/object:Gem::Requirement
254
282
  requirements:
255
283
  - - "~>"
256
284
  - !ruby/object:Gem::Version
257
- version: '1.20'
285
+ version: '1.22'
258
286
  type: :runtime
259
287
  prerelease: false
260
288
  version_requirements: !ruby/object:Gem::Requirement
261
289
  requirements:
262
290
  - - "~>"
263
291
  - !ruby/object:Gem::Version
264
- version: '1.20'
292
+ version: '1.22'
293
+ - !ruby/object:Gem::Dependency
294
+ name: semantic_logger
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - '='
298
+ - !ruby/object:Gem::Version
299
+ version: 4.11.0
300
+ type: :runtime
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - '='
305
+ - !ruby/object:Gem::Version
306
+ version: 4.11.0
265
307
  - !ruby/object:Gem::Dependency
266
308
  name: slack-notifier
267
309
  requirement: !ruby/object:Gem::Requirement
@@ -296,28 +338,28 @@ dependencies:
296
338
  requirements:
297
339
  - - "~>"
298
340
  - !ruby/object:Gem::Version
299
- version: '1.1'
341
+ version: '1.2'
300
342
  type: :runtime
301
343
  prerelease: false
302
344
  version_requirements: !ruby/object:Gem::Requirement
303
345
  requirements:
304
346
  - - "~>"
305
347
  - !ruby/object:Gem::Version
306
- version: '1.1'
348
+ version: '1.2'
307
349
  - !ruby/object:Gem::Dependency
308
350
  name: urlscan
309
351
  requirement: !ruby/object:Gem::Requirement
310
352
  requirements:
311
353
  - - "~>"
312
354
  - !ruby/object:Gem::Version
313
- version: '0.7'
355
+ version: '0.8'
314
356
  type: :runtime
315
357
  prerelease: false
316
358
  version_requirements: !ruby/object:Gem::Requirement
317
359
  requirements:
318
360
  - - "~>"
319
361
  - !ruby/object:Gem::Version
320
- version: '0.7'
362
+ version: '0.8'
321
363
  - !ruby/object:Gem::Dependency
322
364
  name: uuidtools
323
365
  requirement: !ruby/object:Gem::Requirement
@@ -371,7 +413,9 @@ files:
371
413
  - lib/miteru/http_client.rb
372
414
  - lib/miteru/kit.rb
373
415
  - lib/miteru/mixin.rb
374
- - lib/miteru/notifier.rb
416
+ - lib/miteru/notifiers/base.rb
417
+ - lib/miteru/notifiers/slack.rb
418
+ - lib/miteru/notifiers/urlscan.rb
375
419
  - lib/miteru/record.rb
376
420
  - lib/miteru/version.rb
377
421
  - lib/miteru/website.rb
@@ -381,7 +425,8 @@ files:
381
425
  homepage: https://github.com/ninoseki/miteru
382
426
  licenses:
383
427
  - MIT
384
- metadata: {}
428
+ metadata:
429
+ rubygems_mfa_required: 'true'
385
430
  post_install_message:
386
431
  rdoc_options: []
387
432
  require_paths:
@@ -397,7 +442,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
397
442
  - !ruby/object:Gem::Version
398
443
  version: '0'
399
444
  requirements: []
400
- rubygems_version: 3.2.22
445
+ rubygems_version: 3.2.14
401
446
  signing_key:
402
447
  specification_version: 4
403
448
  summary: An experimental phishing kit detector
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "colorize"
4
- require "slack-notifier"
5
-
6
- module Miteru
7
- class Notifier
8
- def notify(url:, kits:, message:)
9
- attachement = Attachement.new(url)
10
- kits = kits.select(&:downloaded?)
11
-
12
- if notifiable? && kits.any?
13
- notifier = Slack::Notifier.new(Miteru.configuration.slack_webhook_url, channel: Miteru.configuration.slack_channel)
14
- notifier.post(text: message.capitalize, attachments: attachement.to_a)
15
- end
16
-
17
- message = message.colorize(:light_red) if kits.any?
18
- puts "#{url}: #{message}"
19
- end
20
-
21
- def notifiable?
22
- Miteru.configuration.slack_webhook_url? && Miteru.configuration.post_to_slack?
23
- end
24
- end
25
- end