sslscan_wrapper 0.0.1
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 +7 -0
- data/Gemfile +4 -0
- data/README.md +34 -0
- data/Rakefile +14 -0
- data/lib/sslscan_wrapper.rb +1 -0
- data/lib/sslscan_wrapper/report.rb +114 -0
- data/lib/sslscan_wrapper/scanner.rb +95 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 17102ec6e6de9081e6b60fd9c8c87b9402a48fbdb9835504e186c72446acc751
|
4
|
+
data.tar.gz: fd6a13ba469b548cecc3334ef7912602040622591ecc85fe35042487a4e60390
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 110da3e2aa079522204b497810c4dd73604ca9a6cc94c87c5f5774b311a35669f89646cbc9fcbfd6b18ca54c258a1a601269a26f77a37c4faebf2e3cd397016d
|
7
|
+
data.tar.gz: 3561cca8da3ab70d813955657afb89070b27e86467634a58247ccd2feb48356ed03704018d9303c7a6bdf5bd0df4f6b10fa953d04749ec183a327c8c8e5e7468
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
[](https://badge.fury.io/rb/sslscan_wrapper)
|
2
|
+
|
3
|
+
# sslscan\_wrapper
|
4
|
+
|
5
|
+
sslscan\_wrapper is a wrapper around the sslscan tool to scan SSL/TLS protocol parameters.
|
6
|
+
|
7
|
+
* [rbsec/sslscan at GitHub](https://github.com/rbsec/sslscan)
|
8
|
+
|
9
|
+
Since it is only a wrapper around sslscan it does not depend on the openssl version
|
10
|
+
the ruby interpreter is linked with. The sslscan tool can be compiled statically with
|
11
|
+
a openssl version supporting old protocol versions and ciphers.
|
12
|
+
|
13
|
+
## API Documentation
|
14
|
+
|
15
|
+
Available at [rubydoc.info](http://www.rubydoc.info/gems/sslscan_wrapper).
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
```
|
20
|
+
require 'sslscan_wrapper'
|
21
|
+
|
22
|
+
scanner = SslscanWrapper::Scanner.new
|
23
|
+
report = scanner.scan('www.somesite.tld', 443)
|
24
|
+
|
25
|
+
report.ciphers
|
26
|
+
# => ["ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-RSA-AES128-GCM-SHA256", ...
|
27
|
+
report.host
|
28
|
+
# => "www.somesite.tld"
|
29
|
+
report.signature_algorithm
|
30
|
+
# => "sha256WithRSAEncryption"
|
31
|
+
report.heartbleed_vulnerable?
|
32
|
+
# => false
|
33
|
+
```
|
34
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
|
6
|
+
spec = eval(File.read('sslscan_wrapper.gemspec'))
|
7
|
+
Gem::PackageTask.new(spec) do |pkg|
|
8
|
+
end
|
9
|
+
|
10
|
+
Rake::RDocTask.new do |rd|
|
11
|
+
rd.rdoc_files.include("lib/**/*.rb","bin/**/*")
|
12
|
+
rd.title = 'Wrapper for sslscan SSL/TLS scanner'
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'sslscan_wrapper/scanner'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module SslscanWrapper
|
5
|
+
class Report
|
6
|
+
# The content body of the report
|
7
|
+
attr_reader :body
|
8
|
+
# The nokogiri document object
|
9
|
+
attr_reader :doc
|
10
|
+
# Initialize a new report object
|
11
|
+
#
|
12
|
+
# Examples
|
13
|
+
#
|
14
|
+
# content = File.read('report.xml')
|
15
|
+
# SslscanWrapper::Report.new(content)
|
16
|
+
#
|
17
|
+
# Returns a new SslscanWrapper::Report
|
18
|
+
def initialize(output)
|
19
|
+
@body = output
|
20
|
+
@doc = Nokogiri::XML(@body)
|
21
|
+
end
|
22
|
+
|
23
|
+
# The hostname of the scanned host
|
24
|
+
def host
|
25
|
+
@doc.xpath('//ssltest/@host').first.value
|
26
|
+
end
|
27
|
+
|
28
|
+
# The port of the scan report
|
29
|
+
def port
|
30
|
+
@doc.xpath('//ssltest/@port').first.value
|
31
|
+
end
|
32
|
+
|
33
|
+
# Is ssl compression supported on target?
|
34
|
+
def compression_supported?
|
35
|
+
@doc.xpath('//compression/@supported').first.value == '1'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Does the target support TLS renegotiation?
|
39
|
+
def renegotiation_supported?
|
40
|
+
@doc.xpath('//renegotiation/@supported').first.value == '1'
|
41
|
+
end
|
42
|
+
|
43
|
+
def renegotiation_secure?
|
44
|
+
@doc.xpath('//renegotiation/@secure').first.value == '1'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Signature algorithm used in the certificate
|
48
|
+
def signature_algorithm
|
49
|
+
@doc.xpath('//certificate/signature-algorithm').first.content
|
50
|
+
end
|
51
|
+
|
52
|
+
# Subject of the certificate
|
53
|
+
def subject
|
54
|
+
@doc.xpath('//certificate/subject').first.content
|
55
|
+
end
|
56
|
+
|
57
|
+
# Subject alternative names of the certificate
|
58
|
+
def altnames
|
59
|
+
@doc.xpath('//certificate/altnames').first.content
|
60
|
+
end
|
61
|
+
|
62
|
+
# Issuer of the certificate
|
63
|
+
def issuer
|
64
|
+
@doc.xpath('//certificate/issuer').first.content
|
65
|
+
end
|
66
|
+
|
67
|
+
# Is the certificate a self-signed certificate?
|
68
|
+
def self_signed?
|
69
|
+
@doc.xpath('//certificate/self-signed').first.content == 'true'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Is the certificate expired?
|
73
|
+
def expired?
|
74
|
+
@doc.xpath('//certificate/expired').first.content == 'true'
|
75
|
+
end
|
76
|
+
|
77
|
+
# Time the certificate starts to be valid
|
78
|
+
def not_before
|
79
|
+
time_str = @doc.xpath('//certificate/not-valid-before').first.content
|
80
|
+
Time.parse(time_str)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Time the certificate is no longer valid
|
84
|
+
def not_after
|
85
|
+
time_str = @doc.xpath('//certificate/not-valid-after').first.content
|
86
|
+
Time.parse(time_str)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns a list of supported ciphers
|
90
|
+
def ciphers
|
91
|
+
@doc.xpath('//cipher/@cipher').map(&:value)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Is the cipher supported?
|
95
|
+
def cipher_supported?(cipher)
|
96
|
+
@doc.xpath("//cipher[@cipher=\"#{cipher}\"]").count > 0
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns a list of preferred ciphers
|
100
|
+
def preferred_ciphers
|
101
|
+
@doc.xpath('//cipher[@status="preferred"]/@cipher').map(&:value)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a list of SSL/TLS protocol versions vulnerable to heartbleed
|
105
|
+
def heartbleed_vulnerable_sslversions
|
106
|
+
@doc.xpath('//heartbleed[@vulnerable="1"]/@sslversion').map(&:value)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Are there any heartblead vulnerable SSL/TLS protocol versions?
|
110
|
+
def heartbleed_vulnerable?
|
111
|
+
@doc.xpath('//heartbleed[@vulnerable="1"]').count > 0
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'sslscan_wrapper/report'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module SslscanWrapper
|
5
|
+
class Scanner
|
6
|
+
# sslscan executable
|
7
|
+
attr_accessor :command
|
8
|
+
|
9
|
+
# Hostname for SNI
|
10
|
+
attr_accessor :sni_name
|
11
|
+
# Only use IPv4
|
12
|
+
attr_accessor :ipv4
|
13
|
+
# Only use IPv6
|
14
|
+
attr_accessor :ipv6
|
15
|
+
# Only check SSLv2 ciphers
|
16
|
+
attr_accessor :ssl2
|
17
|
+
# Only check SSLv3 ciphers
|
18
|
+
attr_accessor :ssl3
|
19
|
+
# Only check TLSv1.0 ciphers
|
20
|
+
attr_accessor :tls10
|
21
|
+
# Only check TLSv1.1 ciphers
|
22
|
+
attr_accessor :tls11
|
23
|
+
# Only check TLSv1.2 ciphers
|
24
|
+
attr_accessor :tls12
|
25
|
+
# Only check TLS ciphers (all versions)
|
26
|
+
attr_accessor :tlsall
|
27
|
+
# Request OCSP response from server
|
28
|
+
attr_accessor :ocsp
|
29
|
+
# A file containing the private key or a PKCS12 file containing a private key/certificate pair
|
30
|
+
attr_accessor :pk
|
31
|
+
# The password for the private key or PKCS12 file certs=<file> A file containing PEM/ASN1 formatted client certificates
|
32
|
+
attr_accessor :pkpass
|
33
|
+
# Use a server-to-server XMPP handshake
|
34
|
+
attr_accessor :xmpp_server
|
35
|
+
# Test a HTTP connection
|
36
|
+
attr_accessor :http
|
37
|
+
# Send RDP preamble before starting scan
|
38
|
+
attr_accessor :rdp
|
39
|
+
# Enable SSL implementation bug work-arounds
|
40
|
+
attr_accessor :bugs
|
41
|
+
# Set socket timeout. Default is 3s
|
42
|
+
attr_accessor :timeout
|
43
|
+
# Pause between connection request. Default is disabled
|
44
|
+
attr_accessor :sleep
|
45
|
+
|
46
|
+
@@SSL_SCAN_FLAGS = [ :ipv4, :ipv6, :ssl2, :ssl3, :tls10, :tls11, :tls12, :tlsall, :ocsp, :xmpp_server, :http, :bugs ]
|
47
|
+
@@SSL_SCAN_OPTIONS = [ :sleep, :timeout, :sni_name, :pk, :pkpass ]
|
48
|
+
@@SSL_SCAN_ARGS = [ '--xml=-', '--no-colour' ]
|
49
|
+
|
50
|
+
# Initialize a new SslscanWrapper::Scanner object
|
51
|
+
#
|
52
|
+
# Examples
|
53
|
+
#
|
54
|
+
# scan = SslscanWrapper::Scanner.new do |s|
|
55
|
+
# s.ipv4 = true
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# Returns a SslscanWrapper::Scanner object
|
59
|
+
def initialize
|
60
|
+
@command = 'sslscan'
|
61
|
+
@port = 443
|
62
|
+
yield self if block_given?
|
63
|
+
end
|
64
|
+
|
65
|
+
# Scan a target
|
66
|
+
#
|
67
|
+
# Returns a SslscanWrapper::Report object
|
68
|
+
def scan(host, port)
|
69
|
+
execute(host, port)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def cmd(host, port)
|
75
|
+
cmd = [ @command ] + @@SSL_SCAN_ARGS
|
76
|
+
@@SSL_SCAN_FLAGS.each do |flag|
|
77
|
+
next if send(flag).nil?
|
78
|
+
cmd << "--#{flag.to_s.gsub('_', '-')}"
|
79
|
+
end
|
80
|
+
@@SSL_SCAN_OPTIONS.each do |option|
|
81
|
+
next if (value = send(option)).nil?
|
82
|
+
cmd << '--' + option.to_s.gsub('_', '-')
|
83
|
+
cmd << value
|
84
|
+
end
|
85
|
+
cmd << "#{host}:#{port}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def execute(host, port)
|
89
|
+
command = cmd(host, port)
|
90
|
+
report, err, status = Open3.capture3(*command)
|
91
|
+
raise "Error while executing sslscan: #{err}" unless status.success?
|
92
|
+
SslscanWrapper::Report.new(report)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sslscan_wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Markus Benning
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aruba
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nokogiri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '6'
|
69
|
+
description:
|
70
|
+
email: ich@markusbenning.de
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- Gemfile
|
76
|
+
- README.md
|
77
|
+
- Rakefile
|
78
|
+
- lib/sslscan_wrapper.rb
|
79
|
+
- lib/sslscan_wrapper/report.rb
|
80
|
+
- lib/sslscan_wrapper/scanner.rb
|
81
|
+
homepage: https://github.com/benningm/sslscan_wrapper
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.7.6
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: Wrapper for sslscan SSL/TLS protocol scanner
|
106
|
+
test_files: []
|