miteru 0.12.8 → 0.12.9

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: 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