fix stupid datat structure

also supports a boolean value for whether the cipher is weak or not
bug/bundler_fix
David Maloney 2013-02-08 11:33:36 -06:00
parent 5c9f946927
commit dfc7ce9381
2 changed files with 137 additions and 91 deletions

View File

@ -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}
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!
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
{
:SSLv2 => @sslv2[:accepted],
:SSLv3 => @sslv3[:accepted],
:TLSv1 => @tlsv1[:accepted]
}
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
def accepted(version = :all)
if version.kind_of? Symbol
case version
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
all_accepted.each do |cipher_result|
end
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 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?

View File

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