Class: Rex::SSLScan::Scanner

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/sslscan/scanner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port = 443, context = {}, timeout = 5) ⇒ Scanner

Initializes the scanner object

Parameters:

  • host (String)

    IP address or hostname to scan

  • port (Fixnum) (defaults to: 443)

    Port number to scan, default: 443

  • timeout (Fixnum) (defaults to: 5)

    Timeout for connections, in seconds. default: 5

Raises:

  • (StandardError)

    Raised when the configuration is invalid



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rex/sslscan/scanner.rb', line 22

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
  raise StandardError, "The scanner configuration is invalid" unless valid?
end

Instance Attribute Details

#contextObject

Returns the value of attribute context.



9
10
11
# File 'lib/rex/sslscan/scanner.rb', line 9

def context
  @context
end

#hostObject

Returns the value of attribute host.



10
11
12
# File 'lib/rex/sslscan/scanner.rb', line 10

def host
  @host
end

#portObject

Returns the value of attribute port.



11
12
13
# File 'lib/rex/sslscan/scanner.rb', line 11

def port
  @port
end

#sslv2Object (readonly)

Returns the value of attribute sslv2.



15
16
17
# File 'lib/rex/sslscan/scanner.rb', line 15

def sslv2
  @sslv2
end

#supported_versionsObject (readonly)

Returns the value of attribute supported_versions.



14
15
16
# File 'lib/rex/sslscan/scanner.rb', line 14

def supported_versions
  @supported_versions
end

#timeoutObject

Returns the value of attribute timeout.



12
13
14
# File 'lib/rex/sslscan/scanner.rb', line 12

def timeout
  @timeout
end

Instance Method Details

#get_cert(ssl_version, cipher) ⇒ OpenSSL::X509::Certificate, Nil

Retrieve the X509 Cert from the target service,

Parameters:

  • ssl_version (Symbol)

    The SSL version to use (:SSLv2, :SSLv3, :TLSv1)

  • cipher (String)

    The SSL Cipher to use

Returns:

  • (OpenSSL::X509::Certificate)

    if the certificate was retrieved

  • (Nil)

    if the cert couldn't be retrieved



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rex/sslscan/scanner.rb', line 147

def get_cert(ssl_version, cipher)
  validate_params(ssl_version,cipher)
  begin
    scan_client = Rex::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

#scanResult

Initiate the Scan against the target. Will test each cipher one at a time.

Returns:

  • (Result)

    object containing the details of the scan



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rex/sslscan/scanner.rb', line 53

def scan
  scan_result = Rex::SSLScan::Result.new
  scan_result.openssl_sslv2 = sslv2
  # If we can't get any SSL connection, then don't bother testing
  # individual ciphers.
  if test_ssl == :rejected and test_tls == :rejected
    return scan_result
  end

  @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
    end
  end
  scan_result
end

#test_cipher(ssl_version, cipher) ⇒ Symbol

Tests the specified SSL Version and Cipher against the configured target

Parameters:

  • ssl_version (Symbol)

    The SSL version to use (:SSLv2, :SSLv3, :TLSv1)

  • cipher (String)

    The SSL Cipher to use

Returns:

  • (Symbol)

    Either :accepted or :rejected



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rex/sslscan/scanner.rb', line 119

def test_cipher(ssl_version, cipher)
  validate_params(ssl_version,cipher)
  begin
    scan_client = Rex::Socket::Tcp.create(
      'Context'    => @context,
      'PeerHost'   => @host,
      'PeerPort'   => @port,
      'SSL'        => true,
      'SSLVersion' => ssl_version,
      'SSLCipher'  => cipher,
      'Timeout'    => @timeout
    )
  rescue ::Exception => e
    return :rejected
  ensure
    if scan_client
      scan_client.close
    end
  end

  return :accepted
end

#test_sslObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rex/sslscan/scanner.rb', line 75

def test_ssl
  begin
    scan_client = Rex::Socket::Tcp.create(
      'Context'    => @context,
      'PeerHost'   => @host,
      'PeerPort'   => @port,
      'SSL'        => true,
      'SSLVersion' => :SSLv23,
      'Timeout'    => @timeout
    )
  rescue ::Exception => e
    return :rejected
  ensure
    if scan_client
      scan_client.close
    end
  end
  return :accepted
end

#test_tlsObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rex/sslscan/scanner.rb', line 95

def test_tls
  begin
    scan_client = Rex::Socket::Tcp.create(
      'Context'    => @context,
      'PeerHost'   => @host,
      'PeerPort'   => @port,
      'SSL'        => true,
      'SSLVersion' => :TLSv1,
      'Timeout'    => @timeout
    )
  rescue ::Exception => e
    return :rejected
  ensure
    if scan_client
      scan_client.close
    end
  end
  return :accepted
end

#valid?Boolean

Checks whether the scanner option has a valid configuration

Returns:

  • (Boolean)

    True or False, the configuration is valid.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rex/sslscan/scanner.rb', line 39

def valid?
  begin
    @host = Rex::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