snackhack2 0.6.7 → 0.6.9
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/lib/snackhack2/SSL.rb +34 -0
- data/lib/snackhack2/bannergrabber.rb +53 -12
- data/lib/snackhack2/comments.rb +4 -2
- data/lib/snackhack2/dns.rb +2 -1
- data/lib/snackhack2/drupal.rb +7 -5
- data/lib/snackhack2/emails.rb +4 -1
- data/lib/snackhack2/forward_remote.rb +1 -1
- data/lib/snackhack2/google_analytics.rb +18 -6
- data/lib/snackhack2/host_injection.rb +93 -0
- data/lib/snackhack2/iplookup.rb +28 -21
- data/lib/snackhack2/list_users.rb +2 -0
- data/lib/snackhack2/phishing_tlds.rb +1 -11
- data/lib/snackhack2/phone_number.rb +66 -25
- data/lib/snackhack2/portscan.rb +11 -1
- data/lib/snackhack2/robots.rb +33 -15
- data/lib/snackhack2/ruby_comments.rb +46 -0
- data/lib/snackhack2/screenshots.rb +7 -0
- data/lib/snackhack2/sitemap.rb +11 -3
- data/lib/snackhack2/sshbrute.rb +6 -0
- data/lib/snackhack2/ssrf.rb +52 -4
- data/lib/snackhack2/subdomains.rb +10 -7
- data/lib/snackhack2/subdomains2.rb +7 -1
- data/lib/snackhack2/tomcat.rb +22 -9
- data/lib/snackhack2/version.rb +1 -1
- data/lib/snackhack2/webserver_log_cleaner.rb +55 -0
- data/lib/snackhack2/website_links.rb +5 -1
- data/lib/snackhack2/website_meta.rb +5 -5
- data/lib/snackhack2/wordpress.rb +63 -13
- data/lib/snackhack2/wpForo_Forum.rb +1 -0
- data/lib/snackhack2.rb +11 -1
- metadata +5 -3
- data/lib/snackhack2/ssh.rb +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23625b0c0b96d9310abb4adcfe327cbf41bfcd0b30a605b420fdaf39b56587c7
|
|
4
|
+
data.tar.gz: 748b136fb5ec56893c91d2a5e911a642d7f52aebc4b1dd4a3a4372644c107fc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c5d3a5223ea6b1522b0448d9b1e6e01aa3ef1eece72c81888b3b317792533ddeb3c9ebfe517b6069a096b9f21250ef3b93d00c914602a1d5018fd1d7d012f1b
|
|
7
|
+
data.tar.gz: 189d3057f610d1a52b51f7e4745082814ab637fb985cc53f93cef48aa654b12c5fc0775309b5c3625d709228c021e43e0918808a5585390b18d81d93f81cbd52
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'openssl'
|
|
3
|
+
module Snackhack2
|
|
4
|
+
class SSLCert
|
|
5
|
+
attr_accessor :site, :file_save
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@site = site
|
|
9
|
+
@file_save = false
|
|
10
|
+
end
|
|
11
|
+
def get_cert(print_status: false)
|
|
12
|
+
save_txt_file = ''
|
|
13
|
+
begin
|
|
14
|
+
if @site.downcase.include?("https://")
|
|
15
|
+
@site = @site.downcase.gsub("https://", "")
|
|
16
|
+
end
|
|
17
|
+
uri = URI::HTTPS.build(host: @site)
|
|
18
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true)
|
|
19
|
+
cert = response.peer_cert
|
|
20
|
+
if @file_save
|
|
21
|
+
save_txt_file += cert.serial
|
|
22
|
+
else
|
|
23
|
+
if print_status
|
|
24
|
+
puts cert.serial
|
|
25
|
+
else
|
|
26
|
+
return cert.serial
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
rescue OpenSSL::SSL::SSLError,Net::OpenTimeout, Errno::EHOSTUNREACH
|
|
30
|
+
end
|
|
31
|
+
Snackhack2.file_save(@site, 'ssl', save_txt_file) if @file_save
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
require 'socket'
|
|
3
3
|
module Snackhack2
|
|
4
4
|
class BannerGrabber
|
|
@@ -13,23 +13,29 @@ module Snackhack2
|
|
|
13
13
|
def run
|
|
14
14
|
nginx
|
|
15
15
|
apache2
|
|
16
|
+
cloudflare
|
|
16
17
|
wordpress
|
|
17
|
-
|
|
18
|
+
cloudfront
|
|
18
19
|
end
|
|
19
20
|
def headers
|
|
20
21
|
@headers = Snackhack2.get(@site).headers
|
|
21
22
|
end
|
|
22
23
|
def nginx
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
if headers['server'].include?("nginx")
|
|
25
|
+
puts "[+] Server is running NGINX... Now checking if #{File.join(@site, 'nginx_status')} is valid..."
|
|
26
|
+
nginx = Snackhack2.get(File.join(@site, 'nginx_status'))
|
|
27
|
+
if nginx.code == 200
|
|
28
|
+
puts "Check #{@site}/nginx_status"
|
|
29
|
+
else
|
|
30
|
+
puts "Response code: #{nginx.code}... nginx_status not giving 200"
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
puts "[+] No nginx detected..."
|
|
29
34
|
end
|
|
30
35
|
end
|
|
31
36
|
|
|
32
37
|
def curl
|
|
38
|
+
# uses cURL to head a website header
|
|
33
39
|
servers = ''
|
|
34
40
|
# rus the curl command to get the headers of the given site.
|
|
35
41
|
cmd = `curl -s -I #{@site.gsub('https://', '')}`
|
|
@@ -55,16 +61,20 @@ module Snackhack2
|
|
|
55
61
|
else
|
|
56
62
|
puts "[+] Response Code: #{apache.code}...\n\n"
|
|
57
63
|
end
|
|
58
|
-
else
|
|
59
|
-
puts "Apache2 is not found...\n\n"
|
|
60
64
|
end
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
def wordpress
|
|
68
|
+
wp_status = false
|
|
69
|
+
wp_types = ["Yoast SEO plugin", "wp-content", "wp-json"]
|
|
64
70
|
wp = Snackhack2.get(@site).body
|
|
65
|
-
return unless wp.match(/wp-content/)
|
|
71
|
+
# return unless wp.match(/wp-content/)
|
|
72
|
+
wp_types.each do |wp|
|
|
73
|
+
p wp.match(/#{wp}/)
|
|
74
|
+
end
|
|
75
|
+
#puts "[+] Wordpress '/wp-content' found [+]\n\n\n" if wp.match(/wp-content/)
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
|
|
68
78
|
end
|
|
69
79
|
def types
|
|
70
80
|
{
|
|
@@ -116,6 +126,37 @@ module Snackhack2
|
|
|
116
126
|
end
|
|
117
127
|
end
|
|
118
128
|
end
|
|
129
|
+
def cloudfront(print_status: true)
|
|
130
|
+
# the purpose of this method is to
|
|
131
|
+
# check to see if a site has
|
|
132
|
+
# cloudflare in the headers
|
|
133
|
+
|
|
134
|
+
cf_status = false
|
|
135
|
+
cf_count = 0
|
|
136
|
+
|
|
137
|
+
# access the 'types' hash to get the cloudflare strings.
|
|
138
|
+
cf = types[:"aws CloudFront"]
|
|
139
|
+
|
|
140
|
+
# make a single get request to the site defined at '@site'
|
|
141
|
+
find_headers.each do |k,v|
|
|
142
|
+
# if the key is in the array cf
|
|
143
|
+
if cf.include?(k)
|
|
144
|
+
cf_status = true
|
|
145
|
+
cf_count += 1
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
unless print_status
|
|
149
|
+
# cf_status[0] : the status if cloudfront was found
|
|
150
|
+
# cf_count[1] : the number of found elements in the 'cloudfront' hash.
|
|
151
|
+
return [cf_status, cf_count]
|
|
152
|
+
else
|
|
153
|
+
if cf_status
|
|
154
|
+
puts "Cloudfront was found. The count is: #{cf_count}"
|
|
155
|
+
else
|
|
156
|
+
puts "Cloudfront was NOT found. The count is #{cf_count}"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
119
160
|
def detect_header(return_status: true)
|
|
120
161
|
# stores the data found in
|
|
121
162
|
# the headers.
|
data/lib/snackhack2/comments.rb
CHANGED
|
@@ -12,13 +12,15 @@ module Snackhack2
|
|
|
12
12
|
c = Snackhack2.get(@site)
|
|
13
13
|
|
|
14
14
|
if c.code == 200
|
|
15
|
+
# turns the body of the text into an array
|
|
15
16
|
body = c.body.split("\n")
|
|
16
17
|
body.each_with_index do |l, i|
|
|
17
18
|
line = l.strip
|
|
19
|
+
# detects if html code is present
|
|
18
20
|
if line.start_with?('<!--')
|
|
19
|
-
puts body[i].next
|
|
21
|
+
puts body[i].next.strip
|
|
20
22
|
elsif line.include?('<!')
|
|
21
|
-
puts body[i].next
|
|
23
|
+
puts body[i].next.strip
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
else
|
data/lib/snackhack2/dns.rb
CHANGED
data/lib/snackhack2/drupal.rb
CHANGED
|
@@ -19,22 +19,24 @@ module Snackhack2
|
|
|
19
19
|
drupal_score = 0
|
|
20
20
|
d = Snackhack2.get(@site)
|
|
21
21
|
if d.code == 200
|
|
22
|
-
d.headers.each do |k|
|
|
23
|
-
drupal_score += 10 if k.include?('drupal')
|
|
22
|
+
d.headers.each do |k,v|
|
|
23
|
+
drupal_score += 10 if k.downcase.include?('drupal')
|
|
24
|
+
drupal_score += 10 if v.downcase.include?('drupal')
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
|
-
|
|
27
|
-
drupal_score += 10 if v.include?('drupal')
|
|
28
|
-
end
|
|
27
|
+
|
|
29
28
|
doc = Nokogiri::HTML(URI.open(@site))
|
|
29
|
+
# uses xpath to extra the data stored in the meta tags
|
|
30
30
|
posts = doc.xpath('//meta')
|
|
31
31
|
posts.each do |l|
|
|
32
|
+
# display the drupal version and other info
|
|
32
33
|
puts "\n\n[+] Drupal Version: #{l.attributes['content']}\n" if l.attributes['content'].to_s.include?('Drupal')
|
|
33
34
|
end
|
|
34
35
|
puts "\nDrupal Score: #{drupal_score}\n"
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def user_brute
|
|
39
|
+
# enumerate the users by looping 0 to 1000
|
|
38
40
|
(1..1000).each do |user|
|
|
39
41
|
u = Snackhack2.get(File.join(@site, 'user', user.to_s)).body
|
|
40
42
|
if u.include?('Page not found')
|
data/lib/snackhack2/emails.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Snackhack2
|
|
|
6
6
|
class Email
|
|
7
7
|
attr_accessor :max_depth
|
|
8
8
|
|
|
9
|
-
def initialize(site, save_file: true, max_depth:
|
|
9
|
+
def initialize(site, save_file: true, max_depth: 2)
|
|
10
10
|
@site = site
|
|
11
11
|
@save_file = save_file
|
|
12
12
|
@max_depth = max_depth
|
|
@@ -19,8 +19,11 @@ module Snackhack2
|
|
|
19
19
|
Spidr.start_at(@site, max_depth: @max_depth) do |agent|
|
|
20
20
|
agent.every_page do |page|
|
|
21
21
|
body = page.to_s
|
|
22
|
+
# uses a regex to look for email addresses
|
|
22
23
|
if body.scan(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}/)
|
|
24
|
+
# again, uses regex to extract the email addresses and removes duplicates
|
|
23
25
|
email = body.scan(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}/).uniq
|
|
26
|
+
# if emails not found already in the array, it will add the email to the array.
|
|
24
27
|
found_emails << email if !email.include?(found_emails) && !email.empty?
|
|
25
28
|
end
|
|
26
29
|
end
|
|
@@ -5,26 +5,38 @@ module Snackhack2
|
|
|
5
5
|
class GoogleAnalytics
|
|
6
6
|
attr_accessor :site
|
|
7
7
|
|
|
8
|
-
def initialize
|
|
8
|
+
def initialize(print_status: false)
|
|
9
9
|
@site = site
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def run
|
|
13
|
+
# uses a handful of different regexs to extract the Google Analytics
|
|
14
|
+
# code from sites. This is used by the site admin to track and mesaure
|
|
15
|
+
# people who visit the site. This could be used to find more sites
|
|
16
|
+
# they own where they re-use the code.
|
|
17
|
+
gas = []
|
|
13
18
|
a = Snackhack2.get(@site).body
|
|
14
19
|
case a
|
|
15
20
|
when /UA-\d{8}-\d/
|
|
16
|
-
|
|
21
|
+
gas << a.match(/UA-\d{8}-\d/).to_s
|
|
17
22
|
when /GTM-[A-Z0-9]{7}/
|
|
18
|
-
|
|
23
|
+
gas << a.match(/GTM-[A-Z0-9]{7}/).to_s
|
|
19
24
|
when /G-([0-9]+([A-Za-z]+[0-9]+)+)/
|
|
20
|
-
|
|
25
|
+
gas << a.match(/G-([0-9]+([A-Za-z]+[0-9]+)+)/).to_s
|
|
21
26
|
when /G-[A-Za-z0-9]+/
|
|
22
|
-
|
|
27
|
+
gas << a.match(/G-[A-Za-z0-9]+/).to_s
|
|
23
28
|
when /GT-[A-Za-z0-9]+/
|
|
24
|
-
|
|
29
|
+
gas << a.match(/GT-[A-Za-z0-9]+/).to_s
|
|
25
30
|
else
|
|
26
31
|
puts '[+] No Google Analytics found :('
|
|
27
32
|
end
|
|
33
|
+
if @print_status
|
|
34
|
+
gas.each do |g|
|
|
35
|
+
puts g
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
return gas
|
|
39
|
+
end
|
|
28
40
|
end
|
|
29
41
|
end
|
|
30
42
|
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Process.spawn("ruby -run -ehttpd . -p8008")
|
|
4
|
+
# sleep 10
|
|
5
|
+
module Snackhack2
|
|
6
|
+
class HostInjection
|
|
7
|
+
attr_accessor :site, :new_host_ip, :old_host_ip
|
|
8
|
+
# old_host_ip: the IP of the host (public IP) that its supposed to be
|
|
9
|
+
# new_host_ip: the IP of the host to bypass access controls
|
|
10
|
+
def initialize
|
|
11
|
+
@site = site
|
|
12
|
+
end
|
|
13
|
+
def test_all
|
|
14
|
+
p @new_host_ip
|
|
15
|
+
p @old_host_ip
|
|
16
|
+
[ "Host", "\sHost", "\rHost", "X-Forwarded-Host", "\sX-Forwarded-Host",
|
|
17
|
+
"X-Host", "\sX-Host", "\rX-Host", "X-Remote-Addr", "\sX-Remote-Addr",
|
|
18
|
+
"\rX-Remote-Addr", "X-Remote-IP", "\sX-Remote-IP", "\rX-Remote-IP",
|
|
19
|
+
"X-Forwarded-Server", "\sX-Forwarded-Server", "\rX-Forwarded-Server",
|
|
20
|
+
"Forwarded", "\sForwarded", "\rForwarded", "\sX-HTTP-Host-Override",
|
|
21
|
+
"X-HTTP-Host-Override", "\rX-HTTP-Host-Override"].each do |h|
|
|
22
|
+
head = {"Host" => @old_host_ip}
|
|
23
|
+
head[h] = @new_host_ip
|
|
24
|
+
r = HTTParty.get(@site, headers: head)
|
|
25
|
+
puts r.code
|
|
26
|
+
puts "\n==========================\n"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def host_ip
|
|
31
|
+
unless @old_host_ip.nil?
|
|
32
|
+
response = HTTParty.get(@site, headers: { "Host" => @old_host_ip})
|
|
33
|
+
puts response.body
|
|
34
|
+
puts response.code
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
def double_host_ip
|
|
38
|
+
unless @old_host_ip.nil?
|
|
39
|
+
response = HTTParty.get(@site, headers: { "Host" => @old_host_ip, "Host" => @new_host_ip})
|
|
40
|
+
puts response.body
|
|
41
|
+
puts response.code
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
def x_forwarded
|
|
45
|
+
unless @old_host_ip.nil?
|
|
46
|
+
response = HTTParty.get(@site, headers: { "Host" => @old_host_ip, "X-Forwarded-Host" => @new_host_ip})
|
|
47
|
+
puts response.body
|
|
48
|
+
puts response.code
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
def double_x_forwarded
|
|
52
|
+
unless @old_host_ip.nil?
|
|
53
|
+
response = HTTParty.get(@site, headers: { "X-Forwarded-Host" => @old_host_ip, "X-Forwarded-Host" => @new_host_ip})
|
|
54
|
+
puts response.body
|
|
55
|
+
puts response.code
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
def x_forwarded_server
|
|
59
|
+
unless @old_host_ip.nil?
|
|
60
|
+
r = HTTParty.get(@site, headers: {"Host" => @old_host_ip, "X-Forwarded-Server" => @new_host_ip})
|
|
61
|
+
puts r.body
|
|
62
|
+
puts r.code
|
|
63
|
+
r = HTTParty.get(@site, headers: {"X-Forwarded-Server" => @old_host_ip, "X-Forwarded-Server" => @new_host_ip})
|
|
64
|
+
puts r.body
|
|
65
|
+
puts r.code
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
def http_host_override
|
|
69
|
+
unless @old_host_ip.nil?
|
|
70
|
+
r = HTTParty.get(@site, headers: {"Host" => @old_host_ip, "X-HTTP-Host-Override" => @new_host_ip})
|
|
71
|
+
puts r.body
|
|
72
|
+
puts r.code
|
|
73
|
+
r = HTTParty.get(@site, headers: {"X-HTTP-Host-Override" => @old_host_ip, "X-HTTP-Host-Override" => @new_host_ip}).body
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
def extra_return_host
|
|
77
|
+
unless @new_host_ip.nil?
|
|
78
|
+
response = HTTParty.get(@site, headers: {"\rHost" => "#{@new_host_ip}"}, "Host" => "#{old_host_ip}").body
|
|
79
|
+
puts response
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
def extra_space_host
|
|
83
|
+
unless @new_host_ip.nil?
|
|
84
|
+
response = HTTParty.get(@site, headers: {"\sHost" => "#{@new_host_ip}"}, "Host" => "#{old_host_ip}").body
|
|
85
|
+
puts response
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
data/lib/snackhack2/iplookup.rb
CHANGED
|
@@ -2,51 +2,58 @@
|
|
|
2
2
|
|
|
3
3
|
require 'socket'
|
|
4
4
|
require 'colorize'
|
|
5
|
+
|
|
5
6
|
module Snackhack2
|
|
6
7
|
class IpLookup
|
|
7
8
|
attr_accessor :site
|
|
8
9
|
|
|
9
10
|
def initialize(file_save: false)
|
|
10
11
|
@file_save = file_save
|
|
11
|
-
|
|
12
|
+
# Clean the URL immediately to avoid repeating .gsub everywhere
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def site
|
|
16
|
+
@site = @site.gsub(%r{https?://}, '').split('/').first
|
|
12
17
|
end
|
|
13
18
|
|
|
14
19
|
def run
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
# Running all methods and displaying results
|
|
21
|
+
puts "Methods for: #{@site}".bold.blue
|
|
22
|
+
puts "Ping: #{get_ip.join(', ')}"
|
|
23
|
+
puts "NS: #{nslookup.is_a?(Array) ? nslookup.join(', ') : 'Saved to file'}"
|
|
24
|
+
puts "Socket: #{socket_lookup}"
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
def get_ip
|
|
28
|
+
# Uses ping command to get IP of the host
|
|
21
29
|
ips = []
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
output = `ping -c 2 #{@site}`
|
|
31
|
+
# Using scan to find all IP-like patterns
|
|
32
|
+
output.scan(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/).each do |match|
|
|
33
|
+
ip = match.first
|
|
34
|
+
ips << ip unless ips.include?(ip)
|
|
26
35
|
end
|
|
27
36
|
ips
|
|
28
37
|
end
|
|
29
38
|
|
|
30
39
|
def nslookup
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if !ips.include?(new_ip) && !new_ip.nil?
|
|
36
|
-
|
|
37
|
-
ips << new_ip.split('Addresses: ')[1].to_s
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
+
# Uses the nslookup command to extract the IP
|
|
41
|
+
output = `nslookup #{@site}`
|
|
42
|
+
# Simplified extraction using regex for "Address: [IP]"
|
|
43
|
+
ips = output.scan(/Address: (\d{1,3}(?:\.\d{1,3}){3})/).flatten.uniq
|
|
40
44
|
|
|
41
45
|
if @file_save
|
|
42
|
-
Snackhack2.file_save
|
|
46
|
+
# Note: Ensure Snackhack2.file_save is defined in your main module
|
|
47
|
+
Snackhack2.file_save(@site, 'ip_lookup', ips.join("\n"))
|
|
43
48
|
else
|
|
44
49
|
ips
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
|
|
48
|
-
def
|
|
49
|
-
|
|
53
|
+
def socket_lookup
|
|
54
|
+
IPSocket.getaddress(@site)
|
|
55
|
+
rescue SocketError
|
|
56
|
+
"Could not resolve"
|
|
50
57
|
end
|
|
51
58
|
end
|
|
52
|
-
end
|
|
59
|
+
end
|
|
@@ -167,8 +167,6 @@ class PhishingTlds < PhishingData
|
|
|
167
167
|
letters_with_more_than_one << key
|
|
168
168
|
end
|
|
169
169
|
end
|
|
170
|
-
|
|
171
|
-
|
|
172
170
|
ds = remove_tlds
|
|
173
171
|
new_ds = ds.shift
|
|
174
172
|
|
|
@@ -184,15 +182,7 @@ class PhishingTlds < PhishingData
|
|
|
184
182
|
# removes ALL chracters ( l )
|
|
185
183
|
remove_letters_out << new_ds.gsub(l, "")
|
|
186
184
|
end
|
|
187
|
-
|
|
188
|
-
domains_with_tlds = add_tlds(remove_letters_out)
|
|
189
|
-
if array_out
|
|
190
|
-
domains_with_tlds
|
|
191
|
-
else
|
|
192
|
-
# will print the contents of the array
|
|
193
|
-
# instead of returning the array
|
|
194
|
-
domains_with_tlds.each { |a| puts a }
|
|
195
|
-
end
|
|
185
|
+
add_tlds(remove_letters_out)
|
|
196
186
|
end
|
|
197
187
|
def add_tlds(list)
|
|
198
188
|
# takes the newly created domains (list)
|
|
@@ -7,47 +7,88 @@ module Snackhack2
|
|
|
7
7
|
attr_accessor :save_file, :site
|
|
8
8
|
|
|
9
9
|
def initialize(save_file: true)
|
|
10
|
-
@site = site
|
|
10
|
+
@site = site
|
|
11
11
|
@save_file = save_file
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
attr_reader :save_file
|
|
15
15
|
|
|
16
16
|
def run
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
regex = http.body
|
|
21
|
-
phone = regex.scan(/((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})/)
|
|
22
|
-
out = phone.map { |n| n[0] }.compact
|
|
23
|
-
numbers << out
|
|
17
|
+
found_numbers = []
|
|
18
|
+
unless @site.include?("https://")
|
|
19
|
+
@site = "https://#{@site}"
|
|
24
20
|
else
|
|
25
|
-
|
|
21
|
+
@site = site
|
|
26
22
|
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
http = Snackhack2.get(@site).body
|
|
24
|
+
case http
|
|
25
|
+
when (/((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})/)
|
|
26
|
+
ph_1 = http.scan(/((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})/).flatten
|
|
27
|
+
found_numbers << ph_1
|
|
28
|
+
when /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/
|
|
29
|
+
ph_2 = http.scan(/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/).flatten
|
|
30
|
+
found_numbers << ph_2
|
|
31
|
+
when (/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/)
|
|
32
|
+
ph_3 = http.scan(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/).flatten
|
|
33
|
+
found_numbers << ph_3
|
|
34
|
+
when (/^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$/).flatten
|
|
35
|
+
ph_4 = http.scan((/^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$/))
|
|
36
|
+
found_numbers << ph_4
|
|
37
|
+
when (/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/)
|
|
38
|
+
ph_5 = http.scan(/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/)
|
|
39
|
+
found_numbers << ph_5
|
|
40
|
+
when (/^\+?[1-9][0-9]{7,14}$/)
|
|
41
|
+
ph_6 = http.scan(/^\+?[1-9][0-9]{7,14}$/)
|
|
42
|
+
found_numbers << ph_6
|
|
43
|
+
when (/^\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/)
|
|
44
|
+
ph_7 = http.scan(/^\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/)
|
|
45
|
+
found_numbers << ph_7
|
|
46
|
+
end
|
|
47
|
+
numbers = found_numbers.flatten.compact
|
|
48
|
+
if @save_file
|
|
49
|
+
Snackhack2.file_save(@site, 'phone_numbers', numbers.join("\n"))
|
|
50
|
+
else
|
|
51
|
+
return numbers
|
|
52
|
+
end
|
|
32
53
|
end
|
|
33
|
-
|
|
34
54
|
def spider
|
|
35
|
-
|
|
55
|
+
found_numbers = []
|
|
36
56
|
Spidr.start_at(@site, max_depth: 4) do |agent|
|
|
37
57
|
agent.every_page do |page|
|
|
38
58
|
body = page.to_s
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
# regex to extract phone numbers
|
|
60
|
+
case body
|
|
61
|
+
when (/((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})/)
|
|
62
|
+
ph_1 = http.scan(/((\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4})/).flatten
|
|
63
|
+
found_numbers << ph_1
|
|
64
|
+
when /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/
|
|
65
|
+
ph_2 = http.scan(/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/).flatten
|
|
66
|
+
found_numbers << ph_2
|
|
67
|
+
when (/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/)
|
|
68
|
+
ph_3 = http.scan(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/).flatten
|
|
69
|
+
found_numbers << ph_3
|
|
70
|
+
when (/^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$/).flatten
|
|
71
|
+
ph_4 = http.scan((/^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$/))
|
|
72
|
+
found_numbers << ph_4
|
|
73
|
+
when (/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/)
|
|
74
|
+
ph_5 = http.scan(/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/)
|
|
75
|
+
found_numbers << ph_5
|
|
76
|
+
when (/^\+?[1-9][0-9]{7,14}$/)
|
|
77
|
+
ph_6 = http.scan(/^\+?[1-9][0-9]{7,14}$/)
|
|
78
|
+
found_numbers << ph_6
|
|
79
|
+
when (/^\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/)
|
|
80
|
+
ph_7 = http.scan(/^\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/)
|
|
81
|
+
found_numbers << ph_7
|
|
45
82
|
end
|
|
46
83
|
end
|
|
47
84
|
end
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
85
|
+
unless phone_numbers.empty?
|
|
86
|
+
if @save_file
|
|
87
|
+
Snackhack2.file_save(@site, 'phonenumbers', phone_numbers.join("\n"))
|
|
88
|
+
else
|
|
89
|
+
return phone_numbers
|
|
90
|
+
end
|
|
91
|
+
end
|
|
51
92
|
end
|
|
52
93
|
end
|
|
53
94
|
end
|
data/lib/snackhack2/portscan.rb
CHANGED
|
@@ -13,13 +13,17 @@ module Snackhack2
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def run
|
|
16
|
+
# runs `tcp` with threads
|
|
16
17
|
threads = []
|
|
18
|
+
# creates all the ports between 1 and 1000
|
|
17
19
|
ports = [*1..1000]
|
|
18
20
|
ports.each { |i| threads << Thread.new { tcp(i) } }
|
|
19
21
|
threads.each(&:join)
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def mass_scan
|
|
25
|
+
# uses the `generate_ips` to generate radom
|
|
26
|
+
# IPs. then performs the scan
|
|
23
27
|
generate_ips.each do |ips|
|
|
24
28
|
tcp = PortScan.new
|
|
25
29
|
tcp.ip = ips
|
|
@@ -28,6 +32,8 @@ module Snackhack2
|
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def generate_ips
|
|
35
|
+
# generate a bunch of different Ips to an
|
|
36
|
+
# array named `ips`.
|
|
31
37
|
ips = []
|
|
32
38
|
@count.to_i.times do |_c|
|
|
33
39
|
ips << Array.new(4) { rand(256) }.join('.')
|
|
@@ -36,6 +42,10 @@ module Snackhack2
|
|
|
36
42
|
end
|
|
37
43
|
|
|
38
44
|
def ports_extractor(port)
|
|
45
|
+
# Looks through the files in the folder that
|
|
46
|
+
# match '_port_scan.txt' which extracts the
|
|
47
|
+
# ports
|
|
48
|
+
|
|
39
49
|
ip = []
|
|
40
50
|
files = Dir['*_port_scan.txt']
|
|
41
51
|
files.each do |f|
|
|
@@ -62,7 +72,7 @@ module Snackhack2
|
|
|
62
72
|
return if open_ports.empty?
|
|
63
73
|
|
|
64
74
|
return unless @display
|
|
65
|
-
|
|
75
|
+
# displays the open ports and IPs
|
|
66
76
|
open_ports.each do |port|
|
|
67
77
|
puts "#{ip} - #{port} is open\n"
|
|
68
78
|
end
|