miteru 0.4.0 → 0.5.0

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: aa876b402ad3fcfe44fb1a66035bdb7649db11383650faf572d94fb8b4c8f498
4
- data.tar.gz: c8ffde9ad933fbe670900d8b6547f5ce35ba7f85bd0a0d1201d3c00518d612bb
3
+ metadata.gz: b3784652417f9e36941b1bc9ed8a76acaa86481a4730223b8ad1913775980097
4
+ data.tar.gz: 47526f0cc44c07a8aa9a651973f0fa4a3d455dfe49abed255f0aed1780abb604
5
5
  SHA512:
6
- metadata.gz: 15bc48dc53696348635d637674c5574d537b8cf220939dce354875706f1a58820b95ecab547da0106a72e76d026d3e067b14438bfbef7ce1ce971737491269e2
7
- data.tar.gz: 86d0aad06740b2013c35ef3920fa27fc1ac811580c08103273f3c073362d37b0e2c8bd0e49c9d8aac63dd06004556b902c6bccaf57f7833670e01d8e907d72a1
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 a phishing kit (#{website.zip_files.join(',')})."
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
- destination = HTTPClient.download(target_url, base_dir)
33
- puts "Download #{target_url} as #{destination}"
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
@@ -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 suspicous_urls
20
- url = "https://urlscan.io/api/v1/search/?q=certstream-suspicious&size=#{size}"
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
- suspicous_urls.each do |url|
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?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Miteru
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -18,7 +18,9 @@ module Miteru
18
18
  @zip_files ||= doc.css("a").map do |a|
19
19
  href = a.get("href")
20
20
  href&.end_with?(".zip") ? href : nil
21
- end.compact
21
+ end.compact.map do |href|
22
+ href.start_with?("/") ? href[1..-1] : href
23
+ end
22
24
  end
23
25
 
24
26
  def ok?
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.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-22 00:00:00.000000000 Z
11
+ date: 2018-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler