class Rex::SSLScan::Result

Attributes

ciphers[R]
openssl_sslv2[RW]
supported_versions[R]

Public Class Methods

new() click to toggle source
# File lib/rex/sslscan/result.rb, line 13
def initialize()
  @cert = nil
  @ciphers = Set.new
  @supported_versions = [:SSLv2, :SSLv3, :TLSv1]
end

Public Instance Methods

accepted(version = :all) click to toggle source

Returns all accepted ciphers matching the supplied version @param version [Symbol, Array] The SSL Version to filter on @raise [ArgumentError] if the version supplied is invalid @return [Array] An array of accepted cipher details matching the supplied versions

# File lib/rex/sslscan/result.rb, line 54
def accepted(version = :all)
  enum_ciphers(:accepted, version)
end
add_cipher(version, cipher, key_length, status) click to toggle source

Adds the details of a cipher test to the Result object. @param version [Symbol] the SSL Version @param cipher [String] the SSL cipher @param key_length [Fixnum] the length of encryption key @param status [Symbol] :accepted or :rejected

# 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
cert() click to toggle source
# File lib/rex/sslscan/result.rb, line 19
def cert
  @cert
end
cert=(input) click to toggle source
# 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) { |cipher_result| ... } click to toggle source
# 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) { |cipher_result| ... } click to toggle source
# 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) click to toggle source

Returns all rejected ciphers matching the supplied version @param version [Symbol, Array] The SSL Version to filter on @raise [ArgumentError] if the version supplied is invalid @return [Array] An array of rejected cipher details matching the supplied versions

# File lib/rex/sslscan/result.rb, line 62
def rejected(version = :all)
  enum_ciphers(:rejected, version)
end
sslv2() click to toggle source
# File lib/rex/sslscan/result.rb, line 30
def sslv2
  @ciphers.reject{|cipher| cipher[:version] != :SSLv2 }
end
sslv3() click to toggle source
# File lib/rex/sslscan/result.rb, line 34
def sslv3
  @ciphers.reject{|cipher| cipher[:version] != :SSLv3 }
end
standards_compliant?() click to toggle source
# 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_ciphers() click to toggle source
# File lib/rex/sslscan/result.rb, line 46
def strong_ciphers
  accepted.reject{|cipher| cipher[:weak] }
end
supports_ssl?() click to toggle source
# File lib/rex/sslscan/result.rb, line 90
def supports_ssl?
  supports_sslv2? or supports_sslv3? or supports_tlsv1?
end
supports_sslv2?() click to toggle source
# File lib/rex/sslscan/result.rb, line 78
def supports_sslv2?
  !(accepted(:SSLv2).empty?)
end
supports_sslv3?() click to toggle source
# File lib/rex/sslscan/result.rb, line 82
def supports_sslv3?
  !(accepted(:SSLv3).empty?)
end
supports_tlsv1?() click to toggle source
# File lib/rex/sslscan/result.rb, line 86
def supports_tlsv1?
  !(accepted(:TLSv1).empty?)
end
supports_weak_ciphers?() click to toggle source
# File lib/rex/sslscan/result.rb, line 94
def supports_weak_ciphers?
  !(weak_ciphers.empty?)
end
tlsv1() click to toggle source
# File lib/rex/sslscan/result.rb, line 38
def tlsv1
  @ciphers.reject{|cipher| cipher[:version] != :TLSv1 }
end
to_s() click to toggle source
# 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_ciphers() click to toggle source
# File lib/rex/sslscan/result.rb, line 42
def weak_ciphers
  accepted.reject{|cipher| cipher[:weak] == false }
end

Protected Instance Methods

enum_ciphers(state, version = :all) click to toggle source

@param state [Symbol] Either :accepted or :rejected @param version [Symbol, Array] The SSL Version to filter on (:SSLv2, :SSLv3, :TLSv1, :all) @return [Set] The Set of cipher results matching the filter criteria

# File lib/rex/sslscan/result.rb, line 176
def enum_ciphers(state, version = :all)
  case version
  when Symbol
    case version
    when :all
      return @ciphers.select{|cipher| cipher[:status] == state}
    when :SSLv2, :SSLv3, :TLSv1
      return @ciphers.select{|cipher| cipher[:status] == state and cipher[:version] == version}
    else
      raise ArgumentError, "Invalid SSL Version Supplied: #{version}"
    end
  when Array
    version = version.reject{|v| !(@supported_versions.include? v)}
    if version.empty?
      return @ciphers.select{|cipher| cipher[:status] == state}
    else
      return @ciphers.select{|cipher| cipher[:status] == state and version.include? cipher[:version]}
    end
  else
    raise ArgumentError, "Was expecting Symbol or Array and got #{version.class}"
  end
end