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.



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

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

Instance Attribute Details

#ciphersObject (readonly)

Returns the value of attribute ciphers.



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

def ciphers
  @ciphers
end

#openssl_sslv2Object

Returns the value of attribute openssl_sslv2.



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

def openssl_sslv2
  @openssl_sslv2
end

#supported_versionsObject (readonly)

Returns the value of attribute supported_versions.



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

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:



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

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



111
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
# File 'lib/rex/sslscan/result.rb', line 111

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



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

def cert
  @cert
end

#cert=(input) ⇒ Object



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

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



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

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

#each_rejected(version = :all) ⇒ Object



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

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:



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

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

#sslv2Object



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

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

#sslv3Object



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

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

#standards_compliant?Boolean

Returns:

  • (Boolean)


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

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

#strong_ciphersObject



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

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

#supports_ssl?Boolean

Returns:

  • (Boolean)


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

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

#supports_sslv2?Boolean

Returns:

  • (Boolean)


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

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

#supports_sslv3?Boolean

Returns:

  • (Boolean)


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

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

#supports_tlsv1?Boolean

Returns:

  • (Boolean)


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

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

#supports_weak_ciphers?Boolean

Returns:

  • (Boolean)


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

def supports_weak_ciphers?
  !(weak_ciphers.empty?)
end

#tlsv1Object



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

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

#to_sObject



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
165
166
167
168
169
# File 'lib/rex/sslscan/result.rb', line 140

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



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

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