yawast 0.5.0.beta2 → 0.5.0.beta3
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/CHANGELOG.md +6 -0
- data/README.md +312 -244
- data/bin/yawast +2 -0
- data/lib/resources/common_file.txt +29 -0
- data/lib/resources/srv_list.txt +775 -0
- data/lib/resources/subdomain_list.txt +2354 -0
- data/lib/scanner/core.rb +1 -1
- data/lib/scanner/generic.rb +6 -107
- data/lib/scanner/plugins/dns/generic.rb +195 -0
- data/lib/scanner/plugins/ssl/sweet32.rb +85 -0
- data/lib/scanner/ssl.rb +18 -50
- data/lib/scanner/ssl_labs.rb +1 -1
- data/lib/version.rb +1 -1
- data/yawast.gemspec +1 -0
- metadata +20 -2
data/lib/scanner/core.rb
CHANGED
data/lib/scanner/generic.rb
CHANGED
@@ -1,116 +1,10 @@
|
|
1
1
|
require 'ipaddr_extensions'
|
2
2
|
require 'json'
|
3
|
+
require 'public_suffix'
|
3
4
|
|
4
5
|
module Yawast
|
5
6
|
module Scanner
|
6
7
|
class Generic
|
7
|
-
def self.server_info(uri, options)
|
8
|
-
begin
|
9
|
-
puts 'DNS Information:'
|
10
|
-
|
11
|
-
dns = Resolv::DNS.new
|
12
|
-
Resolv::DNS.open do |resv|
|
13
|
-
a = resv.getresources(uri.host, Resolv::DNS::Resource::IN::A)
|
14
|
-
unless a.empty?
|
15
|
-
a.each do |ip|
|
16
|
-
begin
|
17
|
-
host_name = dns.getname(ip.address)
|
18
|
-
rescue
|
19
|
-
host_name = 'N/A'
|
20
|
-
end
|
21
|
-
|
22
|
-
Yawast::Utilities.puts_info "\t\t#{ip.address} (#{host_name})"
|
23
|
-
|
24
|
-
# if address is private, force internal SSL mode, don't show links
|
25
|
-
if IPAddr.new(ip.address.to_s, Socket::AF_INET).private?
|
26
|
-
options.internalssl = true
|
27
|
-
else
|
28
|
-
#show network info
|
29
|
-
get_network_info ip
|
30
|
-
get_network_location_info ip
|
31
|
-
|
32
|
-
puts "\t\t\thttps://www.shodan.io/host/#{ip.address}"
|
33
|
-
puts "\t\t\thttps://censys.io/ipv4/#{ip.address}"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
aaaa = resv.getresources(uri.host, Resolv::DNS::Resource::IN::AAAA)
|
39
|
-
unless aaaa.empty?
|
40
|
-
aaaa.each do |ip|
|
41
|
-
begin
|
42
|
-
host_name = dns.getname(ip.address)
|
43
|
-
rescue
|
44
|
-
host_name = 'N/A'
|
45
|
-
end
|
46
|
-
|
47
|
-
Yawast::Utilities.puts_info "\t\t#{ip.address} (#{host_name})"
|
48
|
-
|
49
|
-
# if address is private, force internal SSL mode, don't show links
|
50
|
-
if IPAddr.new(ip.address.to_s, Socket::AF_INET6).private?
|
51
|
-
options.internalssl = true
|
52
|
-
else
|
53
|
-
#show network info
|
54
|
-
get_network_info ip
|
55
|
-
get_network_location_info ip
|
56
|
-
|
57
|
-
puts "\t\t\thttps://www.shodan.io/host/#{ip.address.to_s.downcase}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
txt = resv.getresources(uri.host, Resolv::DNS::Resource::IN::TXT)
|
63
|
-
unless txt.empty?
|
64
|
-
txt.each do |rec|
|
65
|
-
Yawast::Utilities.puts_info "\t\tTXT: #{rec.data}"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
mx = resv.getresources(uri.host, Resolv::DNS::Resource::IN::MX)
|
70
|
-
unless mx.empty?
|
71
|
-
mx.each do |rec|
|
72
|
-
Yawast::Utilities.puts_info "\t\tMX: #{rec.exchange} (#{rec.preference})"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
ns = resv.getresources(uri.host, Resolv::DNS::Resource::IN::NS)
|
77
|
-
unless ns.empty?
|
78
|
-
ns.each do |rec|
|
79
|
-
Yawast::Utilities.puts_info "\t\tNS: #{rec.name}"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
puts
|
85
|
-
rescue => e
|
86
|
-
Yawast::Utilities.puts_error "Error getting basic information: #{e.message}"
|
87
|
-
raise
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.get_network_info(ip)
|
92
|
-
begin
|
93
|
-
network_info = JSON.parse(Net::HTTP.get(URI("https://api.iptoasn.com/v1/as/ip/#{ip.address}")))
|
94
|
-
|
95
|
-
Yawast::Utilities.puts_info "\t\t\t#{network_info['as_country_code']} - #{network_info['as_description']}"
|
96
|
-
rescue => e
|
97
|
-
Yawast::Utilities.puts_error "Error getting network information: #{e.message}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.get_network_location_info(ip)
|
102
|
-
begin
|
103
|
-
info = JSON.parse(Net::HTTP.get(URI("https://freegeoip.net/json/#{ip.address}")))
|
104
|
-
location = [info['city'], info['region_name'], info['country_code']].reject { |c| c.empty? }.join(', ')
|
105
|
-
|
106
|
-
if location != nil && !location.empty?
|
107
|
-
Yawast::Utilities.puts_info "\t\t\t#{location}"
|
108
|
-
end
|
109
|
-
rescue => e
|
110
|
-
Yawast::Utilities.puts_error "Error getting location information: #{e.message}"
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
8
|
def self.head_info(head, uri)
|
115
9
|
begin
|
116
10
|
server = ''
|
@@ -242,6 +136,11 @@ module Yawast
|
|
242
136
|
unless elements.include?(' HttpOnly') || elements.include?(' httponly')
|
243
137
|
Yawast::Utilities.puts_warn "\t\t\tCookie missing HttpOnly flag"
|
244
138
|
end
|
139
|
+
|
140
|
+
#check for SameSite cookies
|
141
|
+
unless elements.include?(' SameSite') || elements.include?(' samesite')
|
142
|
+
Yawast::Utilities.puts_warn "\t\t\tCookie missing SameSite flag"
|
143
|
+
end
|
245
144
|
end
|
246
145
|
|
247
146
|
puts ''
|
@@ -0,0 +1,195 @@
|
|
1
|
+
module Yawast
|
2
|
+
module Scanner
|
3
|
+
module Plugins
|
4
|
+
module DNS
|
5
|
+
class Generic
|
6
|
+
def self.dns_info(uri, options)
|
7
|
+
begin
|
8
|
+
puts 'DNS Information:'
|
9
|
+
root_domain = PublicSuffix.parse(uri.host).domain
|
10
|
+
|
11
|
+
dns = Resolv::DNS.new
|
12
|
+
Resolv::DNS.open do |resv|
|
13
|
+
a = resv.getresources(uri.host, Resolv::DNS::Resource::IN::A)
|
14
|
+
unless a.empty?
|
15
|
+
a.each do |ip|
|
16
|
+
begin
|
17
|
+
host_name = dns.getname(ip.address)
|
18
|
+
rescue
|
19
|
+
host_name = 'N/A'
|
20
|
+
end
|
21
|
+
|
22
|
+
Yawast::Utilities.puts_info "\t\t#{ip.address} (#{host_name})"
|
23
|
+
|
24
|
+
# if address is private, force internal SSL mode, don't show links
|
25
|
+
if IPAddr.new(ip.address.to_s, Socket::AF_INET).private?
|
26
|
+
options.internalssl = true
|
27
|
+
else
|
28
|
+
#show network info
|
29
|
+
Yawast::Utilities.puts_info "\t\t\t#{get_network_info(ip.address)}"
|
30
|
+
get_network_location_info ip
|
31
|
+
|
32
|
+
puts "\t\t\thttps://www.shodan.io/host/#{ip.address}"
|
33
|
+
puts "\t\t\thttps://censys.io/ipv4/#{ip.address}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
aaaa = resv.getresources(uri.host, Resolv::DNS::Resource::IN::AAAA)
|
39
|
+
unless aaaa.empty?
|
40
|
+
aaaa.each do |ip|
|
41
|
+
begin
|
42
|
+
host_name = dns.getname(ip.address)
|
43
|
+
rescue
|
44
|
+
host_name = 'N/A'
|
45
|
+
end
|
46
|
+
|
47
|
+
Yawast::Utilities.puts_info "\t\t#{ip.address} (#{host_name})"
|
48
|
+
|
49
|
+
# if address is private, force internal SSL mode, don't show links
|
50
|
+
if IPAddr.new(ip.address.to_s, Socket::AF_INET6).private?
|
51
|
+
options.internalssl = true
|
52
|
+
else
|
53
|
+
#show network info
|
54
|
+
Yawast::Utilities.puts_info "\t\t\t#{get_network_info(ip.address)}"
|
55
|
+
get_network_location_info ip
|
56
|
+
|
57
|
+
puts "\t\t\thttps://www.shodan.io/host/#{ip.address.to_s.downcase}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
txt = resv.getresources(uri.host, Resolv::DNS::Resource::IN::TXT)
|
63
|
+
unless txt.empty?
|
64
|
+
txt.each do |rec|
|
65
|
+
Yawast::Utilities.puts_info "\t\tTXT: #{rec.data}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#check for higher-level TXT records, if we aren't already at the top
|
70
|
+
if root_domain != uri.host
|
71
|
+
txt = resv.getresources(root_domain, Resolv::DNS::Resource::IN::TXT)
|
72
|
+
unless txt.empty?
|
73
|
+
txt.each do |rec|
|
74
|
+
Yawast::Utilities.puts_info "\t\tTXT (#{root_domain}): #{rec.data}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
mx = resv.getresources(uri.host, Resolv::DNS::Resource::IN::MX)
|
80
|
+
unless mx.empty?
|
81
|
+
mx.each do |rec|
|
82
|
+
ip = resv.getaddress rec.exchange
|
83
|
+
|
84
|
+
Yawast::Utilities.puts_info "\t\tMX: #{rec.exchange} (#{rec.preference}) - #{ip} (#{get_network_info(ip.to_s)})"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
#check for higher-level MX records, if we aren't already at the top
|
89
|
+
if root_domain != uri.host
|
90
|
+
mx = resv.getresources(root_domain, Resolv::DNS::Resource::IN::MX)
|
91
|
+
unless mx.empty?
|
92
|
+
mx.each do |rec|
|
93
|
+
ip = resv.getaddress rec.exchange
|
94
|
+
|
95
|
+
Yawast::Utilities.puts_info "\t\tMX (#{root_domain}): #{rec.exchange} (#{rec.preference}) - #{ip} (#{get_network_info(ip.to_s)})"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
ns = resv.getresources(root_domain, Resolv::DNS::Resource::IN::NS)
|
101
|
+
unless ns.empty?
|
102
|
+
ns.each do |rec|
|
103
|
+
ip = resv.getaddress rec.name
|
104
|
+
|
105
|
+
Yawast::Utilities.puts_info "\t\tNS: #{rec.name} - #{ip} (#{get_network_info(ip.to_s)})"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
if options.srv
|
110
|
+
File.open(File.dirname(__FILE__) + '/../../../resources/srv_list.txt', 'r') do |f|
|
111
|
+
f.each_line do |line|
|
112
|
+
host = line.strip + '.' + root_domain
|
113
|
+
begin
|
114
|
+
srv = resv.getresources(host, Resolv::DNS::Resource::IN::SRV)
|
115
|
+
|
116
|
+
unless srv.empty?
|
117
|
+
srv.each do |rec|
|
118
|
+
ip = resv.getaddress rec.target
|
119
|
+
|
120
|
+
Yawast::Utilities.puts_info "\t\tSRV: #{host}: #{rec.target}:#{rec.port} - #{ip} (#{get_network_info(ip.to_s)})"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
rescue
|
124
|
+
#if this fails, don't really care
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if options.subdomains
|
131
|
+
File.open(File.dirname(__FILE__) + '/../../../resources/subdomain_list.txt', 'r') do |f|
|
132
|
+
f.each_line do |line|
|
133
|
+
host = line.strip + '.' + root_domain
|
134
|
+
|
135
|
+
begin
|
136
|
+
a = resv.getresources(host, Resolv::DNS::Resource::IN::A)
|
137
|
+
|
138
|
+
unless a.empty?
|
139
|
+
a.each do |ip|
|
140
|
+
if IPAddr.new(ip.address.to_s, Socket::AF_INET).private?
|
141
|
+
Yawast::Utilities.puts_info "\t\tA: #{host}: #{ip.address}"
|
142
|
+
else
|
143
|
+
Yawast::Utilities.puts_info "\t\tA: #{host}: #{ip.address} (#{get_network_info(ip.address)})"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
rescue
|
148
|
+
#if this fails, don't really care
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
puts
|
156
|
+
rescue => e
|
157
|
+
Yawast::Utilities.puts_error "Error getting basic information: #{e.message}"
|
158
|
+
raise
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.get_network_info(ip)
|
163
|
+
#check to see if we have this one cached
|
164
|
+
@netinfo = Hash.new if @netinfo == nil
|
165
|
+
return @netinfo[ip] if @netinfo[ip] != nil
|
166
|
+
|
167
|
+
begin
|
168
|
+
network_info = JSON.parse(Net::HTTP.get(URI("https://api.iptoasn.com/v1/as/ip/#{ip}")))
|
169
|
+
|
170
|
+
ret = "#{network_info['as_country_code']} - #{network_info['as_description']}"
|
171
|
+
@netinfo[ip] = ret
|
172
|
+
|
173
|
+
return ret
|
174
|
+
rescue => e
|
175
|
+
return "Error: getting network information failed (#{e.message})"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.get_network_location_info(ip)
|
180
|
+
begin
|
181
|
+
info = JSON.parse(Net::HTTP.get(URI("https://freegeoip.net/json/#{ip.address}")))
|
182
|
+
location = [info['city'], info['region_name'], info['country_code']].reject { |c| c.empty? }.join(', ')
|
183
|
+
|
184
|
+
if location != nil && !location.empty?
|
185
|
+
Yawast::Utilities.puts_info "\t\t\t#{location}"
|
186
|
+
end
|
187
|
+
rescue => e
|
188
|
+
Yawast::Utilities.puts_error "Error getting location information: #{e.message}"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Yawast
|
2
|
+
module Scanner
|
3
|
+
module Plugins
|
4
|
+
module SSL
|
5
|
+
class Sweet32
|
6
|
+
def self.get_tdes_session_msg_count(uri)
|
7
|
+
# this method will send a number of HEAD requests to see
|
8
|
+
# if the connection is eventually killed.
|
9
|
+
puts 'TLS Session Request Limit: Checking number of requests accepted using 3DES suites...'
|
10
|
+
|
11
|
+
count = 0
|
12
|
+
begin
|
13
|
+
req = Yawast::Shared::Http.get_http(uri)
|
14
|
+
req.use_ssl = uri.scheme == 'https'
|
15
|
+
req.keep_alive_timeout = 600
|
16
|
+
headers = Yawast::Shared::Http.get_headers
|
17
|
+
|
18
|
+
#force 3DES - this is to ensure that 3DES specific limits are caught
|
19
|
+
req.ciphers = ['3DES']
|
20
|
+
|
21
|
+
#attempt to find a version that supports 3DES
|
22
|
+
versions = OpenSSL::SSL::SSLContext::METHODS.find_all { |v| !v.to_s.include?('_client') && !v.to_s.include?('_server')}
|
23
|
+
versions.each do |version|
|
24
|
+
if version.to_s != 'SSLv23'
|
25
|
+
req.ssl_version = version
|
26
|
+
|
27
|
+
begin
|
28
|
+
req.start do |http|
|
29
|
+
head = http.head(uri.path, headers)
|
30
|
+
|
31
|
+
#check to see if this is on Cloudflare - they break Keep-Alive limits, creating a false positive
|
32
|
+
head.each do |k, v|
|
33
|
+
if k.downcase == 'server'
|
34
|
+
if v == 'cloudflare-nginx'
|
35
|
+
puts 'Cloudflare server found: SWEET32 mitigated: https://support.cloudflare.com/hc/en-us/articles/231510928'
|
36
|
+
return
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
print "Using #{version}"
|
43
|
+
break
|
44
|
+
rescue
|
45
|
+
#we don't care
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
req.start do |http|
|
51
|
+
10000.times do |i|
|
52
|
+
http.head(uri.path, headers)
|
53
|
+
|
54
|
+
# hack to detect transparent disconnects
|
55
|
+
if http.instance_variable_get(:@ssl_context).session_cache_stats[:cache_hits] != 0
|
56
|
+
raise 'TLS Reconnected'
|
57
|
+
end
|
58
|
+
|
59
|
+
count += 1
|
60
|
+
|
61
|
+
if i % 20 == 0
|
62
|
+
print '.'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
rescue => e
|
67
|
+
puts
|
68
|
+
|
69
|
+
if e.message.include? 'alert handshake failure'
|
70
|
+
Yawast::Utilities.puts_info 'TLS Session Request Limit: Server does not support 3DES cipher suites'
|
71
|
+
else
|
72
|
+
Yawast::Utilities.puts_info "TLS Session Request Limit: Connection terminated after #{count} requests (#{e.message})"
|
73
|
+
end
|
74
|
+
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
puts
|
79
|
+
Yawast::Utilities.puts_vuln 'TLS Session Request Limit: Connection not terminated after 10,000 requests; possibly vulnerable to SWEET32'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/scanner/ssl.rb
CHANGED
@@ -34,7 +34,7 @@ module Yawast
|
|
34
34
|
|
35
35
|
ssl.sysclose
|
36
36
|
|
37
|
-
get_tdes_session_msg_count(uri) if tdes_session_count
|
37
|
+
Yawast::Scanner::Plugins::SSL::Sweet32.get_tdes_session_msg_count(uri) if tdes_session_count
|
38
38
|
rescue => e
|
39
39
|
Yawast::Utilities.puts_error "SSL: Error Reading X509 Details: #{e.message}"
|
40
40
|
end
|
@@ -148,7 +148,7 @@ module Yawast
|
|
148
148
|
|
149
149
|
if ciphers != nil
|
150
150
|
check_version_suites uri, ip, ciphers, version
|
151
|
-
elsif get_ciphers_failed
|
151
|
+
elsif !get_ciphers_failed
|
152
152
|
Yawast::Utilities.puts_info "\t#{version}: No cipher suites available."
|
153
153
|
end
|
154
154
|
end
|
@@ -160,6 +160,19 @@ module Yawast
|
|
160
160
|
def self.check_version_suites(uri, ip, ciphers, version)
|
161
161
|
puts "\tChecking for #{version} suites (#{ciphers.count} possible suites)"
|
162
162
|
|
163
|
+
#first, let's see if we can connect using this version - so we don't do pointless checks
|
164
|
+
req = Yawast::Shared::Http.get_http(uri)
|
165
|
+
req.use_ssl = uri.scheme == 'https'
|
166
|
+
req.ssl_version = version
|
167
|
+
begin
|
168
|
+
req.start do |http|
|
169
|
+
http.head(uri.path, Yawast::Shared::Http.get_headers)
|
170
|
+
end
|
171
|
+
rescue
|
172
|
+
Yawast::Utilities.puts_info "\t\tVersion: #{version}\tNo Supported Cipher Suites"
|
173
|
+
return
|
174
|
+
end
|
175
|
+
|
163
176
|
ciphers.each do |cipher|
|
164
177
|
#try to connect and see what happens
|
165
178
|
begin
|
@@ -183,7 +196,9 @@ module Yawast
|
|
183
196
|
Yawast::Utilities.puts_error "\t\tVersion: #{ssl.ssl_version.ljust(7)}\tBits: #{cipher[2]}\tCipher: #{cipher[0]}\t(Supported But Failed)"
|
184
197
|
end
|
185
198
|
rescue => e
|
186
|
-
|
199
|
+
unless e.message.include?('Connection reset by peer')
|
200
|
+
Yawast::Utilities.puts_error "\t\tVersion: #{''.ljust(7)}\tBits: #{cipher[2]}\tCipher: #{cipher[0]}\t(#{e.message})"
|
201
|
+
end
|
187
202
|
ensure
|
188
203
|
ssl.sysclose unless ssl == nil
|
189
204
|
end
|
@@ -233,53 +248,6 @@ module Yawast
|
|
233
248
|
end
|
234
249
|
end
|
235
250
|
|
236
|
-
def self.get_tdes_session_msg_count(uri)
|
237
|
-
# this method will send a number of HEAD requests to see
|
238
|
-
# if the connection is eventually killed.
|
239
|
-
puts 'TLS Session Request Limit: Checking number of requests accepted using 3DES suites...'
|
240
|
-
|
241
|
-
count = 0
|
242
|
-
begin
|
243
|
-
req = Yawast::Shared::Http.get_http(uri)
|
244
|
-
req.use_ssl = uri.scheme == 'https'
|
245
|
-
req.keep_alive_timeout = 600
|
246
|
-
headers = Yawast::Shared::Http.get_headers
|
247
|
-
|
248
|
-
#force 3DES - this is to ensure that 3DES specific limits are caught
|
249
|
-
req.ciphers = ['3DES']
|
250
|
-
|
251
|
-
req.start do |http|
|
252
|
-
10000.times do |i|
|
253
|
-
http.head(uri.path, headers)
|
254
|
-
|
255
|
-
# hack to detect transparent disconnects
|
256
|
-
if http.instance_variable_get(:@ssl_context).session_cache_stats[:cache_hits] != 0
|
257
|
-
raise 'TLS Reconnected'
|
258
|
-
end
|
259
|
-
|
260
|
-
count += 1
|
261
|
-
|
262
|
-
if i % 20 == 0
|
263
|
-
print '.'
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
rescue => e
|
268
|
-
puts
|
269
|
-
|
270
|
-
if e.message.include? 'alert handshake failure'
|
271
|
-
Yawast::Utilities.puts_info 'TLS Session Request Limit: Server does not support 3DES cipher suites'
|
272
|
-
else
|
273
|
-
Yawast::Utilities.puts_info "TLS Session Request Limit: Connection terminated after #{count} requests (#{e.message})"
|
274
|
-
end
|
275
|
-
|
276
|
-
return
|
277
|
-
end
|
278
|
-
|
279
|
-
puts
|
280
|
-
Yawast::Utilities.puts_vuln 'TLS Session Request Limit: Connection not terminated after 10,000 requests; possibly vulnerable to SWEET32'
|
281
|
-
end
|
282
|
-
|
283
251
|
#private methods
|
284
252
|
class << self
|
285
253
|
private
|
data/lib/scanner/ssl_labs.rb
CHANGED
@@ -54,7 +54,7 @@ module Yawast
|
|
54
54
|
Yawast::Utilities.puts_error "Error getting information for IP: #{ep.ip_address}: #{e.message}"
|
55
55
|
end
|
56
56
|
|
57
|
-
Yawast::Scanner::
|
57
|
+
Yawast::Scanner::Plugins::SSL::Sweet32.get_tdes_session_msg_count(uri) if tdes_session_count
|
58
58
|
|
59
59
|
puts
|
60
60
|
end
|
data/lib/version.rb
CHANGED
data/yawast.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_runtime_dependency 'colorize', '~> 0.8'
|
21
21
|
s.add_runtime_dependency 'ipaddr_extensions', '~> 1.0'
|
22
22
|
s.add_runtime_dependency 'ipaddress', '~> 0.8'
|
23
|
+
s.add_runtime_dependency 'public_suffix', '~> 2.0'
|
23
24
|
|
24
25
|
s.bindir = 'bin'
|
25
26
|
s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yawast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.0.
|
4
|
+
version: 0.5.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Caudill
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ssllabs
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.8'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: public_suffix
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
111
125
|
description: YAWAST is an application meant to simplify initial analysis and information
|
112
126
|
gathering for penetration testers and security auditors.
|
113
127
|
email: adam@adamcaudill.com
|
@@ -135,6 +149,8 @@ files:
|
|
135
149
|
- lib/commands/utils.rb
|
136
150
|
- lib/resources/common_dir.txt
|
137
151
|
- lib/resources/common_file.txt
|
152
|
+
- lib/resources/srv_list.txt
|
153
|
+
- lib/resources/subdomain_list.txt
|
138
154
|
- lib/scanner/apache.rb
|
139
155
|
- lib/scanner/cert.rb
|
140
156
|
- lib/scanner/cms.rb
|
@@ -143,8 +159,10 @@ files:
|
|
143
159
|
- lib/scanner/iis.rb
|
144
160
|
- lib/scanner/nginx.rb
|
145
161
|
- lib/scanner/php.rb
|
162
|
+
- lib/scanner/plugins/dns/generic.rb
|
146
163
|
- lib/scanner/plugins/http/directory_search.rb
|
147
164
|
- lib/scanner/plugins/http/file_presence.rb
|
165
|
+
- lib/scanner/plugins/ssl/sweet32.rb
|
148
166
|
- lib/scanner/ssl.rb
|
149
167
|
- lib/scanner/ssl_labs.rb
|
150
168
|
- lib/shared/http.rb
|