require 'rex/socket/ssl' module Msf module Ssl module CertProvider def self.rand_vars(opts = {}) opts ||= {} opts[:cc] ||= 'US' opts[:st] ||= Faker::Address.state_abbr opts[:loc] ||= Faker::Address.city opts[:org] ||= Faker::Company.name opts[:ou] ||= Faker::Hacker.send(%w{noun verb adjective}.sample.to_sym).gsub(/\W+/,'.') opts[:cn] ||= opts[:org].downcase.gsub(/and/,'').gsub(/\W+/,'.') + '.' + Faker::Internet.domain_suffix opts[:email] ||= "#{opts[:ou]}@#{opts[:cn]}" opts end def self.ssl_generate_subject(opts = {}) opts = self.rand_vars(opts) subject = "" subject << "/C=#{opts[:cc]}" if opts[:cc] subject << "/ST=#{opts[:st]}" if opts[:st] subject << "/O=#{opts[:org]}" if opts[:org] subject << "/OU=#{opts[:ou]}" if opts[:ou] subject << "/CN=#{opts[:cn]}" if opts[:cn] subject << "/emailAddress=#{opts[:email]}" if opts[:email] subject end # Not used, for API compatibility def self.ssl_generate_issuer( cc: 'US', org: Faker::Company.name, cn: Faker::Internet.domain_name ) "#{cc}/O=#{org}/CN=#{cn}" end # # Generate a realistic-looking but obstensibly fake SSL # certificate. Use Faker gem to mimic other self-signed # certificates on the web to reduce the chance of sig # identification by NIDS and the like. # # @return [String, String, Array] def self.ssl_generate_certificate(cert_vars: {}, ksize: 2048, **opts) yr = 24*3600*365 vf = opts[:not_before] || Time.at(Time.now.to_i - rand(yr * 3) - yr) vt = opts[:not_after] || Time.at(vf.to_i + (rand(4..9) * yr)) cvars = self.rand_vars(cert_vars) subject = opts[:subject] || ssl_generate_subject(cvars) ctype = opts[:cert_type] || opts[:ca_cert].nil? ? :ca : :server key = opts[:key] || OpenSSL::PKey::RSA.new(ksize){ } cert = OpenSSL::X509::Certificate.new cert.version = opts[:version] || 2 cert.serial = opts[:serial] || (rand(0xFFFFFFFF) << 32) + rand(0xFFFFFFFF) cert.subject = OpenSSL::X509::Name.parse(subject) cert.issuer = opts[:ca_cert] || cert.subject cert.not_before = vf cert.not_after = vt cert.public_key = key.public_key bconst, kuse, ekuse = case ctype when :ca ['CA:TRUE', 'cRLSign,keyCertSign'] when :server ['CA:FALSE', 'digitalSignature,keyEncipherment', 'serverAuth'] when :client ['CA:FALSE', 'nonRepudiation,digitalSignature,keyEncipherment', 'clientAuth,emailProtection'] when :ocsp ['CA:FALSE', 'nonRepudiation,digitalSignature', 'serverAuth,OCSPSigning'] when :tsca ['CA:TRUE,pathlen:0', 'cRLSign,keyCertSign'] end ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = cert ef.issuer_certificate = cert cert.extensions = [ ef.create_extension("basicConstraints", bconst, true), ef.create_extension("subjectKeyIdentifier", "hash") ] if kuse and !kuse.empty? cert.extensions << ef.create_extension("keyUsage", kuse) end if ekuse and !ekuse.empty? cert.extensions << ef.create_extension("extendedKeyUsage", ekuse) end cert.sign(key, OpenSSL::Digest.new('SHA256')) [key, cert, nil] end end end end