fix stupid datat structure
also supports a boolean value for whether the cipher is weak or notbug/bundler_fix
parent
5c9f946927
commit
dfc7ce9381
|
@ -4,16 +4,12 @@ require 'rex/socket'
|
|||
module Rex::SSLScan
|
||||
class Result
|
||||
|
||||
attr_reader :sslv2
|
||||
attr_reader :sslv3
|
||||
attr_reader :tlsv1
|
||||
attr_reader :ciphers
|
||||
attr_reader :supported_versions
|
||||
|
||||
def initialize()
|
||||
@cert = nil
|
||||
@sslv2 = {:accepted => [], :rejected => []}
|
||||
@sslv3 = {:accepted => [], :rejected => []}
|
||||
@tlsv1 = {:accepted => [], :rejected => []}
|
||||
@ciphers = []
|
||||
@supported_versions = [:SSLv2, :SSLv3, :TLSv1]
|
||||
end
|
||||
|
||||
|
@ -28,6 +24,10 @@ class Result
|
|||
@cert = input
|
||||
end
|
||||
|
||||
def sslv2
|
||||
@ciphers.reject{|cipher| cipher[:version] != :SSLv2 }
|
||||
end
|
||||
|
||||
def add_cipher(version, cipher, key_length, status)
|
||||
unless @supported_versions.include? version
|
||||
raise ArgumentError, "Must be a supported SSL Version"
|
||||
|
@ -42,74 +42,86 @@ class Result
|
|||
raise ArgumentError, "status Must be either :accepted or :rejected"
|
||||
end
|
||||
|
||||
cipher_details = {:cipher => cipher, :key_length => key_length}
|
||||
strong_cipher_ctx = OpenSSL::SSL::SSLContext.new(version)
|
||||
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
|
||||
@ciphers.uniq!
|
||||
end
|
||||
|
||||
def accepted(version = :all)
|
||||
if version.kind_of? Symbol
|
||||
case version
|
||||
when :SSLv2
|
||||
@sslv2[status] << cipher_details
|
||||
@sslv2[status].uniq!
|
||||
when :SSLv3
|
||||
@sslv3[status] << cipher_details
|
||||
@sslv3[status].uniq!
|
||||
when :TLSv1
|
||||
@tlsv1[status] << cipher_details
|
||||
@tlsv1[status].uniq!
|
||||
when :all
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :rejected}
|
||||
when :SSLv2, :SSLv3, :TLSv1
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :rejected or cipher[:version] != version}
|
||||
else
|
||||
raise ArgumentError, "Invalid SSL Version Supplied: #{version}"
|
||||
end
|
||||
elsif version.kind_of? Array
|
||||
version.reject!{|version| @supported_versions.include? version}
|
||||
if version.empty?
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :rejected}
|
||||
else
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :rejected or !(version.include? cipher[:version])}
|
||||
end
|
||||
else
|
||||
raise ArgumentError, "Was expecting Symbol or Array and got #{version.class}"
|
||||
end
|
||||
end
|
||||
|
||||
def accepted
|
||||
{
|
||||
:SSLv2 => @sslv2[:accepted],
|
||||
:SSLv3 => @sslv3[:accepted],
|
||||
:TLSv1 => @tlsv1[:accepted]
|
||||
}
|
||||
def rejected(version = :all)
|
||||
if version.kind_of? Symbol
|
||||
case version
|
||||
when :all
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :accepted}
|
||||
when :SSLv2, :SSLv3, :TLSv1
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :accepted or cipher[:version] != version}
|
||||
else
|
||||
raise ArgumentError, "Invalid SSL Version Supplied: #{version}"
|
||||
end
|
||||
elsif version.kind_of? Array
|
||||
version.reject!{|version| @supported_versions.include? version}
|
||||
if version.empty?
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :accepted}
|
||||
else
|
||||
return @ciphers.reject{|cipher| cipher[:status] == :accepted or !(version.include? cipher[:version])}
|
||||
end
|
||||
else
|
||||
raise ArgumentError, "Was expecting Symbol or Array and got #{version.class}"
|
||||
end
|
||||
end
|
||||
|
||||
def rejected
|
||||
{
|
||||
:SSLv2 => @sslv2[:rejected],
|
||||
:SSLv3 => @sslv3[:rejected],
|
||||
:TLSv1 => @tlsv1[:rejected]
|
||||
}
|
||||
end
|
||||
|
||||
def each_accepted
|
||||
all_accepted = []
|
||||
|
||||
accepted.each_pair do |version, cipher_list|
|
||||
cipher_list.each do |cipher_details|
|
||||
cipher_details[:version] = version
|
||||
all_accepted << cipher_details
|
||||
end
|
||||
end
|
||||
all_accepted.each do |cipher_result|
|
||||
def each_accepted(version = :all)
|
||||
accepted(version).each do |cipher_result|
|
||||
yield cipher_result
|
||||
end
|
||||
end
|
||||
|
||||
def each_rejected
|
||||
all_rejected = []
|
||||
|
||||
rejected.each_pair do |version, cipher_list|
|
||||
cipher_list.each do |cipher_details|
|
||||
cipher_details[:version] = version
|
||||
all_rejected << cipher_details
|
||||
end
|
||||
end
|
||||
all_rejected.each do |cipher_result|
|
||||
def each_rejected(version = :all)
|
||||
rejected(version).each do |cipher_result|
|
||||
yield cipher_result
|
||||
end
|
||||
end
|
||||
|
||||
def supports_sslv2?
|
||||
!(accepted[:SSLv2].empty?)
|
||||
!(accepted(:SSLv2).empty?)
|
||||
end
|
||||
|
||||
def supports_sslv3?
|
||||
!(accepted[:SSLv3].empty?)
|
||||
!(accepted(:SSLv3).empty?)
|
||||
end
|
||||
|
||||
def supports_tlsv1?
|
||||
!(accepted[:TLSv1].empty?)
|
||||
!(accepted(:TLSv1).empty?)
|
||||
end
|
||||
|
||||
def supports_ssl?
|
||||
|
|
|
@ -5,33 +5,23 @@ describe Rex::SSLScan::Result do
|
|||
subject{Rex::SSLScan::Result.new}
|
||||
|
||||
it { should respond_to :cert }
|
||||
it { should respond_to :sslv2 }
|
||||
it { should respond_to :sslv3 }
|
||||
it { should respond_to :tlsv1 }
|
||||
it { should respond_to :ciphers }
|
||||
|
||||
context "with no values set" do
|
||||
it "should return nil for the cert" do
|
||||
subject.cert.should == nil
|
||||
end
|
||||
|
||||
it "should return an empty structure for sslv2" do
|
||||
subject.sslv2.should == {:accepted => [], :rejected => []}
|
||||
it "should return an empty array for ciphers" do
|
||||
subject.ciphers.should == []
|
||||
end
|
||||
|
||||
it "should return an empty structure for sslv3" do
|
||||
subject.sslv3.should == {:accepted => [], :rejected => []}
|
||||
it "should return an empty array for accepted" do
|
||||
subject.accepted.should == []
|
||||
end
|
||||
|
||||
it "should return an empty structure for tlsv1" do
|
||||
subject.tlsv1.should == {:accepted => [], :rejected => []}
|
||||
end
|
||||
|
||||
it "should return an empty structure for #accepted" do
|
||||
subject.accepted.should == {:SSLv2=>[], :SSLv3=>[], :TLSv1=>[]}
|
||||
end
|
||||
|
||||
it "should return an emtpy structure for #rejected" do
|
||||
subject.rejected.should == {:SSLv2=>[], :SSLv3=>[], :TLSv1=>[]}
|
||||
it "should return an empty array for rejected" do
|
||||
subject.rejected.should == []
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,65 +79,109 @@ describe Rex::SSLScan::Result do
|
|||
context "that was accepted" do
|
||||
it "should add an SSLv2 cipher result to the SSLv2 Accepted array" do
|
||||
subject.add_cipher(:SSLv2, "DES-CBC3-MD5", 168, :accepted)
|
||||
subject.sslv2[:accepted].should include({:cipher=>"DES-CBC3-MD5", :key_length=>168})
|
||||
subject.accepted[:SSLv2].should include({:cipher=>"DES-CBC3-MD5", :key_length=>168})
|
||||
subject.accepted(:SSLv2).should include({
|
||||
:version => :SSLv2,
|
||||
:cipher=>"DES-CBC3-MD5",
|
||||
:key_length=>168,
|
||||
:weak=> false,
|
||||
:status => :accepted})
|
||||
end
|
||||
|
||||
it "should add an SSLv3 cipher result to the SSLv3 Accepted array" do
|
||||
subject.add_cipher(:SSLv3, "AES256-SHA", 256, :accepted)
|
||||
subject.sslv3[:accepted].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.accepted[:SSLv3].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.accepted(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :accepted})
|
||||
end
|
||||
|
||||
it "should add an TLSv1 cipher result to the TLSv1 Accepted array" do
|
||||
subject.add_cipher(:TLSv1, "AES256-SHA", 256, :accepted)
|
||||
subject.tlsv1[:accepted].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.accepted[:TLSv1].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.accepted(:TLSv1).should include({
|
||||
:version => :TLSv1,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :accepted})
|
||||
end
|
||||
|
||||
it "should successfully add multiple entries in a row" do
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :accepted)
|
||||
subject.add_cipher(:SSLv3, "AES256-SHA", 256, :accepted)
|
||||
subject.sslv3[:accepted].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.sslv3[:accepted].should include({:cipher=>"AES128-SHA", :key_length=>128})
|
||||
subject.accepted(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :accepted})
|
||||
subject.accepted(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :accepted})
|
||||
end
|
||||
|
||||
it "should not add duplicate entries" do
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :accepted)
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :accepted)
|
||||
subject.sslv3[:accepted].count.should == 1
|
||||
subject.accepted(:SSLv3).count.should == 1
|
||||
end
|
||||
end
|
||||
context "that was rejected" do
|
||||
it "should add an SSLv2 cipher result to the SSLv2 Rejected array" do
|
||||
subject.add_cipher(:SSLv2, "DES-CBC3-MD5", 168, :rejected)
|
||||
subject.sslv2[:rejected].should include({:cipher=>"DES-CBC3-MD5", :key_length=>168})
|
||||
subject.rejected[:SSLv2].should include({:cipher=>"DES-CBC3-MD5", :key_length=>168})
|
||||
subject.rejected(:SSLv2).should include({
|
||||
:version => :SSLv2,
|
||||
:cipher=>"DES-CBC3-MD5",
|
||||
:key_length=>168,
|
||||
:weak=> false,
|
||||
:status => :rejected})
|
||||
end
|
||||
|
||||
it "should add an SSLv3 cipher result to the SSLv3 Rejected array" do
|
||||
subject.add_cipher(:SSLv3, "AES256-SHA", 256, :rejected)
|
||||
subject.sslv3[:rejected].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.rejected[:SSLv3].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.rejected(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :rejected})
|
||||
end
|
||||
|
||||
it "should add an TLSv1 cipher result to the TLSv1 Rejected array" do
|
||||
subject.add_cipher(:TLSv1, "AES256-SHA", 256, :rejected)
|
||||
subject.tlsv1[:rejected].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.rejected[:TLSv1].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.rejected(:TLSv1).should include({
|
||||
:version => :TLSv1,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :rejected})
|
||||
end
|
||||
|
||||
it "should successfully add multiple entries in a row" do
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :rejected)
|
||||
subject.add_cipher(:SSLv3, "AES256-SHA", 256, :rejected)
|
||||
subject.sslv3[:rejected].should include({:cipher=>"AES256-SHA", :key_length=>256})
|
||||
subject.sslv3[:rejected].should include({:cipher=>"AES128-SHA", :key_length=>128})
|
||||
subject.rejected(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES256-SHA",
|
||||
:key_length=>256,
|
||||
:weak=> false,
|
||||
:status => :rejected})
|
||||
subject.rejected(:SSLv3).should include({
|
||||
:version => :SSLv3,
|
||||
:cipher=>"AES128-SHA",
|
||||
:key_length=>128,
|
||||
:weak=> false,
|
||||
:status => :rejected})
|
||||
end
|
||||
|
||||
it "should not add duplicate entries" do
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :rejected)
|
||||
subject.add_cipher(:SSLv3, "AES128-SHA", 128, :rejected)
|
||||
subject.sslv3[:rejected].count.should == 1
|
||||
subject.rejected(:SSLv3).count.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -162,7 +196,7 @@ describe Rex::SSLScan::Result do
|
|||
|
||||
it "should return an array of cipher detail hashes" do
|
||||
subject.each_accepted do |cipher_details|
|
||||
cipher_details.should include(:version, :cipher, :key_length)
|
||||
cipher_details.should include(:version, :cipher, :key_length, :status, :weak)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -185,7 +219,7 @@ describe Rex::SSLScan::Result do
|
|||
|
||||
it "should return an array of cipher detail hashes" do
|
||||
subject.each_rejected do |cipher_details|
|
||||
cipher_details.should include(:version, :cipher, :key_length)
|
||||
cipher_details.should include(:version, :cipher, :key_length, :status, :weak)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue