Class: Rex::SSLScan::Result

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResult

Returns a new instance of Result.



14
15
16
17
18
# File 'lib/rex/sslscan/result.rb', line 14

def initialize()
  @cert = nil
  @ciphers = Set.new
  @supported_versions = [:SSLv2, :SSLv3, :TLSv1]
end

Instance Attribute Details

#ciphersObject (readonly)

Returns the value of attribute ciphers.



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

def ciphers
  @ciphers
end

#openssl_sslv2Object

Returns the value of attribute openssl_sslv2.



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

def openssl_sslv2
  @openssl_sslv2
end

#supported_versionsObject (readonly)

Returns the value of attribute supported_versions.



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

def supported_versions
  @supported_versions
end

Instance Method Details

#accepted(version = :all) ⇒ Array

Returns all accepted ciphers matching the supplied version

Parameters:

  • version (Symbol, Array) (defaults to: :all)

    The SSL Version to filter on

Returns:

  • (Array)

    An array of accepted cipher details matching the supplied versions

Raises:



55
56
57
# File 'lib/rex/sslscan/result.rb', line 55

def accepted(version = :all)
  enum_ciphers(:accepted, version)
end

#add_cipher(version, cipher, key_length, status) ⇒ Object

Adds the details of a cipher test to the Result object.

Parameters:

  • version (Symbol)

    the SSL Version

  • cipher (String)

    the SSL cipher

  • key_length (Fixnum)

    the length of encryption key

  • status (Symbol)

    :accepted or :rejected



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rex/sslscan/result.rb', line 112

def add_cipher(version, cipher, key_length, status)
  unless @supported_versions.include? version
    raise ArgumentError, "Must be a supported SSL Version"
  end
  unless OpenSSL::SSL::SSLContext.new(version).ciphers.flatten.include? cipher
    raise ArgumentError, "Must be a valid SSL Cipher for #{version}!"
  end
  unless key_length.kind_of? Fixnum
    raise ArgumentError, "Must supply a valid key length"
  end
  unless [:accepted, :rejected].include? status
    raise ArgumentError, "Status must be either :accepted or :rejected"
  end

  strong_cipher_ctx = OpenSSL::SSL::SSLContext.new(version)
  # OpenSSL Directive For Strong Ciphers
  # See: http://www.rapid7.com/vulndb/lookup/ssl-weak-ciphers
  strong_cipher_ctx.ciphers = "ALL:!aNULL:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"

  if strong_cipher_ctx.ciphers.flatten.include? cipher
    weak = false
  else
    weak = true
  end

  cipher_details = {:version => version, :cipher => cipher, :key_length => key_length, :weak => weak, :status => status}
  @ciphers << cipher_details
end

#certObject



20
21
22
# File 'lib/rex/sslscan/result.rb', line 20

def cert
  @cert
end

#cert=(input) ⇒ Object



24
25
26
27
28
29
# File 'lib/rex/sslscan/result.rb', line 24

def cert=(input)
  unless input.kind_of? OpenSSL::X509::Certificate or input.nil?
    raise ArgumentError, "Must be an X509 Cert!"
  end
  @cert = input
end

#each_accepted(version = :all) ⇒ Object



67
68
69
70
71
# File 'lib/rex/sslscan/result.rb', line 67

def each_accepted(version = :all)
  accepted(version).each do |cipher_result|
    yield cipher_result
  end
end

#each_rejected(version = :all) ⇒ Object



73
74
75
76
77
# File 'lib/rex/sslscan/result.rb', line 73

def each_rejected(version = :all)
  rejected(version).each do |cipher_result|
    yield cipher_result
  end
end

#rejected(version = :all) ⇒ Array

Returns all rejected ciphers matching the supplied version

Parameters:

  • version (Symbol, Array) (defaults to: :all)

    The SSL Version to filter on

Returns:

  • (Array)

    An array of rejected cipher details matching the supplied versions

Raises:



63
64
65
# File 'lib/rex/sslscan/result.rb', line 63

def rejected(version = :all)
  enum_ciphers(:rejected, version)
end

#sslv2Object



31
32
33
# File 'lib/rex/sslscan/result.rb', line 31

def sslv2
  @ciphers.reject{|cipher| cipher[:version] != :SSLv2 }
end

#sslv3Object



35
36
37
# File 'lib/rex/sslscan/result.rb', line 35

def sslv3
  @ciphers.reject{|cipher| cipher[:version] != :SSLv3 }
end

#standards_compliant?Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
# File 'lib/rex/sslscan/result.rb', line 99

def standards_compliant?
  if supports_ssl?
    return false if supports_sslv2?
    return false if supports_weak_ciphers?
  end
  true
end

#strong_ciphersObject



47
48
49
# File 'lib/rex/sslscan/result.rb', line 47

def strong_ciphers
  accepted.reject{|cipher| cipher[:weak] }
end

#supports_ssl?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/rex/sslscan/result.rb', line 91

def supports_ssl?
  supports_sslv2? or supports_sslv3? or supports_tlsv1?
end

#supports_sslv2?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/rex/sslscan/result.rb', line 79

def supports_sslv2?
  !(accepted(:SSLv2).empty?)
end

#supports_sslv3?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/rex/sslscan/result.rb', line 83

def supports_sslv3?
  !(accepted(:SSLv3).empty?)
end

#supports_tlsv1?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/rex/sslscan/result.rb', line 87

def supports_tlsv1?
  !(accepted(:TLSv1).empty?)
end

#supports_weak_ciphers?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/rex/sslscan/result.rb', line 95

def supports_weak_ciphers?
  !(weak_ciphers.empty?)
end

#tlsv1Object



39
40
41
# File 'lib/rex/sslscan/result.rb', line 39

def tlsv1
  @ciphers.reject{|cipher| cipher[:version] != :TLSv1 }
end

#to_sObject



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/rex/sslscan/result.rb', line 141

def to_s
  unless supports_ssl?
    return "Server does not appear to support SSL on this port!"
  end
  table = Rex::Ui::Text::Table.new(
    'Header'      => 'SSL Ciphers',
    'Indent'       => 1,
    'Columns'   => ['Status', 'Weak', 'SSL Version', 'Key Length', 'Cipher'],
    'SortIndex'  => -1
  )
  ciphers.each do |cipher|
    if cipher[:weak]
      weak = '*'
    else
      weak = ' '
    end
    table << [cipher[:status].to_s.capitalize, weak , cipher[:version], cipher[:key_length], cipher[:cipher]]
  end

  # Sort by SSL Version, then Key Length, and then Status
  table.rows.sort_by!{|row| [row[0],row[2],row[3]]}
  text = "#{table.to_s}"
  if @cert
    text << " \n\n #{@cert.to_text}"
  end
  if openssl_sslv2 == false
    text << "\n\n *** WARNING: Your OS hates freedom! Your OpenSSL libs are compiled without SSLv2 support!"
  end
  text
end

#weak_ciphersObject



43
44
45
# File 'lib/rex/sslscan/result.rb', line 43

def weak_ciphers
  accepted.reject{|cipher| cipher[:weak] == false }
end