sslscan_wrapper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/sslscan_wrapper.svg)](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: []
|