Class: SSLScan::Scanner
- Inherits:
-
Object
- Object
- SSLScan::Scanner
- Defined in:
- lib/ssl_scan/scanner.rb
Instance Attribute Summary collapse
-
#context ⇒ Object
Returns the value of attribute context.
-
#host ⇒ Object
Returns the value of attribute host.
-
#peer_supported_versions ⇒ Object
readonly
Returns the value of attribute peer_supported_versions.
-
#port ⇒ Object
Returns the value of attribute port.
-
#results ⇒ Object
readonly
Returns the value of attribute results.
-
#sslv2 ⇒ Object
readonly
Returns the value of attribute sslv2.
-
#supported_versions ⇒ Object
readonly
Returns the value of attribute supported_versions.
-
#timeout ⇒ Object
Returns the value of attribute timeout.
Instance Method Summary collapse
-
#get_cert(ssl_version, cipher) ⇒ OpenSSL::X509::Certificate, Nil
Retrieve the X509 Cert from the target service,.
- #get_first_valid_cert ⇒ Object
- #get_preferred_ciphers ⇒ Object
-
#initialize(host, port = 443, context = {}, timeout = 5) ⇒ Scanner
constructor
Initializes the scanner object.
-
#scan(&block) ⇒ Result
Initiate the Scan against the target.
- #scan_ssl_version(ssl_version, &block) ⇒ Object
-
#test_cipher(ssl_version, cipher) ⇒ Symbol
Tests the specified SSL Version and Cipher against the configured target.
- #test_ssl ⇒ Object
- #test_tls ⇒ Object
-
#valid? ⇒ Boolean
Checks whether the scanner option has a valid configuration.
Constructor Details
#initialize(host, port = 443, context = {}, timeout = 5) ⇒ Scanner
Initializes the scanner object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/ssl_scan/scanner.rb', line 20 def initialize(host,port = 443,context = {},timeout=5) @host = host @port = port @timeout = timeout @context = context if check_opensslv2 == true @supported_versions = [:SSLv2, :SSLv3, :TLSv1] @sslv2 = true else @supported_versions = [:SSLv3, :TLSv1] @sslv2 = false end @peer_supported_versions = [] raise StandardError, "The scanner configuration is invalid" unless valid? end |
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
5 6 7 |
# File 'lib/ssl_scan/scanner.rb', line 5 def context @context end |
#host ⇒ Object
Returns the value of attribute host.
6 7 8 |
# File 'lib/ssl_scan/scanner.rb', line 6 def host @host end |
#peer_supported_versions ⇒ Object (readonly)
Returns the value of attribute peer_supported_versions.
11 12 13 |
# File 'lib/ssl_scan/scanner.rb', line 11 def peer_supported_versions @peer_supported_versions end |
#port ⇒ Object
Returns the value of attribute port.
7 8 9 |
# File 'lib/ssl_scan/scanner.rb', line 7 def port @port end |
#results ⇒ Object (readonly)
Returns the value of attribute results.
12 13 14 |
# File 'lib/ssl_scan/scanner.rb', line 12 def results @results end |
#sslv2 ⇒ Object (readonly)
Returns the value of attribute sslv2.
13 14 15 |
# File 'lib/ssl_scan/scanner.rb', line 13 def sslv2 @sslv2 end |
#supported_versions ⇒ Object (readonly)
Returns the value of attribute supported_versions.
10 11 12 |
# File 'lib/ssl_scan/scanner.rb', line 10 def supported_versions @supported_versions end |
#timeout ⇒ Object
Returns the value of attribute timeout.
8 9 10 |
# File 'lib/ssl_scan/scanner.rb', line 8 def timeout @timeout end |
Instance Method Details
#get_cert(ssl_version, cipher) ⇒ OpenSSL::X509::Certificate, Nil
Retrieve the X509 Cert from the target service,
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/ssl_scan/scanner.rb', line 250 def get_cert(ssl_version, cipher) validate_params(ssl_version, cipher) begin scan_client = SSLScan::Socket::Tcp.create( 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => ssl_version, 'SSLCipher' => cipher, 'Timeout' => @timeout ) cert = scan_client.peer_cert if cert.kind_of? OpenSSL::X509::Certificate return cert else return nil end rescue ::Exception => e return nil ensure if scan_client scan_client.close end end end |
#get_first_valid_cert ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ssl_scan/scanner.rb', line 137 def get_first_valid_cert scan_result = SSLScan::Result.new scan_result.openssl_sslv2 = sslv2 @supported_versions.each do |ssl_version| begin scan_client = SSLScan::Socket::Tcp.create( 'Context' => @context, 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => ssl_version, 'Timeout' => @timeout ) cipher_name = scan_client.cipher[0] key_length = scan_client.cipher[3] status = test_cipher(ssl_version, cipher_name) scan_result.add_cipher(ssl_version, cipher_name, key_length, status) if status == :accepted and scan_result.cert.nil? scan_result.cert = get_cert(ssl_version, cipher_name) break end rescue => ex # noop end end @results = scan_result scan_result end |
#get_preferred_ciphers ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/ssl_scan/scanner.rb', line 109 def get_preferred_ciphers ssl_versions = {}.tap do |v| @supported_versions.each { |sv| v[sv] = [] } end ssl_versions.keys.each do |ssl_version| begin scan_client = SSLScan::Socket::Tcp.create( 'Context' => @context, 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => ssl_version, 'Timeout' => @timeout ) ssl_versions[ssl_version] = scan_client.cipher if scan_client scan_client.close end rescue => ex ssl_versions.delete(ssl_version) end end ssl_versions end |
#scan(&block) ⇒ Result
Initiate the Scan against the target. Will test each cipher one at a time.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ssl_scan/scanner.rb', line 52 def scan(&block) scan_result = SSLScan::Result.new scan_result.openssl_sslv2 = sslv2 # If we can't get any SSL connection, then don't bother testing # individual ciphers. @supported_versions.each do |ssl_version| sslctx = OpenSSL::SSL::SSLContext.new(ssl_version) sslctx.ciphers.each do |cipher_name, ssl_ver, key_length, alg_length| status = test_cipher(ssl_version, cipher_name) scan_result.add_cipher(ssl_version, cipher_name, key_length, status) if status == :accepted and scan_result.cert.nil? scan_result.cert = get_cert(ssl_version, cipher_name) end if block_given? yield(ssl_version, cipher_name, alg_length, status, scan_result.cert) end end end @peer_supported_versions = [].tap do |psv| psv << :SSLv2 if scan_result.supports_sslv2? psv << :SSLv3 if scan_result.supports_sslv3? psv << :TLSv1 if scan_result.supports_tlsv1? end @results = scan_result scan_result end |
#scan_ssl_version(ssl_version, &block) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ssl_scan/scanner.rb', line 82 def scan_ssl_version(ssl_version, &block) scan_result = SSLScan::Result.new scan_result.openssl_sslv2 = sslv2 # If we can't get any SSL connection, then don't bother testing # individual ciphers. if ([:rejected, :failed].include?(test_ssl) and [:rejected, :failed].include?(test_tls)) or !@supported_versions.include?(ssl_version) return scan_result end sslctx = OpenSSL::SSL::SSLContext.new(ssl_version) sslctx.ciphers.each do |cipher_name, ssl_ver, key_length, alg_length| status = test_cipher(ssl_version, cipher_name) scan_result.add_cipher(ssl_version, cipher_name, key_length, status) if status == :accepted and scan_result.cert.nil? scan_result.cert = get_cert(ssl_version, cipher_name) end if block_given? yield(ssl_version, cipher_name, alg_length, status, scan_result.cert) end end @results = scan_result scan_result end |
#test_cipher(ssl_version, cipher) ⇒ Symbol
Tests the specified SSL Version and Cipher against the configured target
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/ssl_scan/scanner.rb', line 218 def test_cipher(ssl_version, cipher) validate_params(ssl_version,cipher) begin scan_client = SSLScan::Socket::Tcp.create( 'Context' => @context, 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => ssl_version, 'SSLCipher' => cipher, 'Timeout' => @timeout ) rescue ::Exception => e if e.kind_of?(Errno::ECONNRESET) return :failed else return :rejected end ensure if scan_client scan_client.close end end return :accepted end |
#test_ssl ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/ssl_scan/scanner.rb', line 166 def test_ssl begin scan_client = SSLScan::Socket::Tcp.create( 'Context' => @context, 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => :SSLv23, 'Timeout' => @timeout ) rescue ::Exception => e if e.kind_of?(Errno::ECONNRESET) return :failed else return :rejected end ensure if scan_client scan_client.close end end return :accepted end |
#test_tls ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/ssl_scan/scanner.rb', line 190 def test_tls begin scan_client = SSLScan::Socket::Tcp.create( 'Context' => @context, 'PeerHost' => @host, 'PeerPort' => @port, 'SSL' => true, 'SSLVersion' => :TLSv1, 'Timeout' => @timeout ) rescue ::Exception => e if e.kind_of?(Errno::ECONNRESET) return :failed else return :rejected end ensure if scan_client scan_client.close end end return :accepted end |
#valid? ⇒ Boolean
Checks whether the scanner option has a valid configuration
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/ssl_scan/scanner.rb', line 38 def valid? begin @host = SSLScan::Socket.getaddress(@host, true) rescue return false end return false unless @port.kind_of? Fixnum return false unless @port >= 0 and @port <= 65535 return false unless @timeout.kind_of? Fixnum return true end |