miteru 0.12.8 → 0.12.9

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: 45b69c99d0a7475dbc37340003f846679b20fbf401726c76f30bc1ac9f456393
4
- data.tar.gz: 33d7dfc24d05922f586f870928e0a5a0876d2f25217136e7918daf96ad2dda3c
3
+ metadata.gz: 82dd344be4204fb882bc86551cdc78d98f2e3822867bae69b06b34458de795d6
4
+ data.tar.gz: 8fe4f2cd077c697e52fca5016138ebb6420e4e335abafeda42a98a29624b6f79
5
5
  SHA512:
6
- metadata.gz: 2b5956777da3f37214b7bd9e715e3aefdd6d417aba579e90a1011df322c26ed033bb34d1891203849198a20958c3e6cf7a884c362f2026c19719a8f5252d23d2
7
- data.tar.gz: 6cb041ca54de93a22ed52453403e23206dbc0c26070fe00df65aed2122df7502cf9568a914cf6421de97dfdca73f6cf75b46f33d9ac0f6428b42357bd8ccf172
6
+ metadata.gz: 37a1635d4e782e52aef19858e6da6a1130db3bbc36e93e428da1f3e7a169bc52a74b1fb3f3d98e8b778c63dddc85e9e43672903dd68048cec83d824faed42dce
7
+ data.tar.gz: 706bad5277ca67650ff671b6ef761cd06429a915ef83b0934e29138fa1f61c6b3fb647ccf10f7675070e5fcade56914658edf5ec3b0daa76777996b9e11fe768
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "miteru/version"
4
4
 
5
+ require "miteru/configuration"
5
6
  require "miteru/error"
6
7
  require "miteru/http_client"
7
8
  require "miteru/kit"
@@ -14,7 +14,20 @@ module Miteru
14
14
  method_option :verbose, type: :boolean, default: true
15
15
  desc "execute", "Execute the crawler"
16
16
  def execute
17
- Crawler.execute options.map { |k, v| [k.to_sym, v] }.to_h
17
+ Miteru.configure do |config|
18
+ config.auto_download = options["auto_download"]
19
+ config.ayashige = options["ayashige"]
20
+ config.directory_traveling = options["directory_traveling"]
21
+ config.download_to = options["download_to"]
22
+ config.post_to_slack = options["post_to_slack"]
23
+ config.size = options["size"]
24
+ config.verbose = options["verbose"]
25
+
26
+ threads = options["threads"]
27
+ config.threads = threads if threads
28
+ end
29
+
30
+ Crawler.execute
18
31
  end
19
32
  end
20
33
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parallel"
4
+
5
+ module Miteru
6
+ class Configuration
7
+ # @return [Boolean]
8
+ attr_accessor :auto_download
9
+
10
+ # @return [Boolean]
11
+ attr_accessor :ayashige
12
+
13
+ # @return [Boolean]
14
+ attr_accessor :directory_traveling
15
+
16
+ # @return [String]
17
+ attr_accessor :download_to
18
+
19
+ # @return [Boolean]
20
+ attr_accessor :post_to_slack
21
+
22
+ # @return [Integer]
23
+ attr_accessor :size
24
+
25
+ # @return [Integer]
26
+ attr_accessor :threads
27
+
28
+ # @return [Boolean]
29
+ attr_accessor :verbose
30
+
31
+ def initialize
32
+ @auto_download = false
33
+ @ayashige = false
34
+ @directory_traveling = false
35
+ @download_to = "/tmp"
36
+ @post_to_slack = false
37
+ @size = 100
38
+ @threads = Parallel.processor_count
39
+ @verbaose = false
40
+ end
41
+
42
+ def auto_download?
43
+ @auto_download
44
+ end
45
+
46
+ def ayashige?
47
+ @ayashige
48
+ end
49
+
50
+ def directory_traveling?
51
+ @directory_traveling
52
+ end
53
+
54
+ def post_to_slack?
55
+ @post_to_slack
56
+ end
57
+
58
+ def verbose?
59
+ @verbaose
60
+ end
61
+ end
62
+
63
+ # @return [Miteru::Configuration] Miteru's current configuration
64
+ def self.configuration
65
+ @configuration ||= Configuration.new
66
+ end
67
+
68
+ # Set Miteru's configuration
69
+ # @param config [Miteru::Configuration]
70
+ def self.configuration=(config)
71
+ @configuration = config
72
+ end
73
+
74
+ # Modify Miteru's current configuration
75
+ # @yieldparam [Miteru::Configuration] config current Miteru config
76
+ def self.configure
77
+ yield configuration
78
+ end
79
+ end
@@ -6,50 +6,36 @@ require "uri"
6
6
 
7
7
  module Miteru
8
8
  class Crawler
9
- attr_reader :ayashige
10
- attr_reader :directory_traveling
11
9
  attr_reader :downloader
12
10
  attr_reader :feeds
13
- attr_reader :size
14
- attr_reader :threads
15
- attr_reader :verbose
16
-
17
- def initialize(auto_download: false, ayashige: false, directory_traveling: false, download_to: "/tmp", post_to_slack: false, size: 100, threads: Parallel.processor_count, verbose: false)
18
- @auto_download = auto_download
19
- @ayashige = ayashige
20
- @directory_traveling = directory_traveling
21
- @downloader = Downloader.new(download_to)
22
- @size = size
23
- @threads = threads
24
- @verbose = verbose
25
-
26
- @feeds = Feeds.new(size: size, ayashige: ayashige, directory_traveling: directory_traveling)
27
- @notifier = Notifier.new(post_to_slack)
11
+
12
+ def initialize
13
+ @downloader = Downloader.new(Miteru.configuration.download_to)
14
+
15
+ @feeds = Feeds.new
16
+ @notifier = Notifier.new
17
+ end
18
+
19
+ def crawl(url)
20
+ website = Website.new(url)
21
+ downloader.download_kits(website.kits) if website.has_kits? && auto_download?
22
+ notify(website) if website.has_kits? || verbose?
23
+ rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError => _e
24
+ nil
28
25
  end
29
26
 
30
27
  def execute
31
- puts "Loaded #{feeds.suspicious_urls.length} URLs to crawl. (crawling in #{threads} threads)" if verbose
32
-
33
- Parallel.each(feeds.suspicious_urls, in_threads: threads) do |url|
34
- website = Website.new(url)
35
- downloader.download_kits(website.kits) if website.has_kits? && auto_download?
36
- notify(website) if verbose || website.has_kits?
37
- rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError => _e
38
- next
28
+ threads = Miteru.configuration.threads
29
+ suspicious_urls = feeds.suspicious_urls
30
+ puts "Loaded #{suspicious_urls.length} URLs to crawl. (crawling in #{threads} threads)" if verbose?
31
+
32
+ Parallel.each(suspicious_urls, in_threads: threads) do |url|
33
+ crawl url
39
34
  end
40
35
  end
41
36
 
42
- def self.execute(auto_download: false, ayashige: false, directory_traveling: false, download_to: "/tmp", post_to_slack: false, size: 100, threads: Parallel.processor_count, verbose: false)
43
- new(
44
- auto_download: auto_download,
45
- ayashige: ayashige,
46
- directory_traveling: directory_traveling,
47
- download_to: download_to,
48
- post_to_slack: post_to_slack,
49
- size: size,
50
- threads: threads,
51
- verbose: verbose
52
- ).execute
37
+ def self.execute
38
+ new.execute
53
39
  end
54
40
 
55
41
  def notify(website)
@@ -57,7 +43,11 @@ module Miteru
57
43
  end
58
44
 
59
45
  def auto_download?
60
- @auto_download
46
+ Miteru.configuration.auto_download?
47
+ end
48
+
49
+ def verbose?
50
+ Miteru.configuration.verbose?
61
51
  end
62
52
  end
63
53
  end
@@ -38,7 +38,7 @@ module Miteru
38
38
  def download_filename(kit)
39
39
  domain = URI(kit.base_url).hostname
40
40
 
41
- "#{domain}_#{kit.basename}_#{SecureRandom.alphanumeric(10)}#{kit.extname}"
41
+ "#{domain}_#{kit.filename}_#{SecureRandom.alphanumeric(10)}#{kit.extname}"
42
42
  end
43
43
 
44
44
  def filepath_to_download(filename)
@@ -6,14 +6,13 @@ require_relative "./feeds/urlscan"
6
6
 
7
7
  module Miteru
8
8
  class Feeds
9
- def initialize(size: 100, ayashige: false, directory_traveling: false)
10
- @feeds = [UrlScan.new(size)]
11
- @feeds << Ayashige.new if ayashige
12
- @directory_traveling = directory_traveling
9
+ def initialize
10
+ @feeds = [UrlScan.new(Miteru.configuration.size)]
11
+ @feeds << Ayashige.new if Miteru.configuration.ayashige?
13
12
  end
14
13
 
15
14
  def directory_traveling?
16
- @directory_traveling
15
+ Miteru.configuration.directory_traveling?
17
16
  end
18
17
 
19
18
  def suspicious_urls
@@ -20,7 +20,7 @@ module Miteru
20
20
  "http://#{domain}"
21
21
  ]
22
22
  end.flatten
23
- rescue HTTPResponseError => e
23
+ rescue HTTPResponseError, JSON::ParserError => e
24
24
  puts "Failed to load ayashige feed (#{e})"
25
25
  []
26
26
  end
@@ -25,7 +25,7 @@ module Miteru
25
25
 
26
26
  res = JSON.parse(get(url))
27
27
  res["results"].map { |result| result.dig("task", "url") }
28
- rescue HTTPResponseError => e
28
+ rescue HTTPResponseError, JSON::ParserError => e
29
29
  puts "Failed to load urlscan.io feed (#{e})"
30
30
  []
31
31
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi"
4
+
3
5
  module Miteru
4
6
  class Kit
5
7
  VALID_EXTENSIONS = [".zip", ".rar", ".7z", ".tar", ".gz"].freeze
@@ -25,6 +27,10 @@ module Miteru
25
27
  File.basename(link)
26
28
  end
27
29
 
30
+ def filename
31
+ CGI.unescape basename
32
+ end
33
+
28
34
  def url
29
35
  "#{base_url}/#{basename}"
30
36
  end
@@ -1,23 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "colorize"
4
- require "slack/incoming/webhooks"
4
+ require "slack-notifier"
5
5
 
6
6
  module Miteru
7
7
  class Notifier
8
- def initialize(post_to_slack = false)
9
- @post_to_slack = post_to_slack
10
- end
11
-
12
8
  def notify(url:, kits:, message:)
13
9
  attachement = Attachement.new(url)
14
10
 
15
11
  if post_to_slack? && !kits.empty?
16
- slack = Slack::Incoming::Webhooks.new(slack_webhook_url, channel: slack_channel)
17
- slack.post(
18
- message,
19
- attachments: attachement.to_a
20
- )
12
+ notifier = Slack::Notifier.new(slack_webhook_url, channel: slack_channel)
13
+ notifier.post(text: message, attachments: attachement.to_a)
21
14
  end
22
15
 
23
16
  message = message.colorize(:light_red) unless kits.empty?
@@ -25,7 +18,7 @@ module Miteru
25
18
  end
26
19
 
27
20
  def post_to_slack?
28
- @post_to_slack && slack_webhook_url?
21
+ slack_webhook_url? && Miteru.configuration.post_to_slack?
29
22
  end
30
23
 
31
24
  def slack_webhook_url
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Miteru
4
- VERSION = "0.12.8"
4
+ VERSION = "0.12.9"
5
5
  end
@@ -41,7 +41,7 @@ module Miteru
41
41
  def message
42
42
  return "It doesn't contain a phishing kit." unless kits?
43
43
 
44
- kit_names = kits.map(&:basename).join(", ")
44
+ kit_names = kits.map(&:filename).join(", ")
45
45
  noun = kits.length == 1 ? "a phishing kit" : "phishing kits"
46
46
  "It might contain #{noun}: #{kit_names}."
47
47
  end
@@ -37,6 +37,6 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "http", "~> 4.1"
38
38
  spec.add_dependency "oga", "~> 2.15"
39
39
  spec.add_dependency "parallel", "~> 1.17"
40
- spec.add_dependency "slack-incoming-webhooks", "~> 0.2"
40
+ spec.add_dependency "slack-notifier", "~> 2.3"
41
41
  spec.add_dependency "thor", "~> 0.19"
42
42
  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: 0.12.8
4
+ version: 0.12.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -179,19 +179,19 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '1.17'
181
181
  - !ruby/object:Gem::Dependency
182
- name: slack-incoming-webhooks
182
+ name: slack-notifier
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '0.2'
187
+ version: '2.3'
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: '0.2'
194
+ version: '2.3'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: thor
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -228,6 +228,7 @@ files:
228
228
  - lib/miteru.rb
229
229
  - lib/miteru/attachement.rb
230
230
  - lib/miteru/cli.rb
231
+ - lib/miteru/configuration.rb
231
232
  - lib/miteru/crawler.rb
232
233
  - lib/miteru/downloader.rb
233
234
  - lib/miteru/error.rb