CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/core/cert_provider.rb
Views: 11623
1
require 'rex/socket/ssl'
2
3
module Msf
4
module Ssl
5
module CertProvider
6
7
def self.rand_vars(opts = {})
8
opts ||= {}
9
opts[:cc] ||= 'US'
10
opts[:st] ||= Faker::Address.state_abbr
11
opts[:loc] ||= Faker::Address.city
12
opts[:org] ||= Faker::Company.name
13
opts[:ou] ||= Faker::Hacker.send(%w{noun verb adjective}.sample.to_sym).gsub(/\W+/,'.')
14
opts[:cn] ||= opts[:org].downcase.gsub(/and/,'').gsub(/\W+/,'.') + '.' + Faker::Internet.domain_suffix
15
opts[:email] ||= "#{opts[:ou]}@#{opts[:cn]}"
16
opts
17
end
18
19
def self.ssl_generate_subject(opts = {})
20
opts = self.rand_vars(opts)
21
subject = ""
22
subject << "/C=#{opts[:cc]}" if opts[:cc]
23
subject << "/ST=#{opts[:st]}" if opts[:st]
24
subject << "/O=#{opts[:org]}" if opts[:org]
25
subject << "/OU=#{opts[:ou]}" if opts[:ou]
26
subject << "/CN=#{opts[:cn]}" if opts[:cn]
27
subject << "/emailAddress=#{opts[:email]}" if opts[:email]
28
subject
29
end
30
31
# Not used, for API compatibility
32
def self.ssl_generate_issuer(
33
cc: 'US',
34
org: Faker::Company.name,
35
cn: Faker::Internet.domain_name
36
)
37
"#{cc}/O=#{org}/CN=#{cn}"
38
end
39
40
#
41
# Generate a realistic-looking but obstensibly fake SSL
42
# certificate. Use Faker gem to mimic other self-signed
43
# certificates on the web to reduce the chance of sig
44
# identification by NIDS and the like.
45
#
46
# @return [String, String, Array]
47
def self.ssl_generate_certificate(cert_vars: {}, ksize: 2048, **opts)
48
yr = 24*3600*365
49
vf = opts[:not_before] || Time.at(Time.now.to_i - rand(yr * 3) - yr)
50
vt = opts[:not_after] || Time.at(vf.to_i + (rand(4..9) * yr))
51
cvars = self.rand_vars(cert_vars)
52
subject = opts[:subject] || ssl_generate_subject(cvars)
53
ctype = opts[:cert_type] || opts[:ca_cert].nil? ? :ca : :server
54
key = opts[:key] || OpenSSL::PKey::RSA.new(ksize){ }
55
cert = OpenSSL::X509::Certificate.new
56
57
cert.version = opts[:version] || 2
58
cert.serial = opts[:serial] || (rand(0xFFFFFFFF) << 32) + rand(0xFFFFFFFF)
59
cert.subject = OpenSSL::X509::Name.parse(subject)
60
cert.issuer = opts[:ca_cert] || cert.subject
61
cert.not_before = vf
62
cert.not_after = vt
63
cert.public_key = key.public_key
64
65
bconst, kuse, ekuse = case ctype
66
when :ca
67
['CA:TRUE', 'cRLSign,keyCertSign']
68
when :server
69
['CA:FALSE', 'digitalSignature,keyEncipherment', 'serverAuth']
70
when :client
71
['CA:FALSE', 'nonRepudiation,digitalSignature,keyEncipherment', 'clientAuth,emailProtection']
72
when :ocsp
73
['CA:FALSE', 'nonRepudiation,digitalSignature', 'serverAuth,OCSPSigning']
74
when :tsca
75
['CA:TRUE,pathlen:0', 'cRLSign,keyCertSign']
76
end
77
78
ef = OpenSSL::X509::ExtensionFactory.new
79
ef.subject_certificate = cert
80
ef.issuer_certificate = cert
81
cert.extensions = [
82
ef.create_extension("basicConstraints", bconst, true),
83
ef.create_extension("subjectKeyIdentifier", "hash")
84
]
85
if kuse and !kuse.empty?
86
cert.extensions << ef.create_extension("keyUsage", kuse)
87
end
88
89
if ekuse and !ekuse.empty?
90
cert.extensions << ef.create_extension("extendedKeyUsage", ekuse)
91
end
92
93
cert.sign(key, OpenSSL::Digest.new('SHA256'))
94
95
[key, cert, nil]
96
end
97
end
98
end
99
end
100
101