miteru 0.4.0 → 0.5.0
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/cli.rb +21 -3
- data/lib/miteru/crawler.rb +36 -4
- data/lib/miteru/version.rb +1 -1
- data/lib/miteru/website.rb +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3784652417f9e36941b1bc9ed8a76acaa86481a4730223b8ad1913775980097
|
4
|
+
data.tar.gz: 47526f0cc44c07a8aa9a651973f0fa4a3d455dfe49abed255f0aed1780abb604
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 124a5071040ee603dab9e5986064566e6e61d2acb812d052bc8cee69a673253894004b1824c3fac80fa467674640c2a21edec37a14aa1b22d1d03d40c7b99b4c
|
7
|
+
data.tar.gz: 7da8680a710bef8081b2ba279843b53a28fba36c29290ba9566ce3e40fd892ac714a92feec4008236d2b84246ac5bbaa3d94600d008b39953c6103630faa3627
|
data/README.md
CHANGED
@@ -9,8 +9,8 @@ Miteru is an experimental phishing kit detection tool.
|
|
9
9
|
|
10
10
|
## How it works
|
11
11
|
|
12
|
-
- It collects phishing suspicious URLs from [urlscan.io](https://urlscan.io/search/#certstream-suspicious).
|
13
|
-
- It checks a suspicious URL whether it contains a phishing kit (`*.zip` file) or not.
|
12
|
+
- It collects phishing suspicious URLs from [urlscan.io](https://urlscan.io/search/#certstream-suspicious) and [OpenPhish community feed](https://openphish.com/feed.txt).
|
13
|
+
- It checks a suspicious URL whether it has a directory listing and contains a phishing kit (`*.zip` file) or not.
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
data/lib/miteru/cli.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "colorize"
|
4
|
+
require "digest"
|
5
|
+
require "fileutils"
|
4
6
|
require "http"
|
5
7
|
require "thor"
|
6
8
|
|
@@ -17,7 +19,7 @@ module Miteru
|
|
17
19
|
websites.each do |website|
|
18
20
|
next unless website.has_kit?
|
19
21
|
|
20
|
-
message = "#{website.url}: it might contain
|
22
|
+
message = "#{website.url}: it might contain phishing kit(s) (#{website.zip_files.join(', ')})."
|
21
23
|
puts message.colorize(:light_red)
|
22
24
|
post_to_slack(message) if options[:post_to_slack] && valid_slack_setting?
|
23
25
|
download_zip_files(website.url, website.zip_files, options[:download_to]) if options[:auto_download]
|
@@ -29,14 +31,30 @@ module Miteru
|
|
29
31
|
zip_files.each do |path|
|
30
32
|
target_url = "#{url}/#{path}"
|
31
33
|
begin
|
32
|
-
|
33
|
-
|
34
|
+
download_file_path = HTTPClient.download(target_url, base_dir)
|
35
|
+
if duplicated?(download_file_path, base_dir)
|
36
|
+
puts "Do not download #{target_url} because there is a same hash file in the directory (SHA256: #{sha256(download_file_path)})."
|
37
|
+
FileUtils.rm download_file_path
|
38
|
+
else
|
39
|
+
puts "Download #{target_url} as #{download_file_path}"
|
40
|
+
end
|
34
41
|
rescue Down::Error => e
|
35
42
|
puts "Failed to download: #{target_url} (#{e})"
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
47
|
+
def sha256(path)
|
48
|
+
digest = Digest::SHA256.file(path)
|
49
|
+
digest.hexdigest
|
50
|
+
end
|
51
|
+
|
52
|
+
def duplicated?(file_path, base_dir)
|
53
|
+
base = sha256(file_path)
|
54
|
+
sha256s = Dir.glob("#{base_dir}/*.zip").map { |path| sha256(path) }
|
55
|
+
sha256s.select { |sha256| sha256 == base }.length > 1
|
56
|
+
end
|
57
|
+
|
40
58
|
def valid_slack_setting?
|
41
59
|
ENV["SLACK_WEBHOOK_URL"] != nil
|
42
60
|
end
|
data/lib/miteru/crawler.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "thread/pool"
|
4
3
|
require "http"
|
4
|
+
require "json"
|
5
|
+
require "thread/pool"
|
6
|
+
require "uri"
|
5
7
|
|
6
8
|
module Miteru
|
7
9
|
class Crawler
|
@@ -9,6 +11,9 @@ module Miteru
|
|
9
11
|
attr_reader :size
|
10
12
|
attr_reader :verbose
|
11
13
|
|
14
|
+
URLSCAN_ENDPOINT = "https://urlscan.io/api/v1"
|
15
|
+
OPENPHISH_ENDPOINT = "https://openphish.com"
|
16
|
+
|
12
17
|
def initialize(size: 100, verbose: false)
|
13
18
|
@threads = 10
|
14
19
|
@size = size
|
@@ -16,17 +21,44 @@ module Miteru
|
|
16
21
|
raise ArgumentError, "size must be less than 100,000" if size > 100_000
|
17
22
|
end
|
18
23
|
|
19
|
-
def
|
20
|
-
url = "
|
24
|
+
def urlscan_feed
|
25
|
+
url = "#{URLSCAN_ENDPOINT}/search/?q=certstream-suspicious&size=#{size}"
|
21
26
|
res = JSON.parse(get(url))
|
22
27
|
res["results"].map { |result| result.dig("task", "url") }
|
23
28
|
end
|
24
29
|
|
30
|
+
def openphish_feed
|
31
|
+
res = get("#{OPENPHISH_ENDPOINT}/feed.txt")
|
32
|
+
res.lines.map(&:chomp)
|
33
|
+
end
|
34
|
+
|
35
|
+
def breakdown(url)
|
36
|
+
begin
|
37
|
+
uri = URI.parse(url)
|
38
|
+
rescue URI::InvalidURIError => _
|
39
|
+
return []
|
40
|
+
end
|
41
|
+
base = "#{uri.scheme}://#{uri.hostname}"
|
42
|
+
[base]
|
43
|
+
# TODO: Should add a option for burute force directory
|
44
|
+
# segments = uri.path.split("/")
|
45
|
+
# if segments.length.zero?
|
46
|
+
# [base]
|
47
|
+
# else
|
48
|
+
# (0...segments.length).map { |idx| "#{base}#{segments[0..idx].join('/')}" }
|
49
|
+
# end
|
50
|
+
end
|
51
|
+
|
52
|
+
def suspicious_urls
|
53
|
+
urls = urlscan_feed + openphish_feed
|
54
|
+
urls.map { |url| breakdown(url) }.flatten.uniq.sort
|
55
|
+
end
|
56
|
+
|
25
57
|
def execute
|
26
58
|
pool = Thread.pool(threads)
|
27
59
|
websites = []
|
28
60
|
|
29
|
-
|
61
|
+
suspicious_urls.each do |url|
|
30
62
|
pool.process do
|
31
63
|
website = Website.new(url)
|
32
64
|
puts "#{website.url}: it doesn't contain a phishing kit." if verbose && !website.has_kit?
|
data/lib/miteru/version.rb
CHANGED
data/lib/miteru/website.rb
CHANGED
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.
|
4
|
+
version: 0.5.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: 2018-09-
|
11
|
+
date: 2018-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|