snackhack2 0.6.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cda044a6c9ae56812b5742965caa204d3e32d8fe9dee0857806cefd45d058e4e
4
- data.tar.gz: 6f6b5a0c249afdd9691070f481fcaa756721d599b5bf7f1f68909a54c30211f1
3
+ metadata.gz: b016f87e2b46dc87ffab71256f1b5880f3db8b1bf16ccbc35bbe7aeeb0e7fe26
4
+ data.tar.gz: 1a9accfc1fe6f09c5d3e5f624eeeb032441f0fac9a25523c0b08f8b34c9963da
5
5
  SHA512:
6
- metadata.gz: 62c3e1c33052a126536a6c3b2708f2f15acd1a4adbb2d26df1f3ad9ba639c1e55308034872391fc179736e0ad9899c3f633a3273e7217ac5a547ced717f389b9
7
- data.tar.gz: 43943cb44a33159f5fdd31650e8322355882ceb46ce4049ad6e17d900e6bd74e35d83989a205f0a3379c303233ed3359c5abf774fd9fc164fceb4ca763af5e40
6
+ metadata.gz: ce184f5769d385950ebc9a5824f4788398cf301544eacc0dd59a7b2bd64e100f0b4816db9807e307287e8ef89085d18168a575f9b620177dd3bdac53916bcf49
7
+ data.tar.gz: 82efd660a7495c292a45c527cc9e937e73b143c00fb8e36800be34544c9447f3864f07f1d137d351ab2acd70aa126f8d2ace81080acd79cfcbba61a1b6350a54
@@ -8,24 +8,18 @@ module Snackhack2
8
8
  def initialize(port: 443, save_file: true)
9
9
  @site = site
10
10
  @port = port
11
- @headers = Snackhack2.get(@site).headers
12
11
  @save_file = save_file
13
12
  end
14
13
 
15
- def site
16
- # @site.gsub('https://', '')
17
- end
18
-
19
14
  def run
20
15
  nginx
21
16
  apache2
22
17
  wordpress
23
- headers
24
18
  end
25
-
19
+ def headers
20
+ @headers = Snackhack2.get(@site).headers
21
+ end
26
22
  def nginx
27
- return unless @headers['server'].match(/nginx/)
28
-
29
23
  puts "[+] Server is running NGINX... Now checking if #{File.join(@site, 'nginx_status')} is valid..."
30
24
  nginx = Snackhack2.get(File.join(@site, 'nginx_status'))
31
25
  if nginx.code == 200
@@ -37,20 +31,25 @@ module Snackhack2
37
31
 
38
32
  def curl
39
33
  servers = ''
34
+ # rus the curl command to get the headers of the given site.
40
35
  cmd = `curl -s -I #{@site.gsub('https://', '')}`
36
+ # extracts the server header from the curl results
41
37
  version = cmd.split('Server: ')[1].split("\n")[0].strip
42
38
  if @save_file
43
39
  servers += version.to_s
44
40
  else
45
41
  puts "Banner: #{cmd.split('Server: ')[1].split("\n")[0]}"
46
42
  end
43
+
44
+ # saves the results if '@save_file' is set to true.
47
45
  Snackhack2.file_save(@site, 'serverversion', servers) if @save_file
48
46
  end
49
47
 
50
48
  def apache2
51
- if @headers['server'].match(/Apache/)
49
+ if headers['server'].match(/Apache/)
52
50
  puts "[+] Server is running Apache2... Now checking #{File.join(@site, 'server-status')}..."
53
51
  apache = Snackhack2.get(File.join(@site, 'server-status'))
52
+ # status code 200 means the request was successful.
54
53
  if apache.code == 200
55
54
  puts "Check #{@site}/server-status"
56
55
  else
@@ -67,16 +66,89 @@ module Snackhack2
67
66
 
68
67
  puts "[+] Wordpress found [+]\n\n\n"
69
68
  end
70
-
71
- def headers
72
- h = Snackhack2.get(@site).headers
73
- puts "[+] Server Version: #{h['server']}..."
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
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"]
75
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
76
144
  def server
77
145
  @headers['server']
78
146
  end
79
147
 
80
148
  attr_reader :site
81
- end
149
+ private :find_headers
150
+ end
82
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,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snackhack2
4
- class PhishingData
4
+ class PhishingData
5
5
  def domains
6
6
  [
7
7
  ".com",
@@ -44,154 +44,244 @@ module Snackhack2
44
44
  ".work"
45
45
  ]
46
46
  end
47
+ def domain_keywords
48
+ [
49
+ "connect",
50
+ "corp",
51
+ "duo",
52
+ "help",
53
+ "he1p",
54
+ "helpdesk",
55
+ "helpnow",
56
+ "info",
57
+ "internal",
58
+ "mfa",
59
+ "my",
60
+ "okta",
61
+ "onelogin",
62
+ "schedule",
63
+ "service",
64
+ "servicedesk",
65
+ "servicenow",
66
+ "rci",
67
+ "rsa",
68
+ "sso",
69
+ "ssp",
70
+ "support",
71
+ "usa",
72
+ "vpn",
73
+ "work",
74
+ "dev",
75
+ "workspace",
76
+ "it",
77
+ "ops",
78
+ "hr",
79
+ "login",
80
+ "secure"
81
+ ]
82
+ end
47
83
  private :domains
48
84
  end
49
- class PhishingTlds < PhishingData
50
- attr_reader :site
51
- def initialize
52
- @site = site
85
+ class PhishingTlds < PhishingData
86
+ attr_reader :site
87
+ def initialize
88
+ @site = site
89
+ end
90
+ def domain_split
91
+ # This method splits up the value block_given
92
+ # given in @site by the period. Which is used
93
+ # by 'remove_tlds' method to remove the TLDs
94
+ @site.split(".")
95
+ end
96
+ def site=(s)
97
+ @site = s
98
+ end
99
+ def remove_tlds
100
+ # this method function is to remove
101
+ # the TLDs from the @site. For Example
102
+ # it will remove .org, .com
103
+
104
+ ds = domain_split
105
+
106
+ # remove ".com" (last element in array)
107
+ ds.pop
108
+
109
+ # returns the domain w/o the tlds
110
+ ds
111
+ end
112
+ def check_domains(array: true)
113
+ # The function of this method is to
114
+ # check if the given domains are valid or not.
115
+ # By valid I mean resolvable and active.
116
+
117
+
118
+ # if domains is set to true, this array will hold the domains
119
+ domains_out = []
120
+
121
+ # build the list of domains
122
+ generated_tlds = change_tld
123
+
124
+ valid_domains = []
125
+ not_valid_domains = []
126
+
127
+ generated_tlds.each do |domain|
128
+ # if array is true; add the domains to array
129
+ if array
130
+ domains_out << domain
131
+ else
132
+ # if array is false print out the domains
133
+ puts domain
53
134
  end
54
- def domain_split
55
- # This method splits up the value block_given
56
- # given in @site by the period. Which is used
57
- # by 'remove_tlds' method to remove the TLDs
58
- @site.split(".")
135
+ domains_out if array
136
+ end
137
+ end
138
+ def remove_letters(array_out: true)
139
+ # This method will remove letters that
140
+ # occur more than once. For example:
141
+ # google.com would become goggle.com
142
+
143
+ # store the letter count in a hash.
144
+ letter_count = {}
145
+
146
+ ds = remove_tlds
147
+
148
+ # Creates an array with each character being
149
+ # stored in a element. It will loop through the array
150
+ # and figure out the number of occurrences for each character
151
+ ds.shift.split(//).each do |letter|
152
+ if letter_count.has_key?(letter)
153
+ letter_count[letter] += 1
154
+ else
155
+ letter_count[letter] = 1
59
156
  end
60
- def site=(s)
61
- @site = s
157
+ end
158
+
159
+ # After it creates the hash with the character and
160
+ # the number of time it cocures. This method
161
+ # will loop through the hash and check to see
162
+ # if the value is greater than 1. If it is then the key ( the letter)
163
+ # is added to the array named 'letters_with_more_than_one'
164
+ letters_with_more_than_one = []
165
+ letter_count.each do |key, value|
166
+ if value > 1
167
+ letters_with_more_than_one << key
62
168
  end
63
- def remove_tlds
64
- # this method function is to remove
65
- # the TLDs from the @site. For Example
66
- # it will remove .org, .com
67
-
68
- ds = domain_split
69
-
70
- # remove ".com" (last element in array)
71
- ds.pop
72
-
73
- # returns the domain w/o the tlds
74
- ds
169
+ end
170
+
171
+
172
+ ds = remove_tlds
173
+ new_ds = ds.shift
174
+
175
+ # the final array with the duplicates letters removed
176
+ remove_letters_out = []
177
+
178
+ # Loops through the 'letters_with_more_than_one'
179
+ # array and uses 'sub' to remove the occurence
180
+ # of one of the letters
181
+ letters_with_more_than_one.each do |l|
182
+ # removes only first character ( l )
183
+ remove_letters_out << new_ds.sub(l, "")
184
+ # removes ALL chracters ( l )
185
+ remove_letters_out << new_ds.gsub(l, "")
186
+ end
187
+
188
+ domains_with_tlds = []
189
+ # adding the TLDS to the 'remove_letter_out' array
190
+ domains.each do |d|
191
+ remove_letters_out.each do |rl|
192
+ # adds the words ( rl ) and the TLDS ( d )
193
+ # to the domains_with_tld array.
194
+ domains_with_tlds << "#{rl}#{d}"
75
195
  end
76
- def check_domains(array: true)
77
- # The function of this method is to
78
- # check if the given domains are valid or not.
79
- # By valid I mean resolvable and active.
80
-
81
-
82
- # if domains is set to true, this array will hold the domains
83
- domains_out = []
84
-
85
- # build the list of domains
86
- generated_tlds = change_tld
87
-
88
- valid_domains = []
89
- not_valid_domains = []
90
-
91
- generated_tlds.each do |domain|
92
- # if array is true; add the domains to array
93
- if array
94
- domains_out << domain
95
- else
96
- # if array is false print out the domains
97
- puts domain
98
- end
99
- domains_out if array
196
+ end
197
+ if array_out
198
+ domains_with_tlds
199
+ else
200
+ # will print the contents of the array
201
+ # instead of returning the array
202
+ domains_with_tlds.each { |a| puts a }
203
+ end
204
+ end
205
+ def combosquatting
206
+ # where the generated domains will be located.
207
+ results = []
208
+
209
+ # get the domain_keywords array from the PhishingData class.
210
+ keywords = domain_keywords
211
+
212
+ prefixes = ["-", ".", "--"]
213
+ ds = remove_tlds
214
+ # this will generate the 'new_domain' with the keywords
215
+ # as a prefix
216
+ prefixes.each do |pre|
217
+ ds.each do |domain|
218
+ keywords.each do |key|
219
+ new_domain = "#{key}#{pre}#{domain}"
220
+ results << new_domain
100
221
  end
101
222
  end
102
- def remove_letters(array_out: true)
103
- # This method will remove letters that
104
- # occur more than once. For example:
105
- # google.com would become goggle.com
106
-
107
- # store the letter count in a hash.
108
- letter_count = {}
109
-
110
- ds = remove_tlds
111
-
112
- # Creates an array with each character being
113
- # stored in a element. It will loop through the array
114
- # and figure out the number of occurrences for each character
115
- ds.shift.split(//).each do |letter|
116
- if letter_count.has_key?(letter)
117
- letter_count[letter] += 1
118
- else
119
- letter_count[letter] = 1
120
- end
121
- end
122
-
123
- # After it creates the hash with the character and
124
- # the number of time it cocures. This method
125
- # will loop through the hash and check to see
126
- # if the value is greater than 1. If it is then the key ( the letter)
127
- # is added to the array named 'letters_with_more_than_one'
128
- letters_with_more_than_one = []
129
- letter_count.each do |key, value|
130
- if value > 1
131
- letters_with_more_than_one << key
132
- end
133
- end
134
-
135
-
136
- ds = remove_tlds
137
- new_ds = ds.shift
138
-
139
- # the final array with the duplicates letters removed
140
- remove_lettters_out = []
141
-
142
- # Loops through the 'letters_with_more_than_one'
143
- # array and uses 'sub' to remove the occurence
144
- # of one of the letters
145
- letters_with_more_than_one.each do |l|
146
- remove_lettters_out << new_ds.sub(l, "")
147
- end
148
-
149
- if array_out
150
- remove_lettters_out
151
- else
152
- # will print the contents of the array
153
- # instead of returning the array
154
- remove_lettters_out.each { |a| puts a }
223
+ end
224
+ suffixes = ["-", ".", "--"]
225
+ # this will generate the 'new_domain' with the keywords
226
+ # as a suffixes
227
+ suffixes.each do |suf|
228
+ ds.each do |domain|
229
+ keywords.each do |key|
230
+ new_domain = "#{domain}#{suf}#{key}"
231
+ results << new_domain
155
232
  end
156
233
  end
157
- def change_tld(no_tld: true)
158
- # This method will take the inputted site in @site and
159
- # remove the TLDs and add a new TLDs to the domain.
160
- # its uses the 'domain' method in the PhishingData class
161
- # which has an array of a bunch of different tlds.
162
-
234
+ end
235
+ final_results = []
236
+
237
+ # Loops through the domains array in the PhishingData class
238
+ domains.each do |tlds|
239
+ results.each do |r|
240
+ new_domain = "#{r}#{tlds}"
241
+ final_results << new_domain
242
+ end
243
+ end
244
+ final_results
245
+ end
246
+ def change_tld(no_tld: true)
247
+ # This method will take the inputted site in @site and
248
+ # remove the TLDs and add a new TLDs to the domain.
249
+ # its uses the 'domain' method in the PhishingData class
250
+ # which has an array of a bunch of different tlds.
251
+
252
+
253
+ # if the @site does not have a tlds
254
+ if no_tld
255
+ new_domains = []
256
+ # loop through the tlds
257
+ domains.each do |d|
258
+ # combine the inputed @site
259
+ # and the tlds
260
+ new_domains << "#{@site}#{d}"
261
+ end
262
+ new_domains
263
+ else
264
+ # If the @site does have a TLDs.
163
265
 
164
- # if the @site does not have a tlds
165
- if no_tld
166
- new_domains = []
167
- # loop through the tlds
168
- domains.each do |d|
169
- # combine the inputed @site
170
- # and the tlds
171
- new_domains << "#{@site}#{d}"
172
- end
173
- new_domains
174
- else
175
- # If the @site does have a TLDs.
176
-
177
- # this is where the final results
178
- # are stored.
179
- list_of_domains = []
180
-
181
- # removes .com, .org, etc
182
- ds = remove_tlds
183
-
184
- # join the elements together
185
- ds = ds.join(".")
186
-
187
- # loops through the tlds
188
- domains.each do |tlds|
189
- # adds the new domains to the array
190
- list_of_domains << ds + tlds
191
- end
192
- list_of_domains
193
- end
266
+ # this is where the final results
267
+ # are stored.
268
+ list_of_domains = []
269
+
270
+ # removes .com, .org, etc
271
+ ds = remove_tlds
272
+
273
+ # join the elements together
274
+ ds = ds.join(".")
275
+
276
+
277
+ # loops through the tlds
278
+ domains.each do |tlds|
279
+ # adds the new domains to the array
280
+ list_of_domains << ds + tlds
194
281
  end
195
- private :remove_tlds, :domain_split
282
+ list_of_domains
196
283
  end
284
+ end
285
+ private :remove_tlds, :domain_split
286
+ end
197
287
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snackhack2
4
- VERSION = '0.6.5'
4
+ VERSION = '0.6.6'
5
5
  end
data/lib/snackhack2.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'uri'
4
4
  require 'httparty'
5
-
5
+ =begin
6
6
  require_relative 'snackhack2/version'
7
7
  require_relative 'snackhack2/bannergrabber'
8
8
  require_relative 'snackhack2/wordpress'
@@ -36,6 +36,12 @@ require_relative 'snackhack2/ssrf'
36
36
  require_relative 'snackhack2/dns'
37
37
  require_relative 'snackhack2/CVE-2017-9841'
38
38
  require_relative 'snackhack2/phishing_tlds'
39
+ =end
40
+ Dir.glob(File.join(File.dirname(__FILE__), "snackhack2", "*")).each do |file|
41
+ unless File.directory?(file)
42
+ require_relative file
43
+ end
44
+ end
39
45
  module Snackhack2
40
46
  UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
41
47
  def self.read_serverversion
@@ -57,10 +63,17 @@ module Snackhack2
57
63
  end
58
64
  end
59
65
 
60
- def self.file_save(site, type, content, ip: false)
61
- hostname = URI.parse(site).host
62
- File.open("#{hostname}_#{type}.txt", 'w+') { |file| file.write(content) }
63
- puts "[+] Saving file to #{hostname}_#{type}.txt..."
66
+ def self.file_save(site, type, content, ip: false, host: true)
67
+ if host
68
+ hostname = URI.parse(site).host
69
+ File.open("#{hostname}_#{type}.txt", 'w+') { |file| file.write(content) }
70
+ puts "[+] Saving file to #{hostname}_#{type}.txt..."
71
+ else
72
+ File.open("#{site}_#{type}.txt", 'w+') { |file| file.write(content) }
73
+ puts "[+] Saving file to #{site}_#{type}.txt..."
74
+ end
75
+
76
+
64
77
  end
65
78
 
66
79
  def self.get(site)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snackhack2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - mike
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-08 00:00:00.000000000 Z
11
+ date: 2025-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty