Require msf/core/cert_provider in framework.rb

Add an explicit require for the new cert_provider in framework.rb
in case it has not yet been loaded.

This should address the Travis failure on initial PR, although the
gem version in socket has not been updated, so this might take a
bit to propagate. In the end, if the dependency already gives us
this functionality by the time we call Rex::Socket::Ssl then this
commit can safely be dropped
MS-2855/keylogger-mettle-extension
RageLtMan 2017-12-29 01:35:23 -05:00
parent 18f3815147
commit c32ef4a3be
3 changed files with 102 additions and 100 deletions

View File

@ -0,0 +1,100 @@
require 'rex/socket/ssl'
require 'faker'
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(opts = {}, ksize = 2048)
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(9)+1) * yr)
cvars = opts[:cert_vars] || self.rand_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.new([["C", 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::SHA256.new)
[key, cert, nil]
end
end
end
end

View File

@ -1,99 +0,0 @@
module Msf
module Exploit::Remote::Ssl
require 'rex/socket/ssl'
require 'faker'
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(opts = {}, ksize = 2048)
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(9)+1) * yr)
cvars = opts[:cert_vars] || self.rand_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.new([["C", 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::SHA256.new)
[key, cert, nil]
end
end
end
end

View File

@ -61,6 +61,7 @@ class Framework
require 'msf/core/db_manager'
require 'msf/core/event_dispatcher'
require 'rex/json_hash_file'
require 'msf/core/cert_provider'
#
# Creates an instance of the framework context.
@ -85,7 +86,7 @@ class Framework
Rex::ThreadFactory.provider = Metasploit::Framework::ThreadFactoryProvider.new(framework: self)
# Configure the SSL certificate generator
Rex::Socket::Ssl.cert_provider = Msf::Exploit::Remote::Ssl::CertProvider
Rex::Socket::Ssl.cert_provider = Msf::Ssl::CertProvider
subscriber = FrameworkEventSubscriber.new(self)
events.add_exploit_subscriber(subscriber)