miteru 0.12.0 → 0.12.1
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 +4 -4
- data/README.md +2 -2
- data/lib/miteru.rb +1 -0
- data/lib/miteru/cli.rb +1 -1
- data/lib/miteru/crawler.rb +4 -8
- data/lib/miteru/downloader.rb +12 -15
- data/lib/miteru/kit.rb +30 -0
- data/lib/miteru/notifier.rb +3 -4
- data/lib/miteru/version.rb +1 -1
- data/lib/miteru/website.rb +16 -12
- data/miteru.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c06dbaa1d46bc20c70d44bf5a3fda286e45a9f5bdb5046e9c900e3c6aa5e86a5
|
4
|
+
data.tar.gz: c512cddc5e3c53875e9cc0c0c7db5b61e45fb301ce7cac2a0ab5b46167729df4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7321f78b8d68ce7434f9aaf29b4d781b0cac49ccf48b6a4f9944e6154c55ad0185bc7fe91625a46d7dece574f121d41523df63e761efa264fd4866370c85ccbd
|
7
|
+
data.tar.gz: 4589f29b656ecec1fe9cc03cad0395b49b5f0a9bf674fb36bbcf13b4b2ebfa6cb0601f1d80ea1b94a2fd9f5d33f23b3654c6bc5852a810977da93dcf39f6a2f6
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ Miteru is an experimental phishing kit detection tool.
|
|
10
10
|
## How it works
|
11
11
|
|
12
12
|
- It collects phishy URLs from the following feeds:
|
13
|
-
- [urlscan.io
|
13
|
+
- [CertStream-Suspicious feed via urlscan.io](https://urlscan.io/search/#certstream-suspicious)
|
14
14
|
- [OpenPhish feed via urlscan.io](https://urlscan.io/search/#OpenPhish)
|
15
15
|
- [PhishTank feed via urlscan.io](https://urlscan.io/search/#PhishTank)
|
16
16
|
- [Ayashige feed](https://github.com/ninoseki/ayashige)
|
@@ -20,7 +20,7 @@ Miteru is an experimental phishing kit detection tool.
|
|
20
20
|
## Features
|
21
21
|
|
22
22
|
- [x] Phishing kit detection & collection.
|
23
|
-
- [x] Slack
|
23
|
+
- [x] Slack notification.
|
24
24
|
- [x] Threading.
|
25
25
|
|
26
26
|
## Installation
|
data/lib/miteru.rb
CHANGED
data/lib/miteru/cli.rb
CHANGED
@@ -4,7 +4,7 @@ require "thor"
|
|
4
4
|
|
5
5
|
module Miteru
|
6
6
|
class CLI < Thor
|
7
|
-
method_option :auto_download, type: :boolean, default: false, desc: "Enable or disable auto-download of
|
7
|
+
method_option :auto_download, type: :boolean, default: false, desc: "Enable or disable auto-download of phishing kits"
|
8
8
|
method_option :directory_traveling, type: :boolean, default: false, desc: "Enable or disable directory traveling"
|
9
9
|
method_option :download_to, type: :string, default: "/tmp", desc: "Directory to download file(s)"
|
10
10
|
method_option :post_to_slack, type: :boolean, default: false, desc: "Post a message to Slack if it detects a phishing kit"
|
data/lib/miteru/crawler.rb
CHANGED
@@ -31,12 +31,8 @@ module Miteru
|
|
31
31
|
|
32
32
|
Parallel.each(feeds.suspicious_urls, in_threads: threads) do |url|
|
33
33
|
website = Website.new(url)
|
34
|
-
if website.
|
35
|
-
|
36
|
-
notify(website.url, website.compressed_files)
|
37
|
-
else
|
38
|
-
notify(website.url, website.compressed_files) if verbose
|
39
|
-
end
|
34
|
+
downloader.download_kits(website.kits) if website.has_kits? && auto_download?
|
35
|
+
notify(website) if verbose || website.has_kits?
|
40
36
|
rescue OpenSSL::SSL::SSLError, HTTP::Error, LL::ParserError, Addressable::URI::InvalidURIError => _
|
41
37
|
next
|
42
38
|
end
|
@@ -54,8 +50,8 @@ module Miteru
|
|
54
50
|
).execute
|
55
51
|
end
|
56
52
|
|
57
|
-
def notify(
|
58
|
-
@notifier.notify(url, message)
|
53
|
+
def notify(website)
|
54
|
+
@notifier.notify(url: website.url, kits: website.kits, message: website.message)
|
59
55
|
end
|
60
56
|
|
61
57
|
def auto_download?
|
data/lib/miteru/downloader.rb
CHANGED
@@ -13,33 +13,30 @@ module Miteru
|
|
13
13
|
raise ArgumentError, "#{base_dir} is not existing." unless Dir.exist?(base_dir)
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
filename = download_filename(target_url)
|
16
|
+
def download_kits(kits)
|
17
|
+
kits.each do |kit|
|
18
|
+
filename = download_filename(kit)
|
20
19
|
destination = filepath_to_download(filename)
|
21
20
|
begin
|
22
|
-
|
23
|
-
if duplicated?(
|
24
|
-
puts "Do not download #{
|
25
|
-
FileUtils.rm
|
21
|
+
downloaded_filepath = HTTPClient.download(kit.url, destination)
|
22
|
+
if duplicated?(downloaded_filepath)
|
23
|
+
puts "Do not download #{kit.url} because there is a file that has a same hash value in the directory (SHA256: #{sha256(downloaded_filepath)})."
|
24
|
+
FileUtils.rm downloaded_filepath
|
26
25
|
else
|
27
|
-
puts "Download #{
|
26
|
+
puts "Download #{kit.url} as #{downloaded_filepath}"
|
28
27
|
end
|
29
28
|
rescue Down::Error => e
|
30
|
-
puts "Failed to download: #{
|
29
|
+
puts "Failed to download: #{kit.url} (#{e})"
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
private
|
36
35
|
|
37
|
-
def download_filename(
|
38
|
-
|
39
|
-
extname = File.extname(filename)
|
40
|
-
domain = URI(url).hostname
|
36
|
+
def download_filename(kit)
|
37
|
+
domain = URI(kit.base_url).hostname
|
41
38
|
|
42
|
-
"#{domain}_#{
|
39
|
+
"#{domain}_#{kit.basename}_#{SecureRandom.alphanumeric(10)}#{kit.extname}"
|
43
40
|
end
|
44
41
|
|
45
42
|
def filepath_to_download(filename)
|
data/lib/miteru/kit.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Miteru
|
4
|
+
class Kit
|
5
|
+
VALID_EXTENSIONS = [".zip", ".rar", ".7z", ".tar", ".gz"].freeze
|
6
|
+
|
7
|
+
attr_reader :base_url, :link
|
8
|
+
|
9
|
+
def initialize(base_url:, link:)
|
10
|
+
@base_url = base_url
|
11
|
+
@link = link.start_with?("/") ? link[1..-1] : link
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
VALID_EXTENSIONS.include? extname
|
16
|
+
end
|
17
|
+
|
18
|
+
def extname
|
19
|
+
File.extname(link)
|
20
|
+
end
|
21
|
+
|
22
|
+
def basename
|
23
|
+
File.basename(link)
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
"#{base_url}/#{basename}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/miteru/notifier.rb
CHANGED
@@ -9,11 +9,10 @@ module Miteru
|
|
9
9
|
@post_to_slack = post_to_slack
|
10
10
|
end
|
11
11
|
|
12
|
-
def notify(url
|
13
|
-
message = compressed_files.empty? ? "it doesn't contain a phishing kit." : "it might contain phishing kit(s): (#{compressed_files.join(', ')})."
|
12
|
+
def notify(url:, kits:, message:)
|
14
13
|
attachement = Attachement.new(url)
|
15
14
|
|
16
|
-
if post_to_slack? && !
|
15
|
+
if post_to_slack? && !kits.empty?
|
17
16
|
slack = Slack::Incoming::Webhooks.new(slack_webhook_url, channel: slack_channel)
|
18
17
|
slack.post(
|
19
18
|
url,
|
@@ -24,7 +23,7 @@ module Miteru
|
|
24
23
|
)
|
25
24
|
end
|
26
25
|
|
27
|
-
message = message.colorize(:light_red) unless
|
26
|
+
message = message.colorize(:light_red) unless kits.empty?
|
28
27
|
puts "#{url}: #{message}"
|
29
28
|
end
|
30
29
|
|
data/lib/miteru/version.rb
CHANGED
data/lib/miteru/website.rb
CHANGED
@@ -13,13 +13,12 @@ module Miteru
|
|
13
13
|
doc.at_css("title")&.text
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
16
|
+
def kits
|
17
|
+
@kits ||= doc.css("a").map do |a|
|
18
|
+
link = a.get("href")
|
19
|
+
kit = Kit.new(base_url: url, link: link.to_s)
|
20
|
+
kit.valid? ? kit : nil
|
21
|
+
end.compact
|
23
22
|
end
|
24
23
|
|
25
24
|
def ok?
|
@@ -30,16 +29,21 @@ module Miteru
|
|
30
29
|
title == "Index of /"
|
31
30
|
end
|
32
31
|
|
33
|
-
def
|
34
|
-
!
|
32
|
+
def kits?
|
33
|
+
!kits.empty?
|
35
34
|
end
|
36
35
|
|
37
|
-
def
|
38
|
-
ok? && index? &&
|
39
|
-
rescue
|
36
|
+
def has_kits?
|
37
|
+
ok? && index? && kits?
|
38
|
+
rescue OpenSSL::SSL::SSLError, HTTP::Error, LL::ParserError, Addressable::URI::InvalidURIError => _
|
40
39
|
false
|
41
40
|
end
|
42
41
|
|
42
|
+
def message
|
43
|
+
kit_names = kits.map(&:basename).join(", ")
|
44
|
+
kits? ? "it might contain phishing kit(s): (#{kit_names})." : "it doesn't contain a phishing kit."
|
45
|
+
end
|
46
|
+
|
43
47
|
private
|
44
48
|
|
45
49
|
def response
|
data/miteru.gemspec
CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_dependency "down", "~> 4.8"
|
37
37
|
spec.add_dependency "http", "~> 4.1"
|
38
38
|
spec.add_dependency "oga", "~> 2.15"
|
39
|
-
spec.add_dependency "parallel", "~> 1.
|
39
|
+
spec.add_dependency "parallel", "~> 1.16"
|
40
40
|
spec.add_dependency "slack-incoming-webhooks", "~> 0.2"
|
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.
|
4
|
+
version: 0.12.1
|
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-03-
|
11
|
+
date: 2019-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '1.
|
173
|
+
version: '1.16'
|
174
174
|
type: :runtime
|
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.
|
180
|
+
version: '1.16'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: slack-incoming-webhooks
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,6 +236,7 @@ files:
|
|
236
236
|
- lib/miteru/feeds/feed.rb
|
237
237
|
- lib/miteru/feeds/urlscan.rb
|
238
238
|
- lib/miteru/http_client.rb
|
239
|
+
- lib/miteru/kit.rb
|
239
240
|
- lib/miteru/notifier.rb
|
240
241
|
- lib/miteru/version.rb
|
241
242
|
- lib/miteru/website.rb
|