#!/usr/bin/env ruby require 'ciphersurfer' require 'rainbow' require 'awesome_print' require 'progressbar' require 'getoptlong' require 'json' opts = GetoptLong.new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--version', '-v', GetoptLong::NO_ARGUMENT ], [ '--list-ciphers', '-l', GetoptLong::NO_ARGUMENT ]#, # [ '--json', '-j', GetoptLong::NO_ARGUMENT] ) options={:json=>false,:list_ciphers=>false} opts.each do |opt, arg| case opt when '--help' ap "usage: ciphersurfer [-ljvh] server[:port]" ap " -l: lists supported ciphers instead of just evaluate the security level" # ap " -j: formats the output using JSON" ap " -v: shows version" ap " -h: this help" exit 0 when '--version' ap "ciphersurfer " + Ciphersurfer::Version.version[:string] exit 0 # unsupported right now... #when '--json' # options[:json]=true when '--list-ciphers' options[:list_ciphers]=true end end if ( ARGV.length != 1 ) ap 'ciphersurfer: missing target' exit -1 end target = ARGV.shift host = target.split(':')[0] ||= "localhost" #fallback here should never occur... however it's better to be paranoid port = target.split(':')[1] ||= 443 # more common here ap "scanning #{host}:#{port} for supported ciphers" if ! Ciphersurfer::Scanner.alive?(host, port) ap "it seems there is no server listening @#{host}:#{port}" exit -2 end protocol_version = [:SSLv2, :SSLv3, :TLSv1]#, :TLSv11, :TLSv12] # ok = {} supported_protocols = [] cipher_bits=[] protocol_version.each do |version| s = Ciphersurfer::Scanner.new({:host=>host, :port=>port, :proto=>version}) s.go if (s.ok_ciphers.size != 0) supported_protocols << version cipher_bits = cipher_bits | s.ok_bits end # ok << {:proto=>version, :ciphers=>s.ok_ciphers} end cert = Ciphersurfer::Scanner.cert(host, port) a=cert.public_key.to_text key_size=/Modulus \((\d+)/i.match(a)[1] proto_score= Ciphersurfer::Score.evaluate_protocols(supported_protocols) cipher_score= Ciphersurfer::Score.evaluate_ciphers(cipher_bits) key_score= Ciphersurfer::Score.evaluate_key(key_size.to_i) score= Ciphersurfer::Score.score(proto_score, key_score, cipher_score) ap Ciphersurfer::Score.evaluate(score) + " ("+score.to_s+")" ap "Protocol support: " + proto_score.to_s ap "Key exchange: " + key_score.to_s ap "Cipher strength: " + cipher_score.to_s # e.g. supported_protocols = [:SSLv2, :TLSv1] # e.g. cipher_bits = [0, 256, 1024] # if options[:list_ciphers] # ok.each do |o| # puts "[+] Accepted\\t #{o[:bits]} bits\\t#{o[:name]}" # end # end