miteru 0.9.1 → 0.9.2
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 +1 -1
- data/lib/miteru.rb +1 -0
- data/lib/miteru/crawler.rb +6 -39
- data/lib/miteru/downloader.rb +42 -0
- data/lib/miteru/version.rb +1 -1
- data/lib/miteru/website.rb +3 -12
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8370829b3ad8da53b7c73070fd972269b09ea27c6c7dce1a3da5d855f81da27
|
4
|
+
data.tar.gz: c017feecfeaa27912de5dc898f23b430652270a16852510785109d60ed04891a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0796be92ea1586ec57f12a4157097d65ea0d49e151eb8876eda3b406ca05908b0bc01ff021f270ab5a1467bda415e281909ef47502f1fb490d5285c69dd1bd9b'
|
7
|
+
data.tar.gz: edbc8c6cce3d85cbfb8bdac217d7ca0ee9d3dfc353a3b7a3c1c7f7ad132b7d9ee80960bda1bba638b859f53d2805a7634901d47fd9a913630b16b0552d463078
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ Usage:
|
|
37
37
|
miteru execute
|
38
38
|
|
39
39
|
Options:
|
40
|
-
[--auto-download], [--no-auto-download] # Enable or disable auto-download of
|
40
|
+
[--auto-download], [--no-auto-download] # Enable or disable auto-download of compressed file(s)
|
41
41
|
[--directory-traveling], [--no-directory-traveling] # Enable or disable directory traveling
|
42
42
|
[--download-to=DOWNLOAD_TO] # Directory to download file(s)
|
43
43
|
# Default: /tmp
|
data/lib/miteru.rb
CHANGED
data/lib/miteru/crawler.rb
CHANGED
@@ -10,7 +10,7 @@ module Miteru
|
|
10
10
|
class Crawler
|
11
11
|
attr_reader :auto_download
|
12
12
|
attr_reader :directory_traveling
|
13
|
-
attr_reader :
|
13
|
+
attr_reader :downloader
|
14
14
|
attr_reader :size
|
15
15
|
attr_reader :threads
|
16
16
|
attr_reader :verbose
|
@@ -22,7 +22,7 @@ module Miteru
|
|
22
22
|
def initialize(auto_download: false, directory_traveling: false, download_to: "/tmp", post_to_slack: false, size: 100, threads: 10, verbose: false)
|
23
23
|
@auto_download = auto_download
|
24
24
|
@directory_traveling = directory_traveling
|
25
|
-
@
|
25
|
+
@downloader = Downloader.new(download_to)
|
26
26
|
@post_to_slack = post_to_slack
|
27
27
|
@size = size
|
28
28
|
@threads = threads
|
@@ -59,6 +59,7 @@ module Miteru
|
|
59
59
|
rescue URI::InvalidURIError => _
|
60
60
|
return []
|
61
61
|
end
|
62
|
+
|
62
63
|
base = "#{uri.scheme}://#{uri.hostname}"
|
63
64
|
return [base] unless directory_traveling
|
64
65
|
|
@@ -82,23 +83,17 @@ module Miteru
|
|
82
83
|
def execute
|
83
84
|
puts "Loaded #{suspicious_urls.length} URLs to crawl." if verbose
|
84
85
|
|
85
|
-
websites = []
|
86
86
|
Parallel.each(suspicious_urls, in_threads: threads) do |url|
|
87
87
|
website = Website.new(url)
|
88
|
-
|
89
88
|
if website.has_kit?
|
90
89
|
message = "#{website.url}: it might contain phishing kit(s) (#{website.compressed_files.join(', ')})."
|
91
90
|
puts message.colorize(:light_red)
|
92
|
-
|
93
|
-
download_compressed_files(website.url, website.compressed_files
|
91
|
+
post_a_message_to_slack(message) if post_to_slack? && valid_slack_setting?
|
92
|
+
downloader.download_compressed_files(website.url, website.compressed_files) if auto_download?
|
94
93
|
else
|
95
94
|
puts "#{website.url}: it doesn't contain a phishing kit." if verbose
|
96
95
|
end
|
97
|
-
break
|
98
|
-
rescue StandardError => e
|
99
|
-
puts "Failed to load #{url} (#{e})" if verbose
|
100
96
|
end
|
101
|
-
websites
|
102
97
|
end
|
103
98
|
|
104
99
|
def self.execute(auto_download: false, directory_traveling: false, download_to: "/tmp", post_to_slack: false, size: 100, threads: 10, verbose: false)
|
@@ -113,24 +108,7 @@ module Miteru
|
|
113
108
|
).execute
|
114
109
|
end
|
115
110
|
|
116
|
-
def
|
117
|
-
compressed_files.each do |path|
|
118
|
-
target_url = "#{url}/#{path}"
|
119
|
-
begin
|
120
|
-
download_file_path = HTTPClient.download(target_url, base_dir)
|
121
|
-
if duplicated?(download_file_path, base_dir)
|
122
|
-
puts "Do not download #{target_url} because there is a same hash file in the directory (SHA256: #{sha256(download_file_path)})."
|
123
|
-
FileUtils.rm download_file_path
|
124
|
-
else
|
125
|
-
puts "Download #{target_url} as #{download_file_path}"
|
126
|
-
end
|
127
|
-
rescue Down::Error => e
|
128
|
-
puts "Failed to download: #{target_url} (#{e})"
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def post_to_slack(message)
|
111
|
+
def post_a_message_to_slack(message)
|
134
112
|
webhook_url = ENV["SLACK_WEBHOOK_URL"]
|
135
113
|
raise ArgumentError, "Please set the Slack webhook URL via SLACK_WEBHOOK_URL env" unless webhook_url
|
136
114
|
|
@@ -154,17 +132,6 @@ module Miteru
|
|
154
132
|
|
155
133
|
private
|
156
134
|
|
157
|
-
def sha256(path)
|
158
|
-
digest = Digest::SHA256.file(path)
|
159
|
-
digest.hexdigest
|
160
|
-
end
|
161
|
-
|
162
|
-
def duplicated?(file_path, base_dir)
|
163
|
-
base = sha256(file_path)
|
164
|
-
sha256s = Dir.glob("#{base_dir}/*.zip").map { |path| sha256(path) }
|
165
|
-
sha256s.select { |sha256| sha256 == base }.length > 1
|
166
|
-
end
|
167
|
-
|
168
135
|
def get(url)
|
169
136
|
res = HTTP.follow(max_hops: 3).get(url)
|
170
137
|
raise HTTPResponseError if res.code != 200
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Miteru
|
4
|
+
class Downloader
|
5
|
+
attr_reader :base_dir
|
6
|
+
|
7
|
+
def initialize(base_dir = "/tmp")
|
8
|
+
@base_dir = base_dir
|
9
|
+
raise ArgumentError, "#{base_dir} is not existing." unless Dir.exist?(base_dir)
|
10
|
+
end
|
11
|
+
|
12
|
+
def download_compressed_files(url, compressed_files)
|
13
|
+
compressed_files.each do |path|
|
14
|
+
target_url = "#{url}/#{path}"
|
15
|
+
begin
|
16
|
+
download_file_path = HTTPClient.download(target_url, base_dir)
|
17
|
+
if duplicated?(download_file_path, base_dir)
|
18
|
+
puts "Do not download #{target_url} because there is a same hash file in the directory (SHA256: #{sha256(download_file_path)})."
|
19
|
+
FileUtils.rm download_file_path
|
20
|
+
else
|
21
|
+
puts "Download #{target_url} as #{download_file_path}"
|
22
|
+
end
|
23
|
+
rescue Down::Error => e
|
24
|
+
puts "Failed to download: #{target_url} (#{e})"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def sha256(path)
|
32
|
+
digest = Digest::SHA256.file(path)
|
33
|
+
digest.hexdigest
|
34
|
+
end
|
35
|
+
|
36
|
+
def duplicated?(file_path, base_dir)
|
37
|
+
base = sha256(file_path)
|
38
|
+
sha256s = Dir.glob("#{base_dir}/*.zip").map { |path| sha256(path) }
|
39
|
+
sha256s.select { |sha256| sha256 == base }.length > 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/miteru/version.rb
CHANGED
data/lib/miteru/website.rb
CHANGED
@@ -7,7 +7,6 @@ module Miteru
|
|
7
7
|
attr_reader :url
|
8
8
|
def initialize(url)
|
9
9
|
@url = url
|
10
|
-
build
|
11
10
|
end
|
12
11
|
|
13
12
|
def title
|
@@ -36,17 +35,9 @@ module Miteru
|
|
36
35
|
end
|
37
36
|
|
38
37
|
def has_kit?
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def build
|
43
|
-
doc
|
44
|
-
end
|
45
|
-
|
46
|
-
def unbuild
|
47
|
-
@doc = nil
|
48
|
-
@response = nil
|
49
|
-
@compressed_files = nil
|
38
|
+
ok? && index? && compressed_files?
|
39
|
+
rescue StandardError => _
|
40
|
+
false
|
50
41
|
end
|
51
42
|
|
52
43
|
private
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miteru
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manabu Niseki
|
@@ -213,6 +213,7 @@ files:
|
|
213
213
|
- lib/miteru.rb
|
214
214
|
- lib/miteru/cli.rb
|
215
215
|
- lib/miteru/crawler.rb
|
216
|
+
- lib/miteru/downloader.rb
|
216
217
|
- lib/miteru/error.rb
|
217
218
|
- lib/miteru/http_client.rb
|
218
219
|
- lib/miteru/version.rb
|