Update the specs
This commit is contained in:
@@ -96,18 +96,18 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
describe '#create_csr' do
|
||||
context 'with a private key supplied via opts' do
|
||||
it 'returns an OpenSSL::X509::Request' do
|
||||
result = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(result).to be_a(OpenSSL::X509::Request)
|
||||
csr, _key = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(csr).to be_a(OpenSSL::X509::Request)
|
||||
end
|
||||
|
||||
it 'signs the CSR with the provided key' do
|
||||
result = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(result.verify(rsa_key.public_key)).to be true
|
||||
csr, _key = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(csr.verify(rsa_key.public_key)).to be true
|
||||
end
|
||||
|
||||
it 'sets the CN to the provided username' do
|
||||
result = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(result.subject.to_s).to include('alice')
|
||||
csr, _key = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(csr.subject.to_s).to include('alice')
|
||||
end
|
||||
|
||||
context 'when the key size matches the expected rsa_key_size' do
|
||||
@@ -117,8 +117,8 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
end
|
||||
|
||||
it 'returns a CSR' do
|
||||
result = subject.create_csr(username: 'alice', private_key: rsa_key, rsa_key_size: 2048)
|
||||
expect(result).to be_a(OpenSSL::X509::Request)
|
||||
csr, _key = subject.create_csr(username: 'alice', private_key: rsa_key, rsa_key_size: 2048)
|
||||
expect(csr).to be_a(OpenSSL::X509::Request)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -154,8 +154,8 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
end
|
||||
|
||||
it 'returns a valid OpenSSL::X509::Request' do
|
||||
result = subject.create_csr(username: 'alice')
|
||||
expect(result).to be_a(OpenSSL::X509::Request)
|
||||
csr, _key = subject.create_csr(username: 'alice')
|
||||
expect(csr).to be_a(OpenSSL::X509::Request)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -282,13 +282,13 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
end
|
||||
|
||||
it 'calls build_on_behalf_of and returns a ContentInfo object' do
|
||||
result = subject.create_csr(
|
||||
csr, _key = subject.create_csr(
|
||||
username: 'alice',
|
||||
private_key: rsa_key,
|
||||
pkcs12: pkcs12,
|
||||
on_behalf_of: 'DOMAIN\\administrator'
|
||||
)
|
||||
expect(result).to be_a(Rex::Proto::CryptoAsn1::Cms::ContentInfo)
|
||||
expect(csr).to be_a(Rex::Proto::CryptoAsn1::Cms::ContentInfo)
|
||||
end
|
||||
|
||||
it 'passes on_behalf_of to build_on_behalf_of' do
|
||||
@@ -314,20 +314,20 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
|
||||
it 'skips build_on_behalf_of and returns a plain CSR' do
|
||||
expect(Rex::Proto::X509::Request).not_to receive(:build_on_behalf_of)
|
||||
result = subject.create_csr(username: 'alice', private_key: rsa_key, pkcs12: pkcs12)
|
||||
expect(result).to be_a(OpenSSL::X509::Request)
|
||||
csr, _key = subject.create_csr(username: 'alice', private_key: rsa_key, pkcs12: pkcs12)
|
||||
expect(csr).to be_a(OpenSSL::X509::Request)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with on_behalf_of but no pkcs12' do
|
||||
it 'skips build_on_behalf_of and returns a plain CSR' do
|
||||
expect(Rex::Proto::X509::Request).not_to receive(:build_on_behalf_of)
|
||||
result = subject.create_csr(
|
||||
csr, _key = subject.create_csr(
|
||||
username: 'alice',
|
||||
private_key: rsa_key,
|
||||
on_behalf_of: 'DOMAIN\\administrator'
|
||||
)
|
||||
expect(result).to be_a(OpenSSL::X509::Request)
|
||||
expect(csr).to be_a(OpenSSL::X509::Request)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -167,6 +167,8 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
describe '#retrieve_certs' do
|
||||
let(:authenticated_client) { double('authenticated_client') }
|
||||
|
||||
before { subject.instance_variable_set(:@issued_certs, {}) }
|
||||
|
||||
it 'calls retrieve_cert for each template' do
|
||||
templates = %w[UserTemplate AdminTemplate]
|
||||
templates.each do |t|
|
||||
@@ -179,6 +181,20 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
expect(subject).not_to receive(:retrieve_cert)
|
||||
subject.retrieve_certs('192.168.1.1', authenticated_client, 'DOMAIN\\user', [])
|
||||
end
|
||||
|
||||
context 'when a cert has already been issued' do
|
||||
before { subject.add_cert_entry('DOMAIN\\user', 'UserTemplate') }
|
||||
|
||||
it 'skips retrieve_cert for the already-issued template' do
|
||||
expect(subject).not_to receive(:retrieve_cert).with('192.168.1.1', authenticated_client, 'DOMAIN\\user', 'UserTemplate')
|
||||
subject.retrieve_certs('192.168.1.1', authenticated_client, 'DOMAIN\\user', ['UserTemplate'])
|
||||
end
|
||||
|
||||
it 'still calls retrieve_cert for other templates' do
|
||||
expect(subject).to receive(:retrieve_cert).with('192.168.1.1', authenticated_client, 'DOMAIN\\user', 'AdminTemplate')
|
||||
subject.retrieve_certs('192.168.1.1', authenticated_client, 'DOMAIN\\user', %w[UserTemplate AdminTemplate])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -190,43 +206,6 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
|
||||
before { subject.instance_variable_set(:@issued_certs, {}) }
|
||||
|
||||
context 'when generating the RSA key' do
|
||||
let(:csr_double) { double('csr', to_der: 'der_bytes') }
|
||||
let(:denied_res) { double('response', code: 200, body: 'request was denied') }
|
||||
|
||||
it 'uses the default key size of 2048 when RSAKeySize is blank' do
|
||||
allow(subject).to receive(:create_csr).and_return(csr_double)
|
||||
allow(subject).to receive(:send_request_raw).and_return(denied_res)
|
||||
expect(OpenSSL::PKey::RSA).to receive(:new).with(2048).and_call_original
|
||||
subject.retrieve_cert(target_ip, authenticated_client, identity, template)
|
||||
end
|
||||
|
||||
it 'uses the RSAKeySize from the datastore when set' do
|
||||
subject.datastore['RSAKeySize'] = '4096'
|
||||
allow(subject).to receive(:create_csr).and_return(csr_double)
|
||||
allow(subject).to receive(:send_request_raw).and_return(denied_res)
|
||||
expect(OpenSSL::PKey::RSA).to receive(:new).with(4096).and_call_original
|
||||
subject.retrieve_cert(target_ip, authenticated_client, identity, template)
|
||||
end
|
||||
|
||||
it 'passes the generated key to create_csr' do
|
||||
generated_key = OpenSSL::PKey::RSA.new(2048)
|
||||
allow(OpenSSL::PKey::RSA).to receive(:new).and_return(generated_key)
|
||||
allow(subject).to receive(:send_request_raw).and_return(denied_res)
|
||||
expect(subject).to receive(:create_csr).with(hash_including(private_key: generated_key)).and_return(csr_double)
|
||||
subject.retrieve_cert(target_ip, authenticated_client, identity, template)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the cert has already been issued' do
|
||||
before { subject.add_cert_entry(identity, template) }
|
||||
|
||||
it 'returns nil without making an HTTP request' do
|
||||
expect(subject).not_to receive(:send_request_raw)
|
||||
expect(subject.retrieve_cert(target_ip, authenticated_client, identity, template)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the POST response is 200 with body containing "request was denied"' do
|
||||
let(:csr) { double('csr', to_der: 'der_bytes') }
|
||||
let(:res) { double('response', code: 200, body: 'Certificate request was denied by policy') }
|
||||
@@ -308,10 +287,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:get_res) { double('response', code: 200, body: certificate.to_der) }
|
||||
|
||||
before do
|
||||
# Force retrieve_cert to use rsa_key so the generated key matches the certificate
|
||||
rsa_key
|
||||
allow(OpenSSL::PKey::RSA).to receive(:new).and_return(rsa_key)
|
||||
allow(subject).to receive(:create_csr).and_return(csr)
|
||||
allow(subject).to receive(:create_csr).and_return([csr, rsa_key])
|
||||
allow(subject).to receive(:send_request_raw).and_return(post_res, get_res)
|
||||
allow(subject).to receive(:store_loot).and_return('/tmp/cert.pfx')
|
||||
end
|
||||
|
||||
@@ -302,47 +302,11 @@ RSpec.describe Msf::Exploit::Remote::MsIcpr do
|
||||
end
|
||||
|
||||
context 'RSA key generation' do
|
||||
it 'generates a 2048-bit key by default' do
|
||||
expect(OpenSSL::PKey::RSA).to receive(:new).with(2048).and_return(rsa_key)
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice' })
|
||||
end
|
||||
|
||||
it 'uses the RSAKeySize from the datastore' do
|
||||
subject.datastore['RSAKeySize'] = '4096'
|
||||
allow(rsa_key).to receive(:n).and_return(double('OpenSSL::BN', num_bits: 4096))
|
||||
expect(OpenSSL::PKey::RSA).to receive(:new).with(4096).and_return(rsa_key)
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice' })
|
||||
end
|
||||
|
||||
it 'uses a private key supplied in opts without generating one' do
|
||||
rsa_key # force let evaluation before stubbing
|
||||
expect(OpenSSL::PKey::RSA).not_to receive(:new)
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key })
|
||||
end
|
||||
|
||||
it 'passes the key to create_csr via opts' do
|
||||
allow(OpenSSL::PKey::RSA).to receive(:new).and_return(rsa_key)
|
||||
expect(subject).to receive(:create_csr).with(hash_including(private_key: rsa_key))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice' })
|
||||
end
|
||||
end
|
||||
|
||||
context 'key size mismatch' do
|
||||
let(:wrong_size_key) { OpenSSL::PKey::RSA.new(1024) }
|
||||
|
||||
it 'raises ArgumentError' do
|
||||
expect { subject.send(:do_request_cert, icpr, { username: 'alice', private_key: wrong_size_key }) }.to raise_error(ArgumentError, /RSA key size mismatch/)
|
||||
end
|
||||
|
||||
it 'logs an RSA key size mismatch error' do
|
||||
expect(subject).to receive(:elog).with('RSA key size mismatch')
|
||||
expect { subject.send(:do_request_cert, icpr, { username: 'alice', private_key: wrong_size_key }) }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'does not call create_csr' do
|
||||
expect(subject).not_to receive(:create_csr)
|
||||
expect { subject.send(:do_request_cert, icpr, { username: 'alice', private_key: wrong_size_key }) }.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'certificate template' do
|
||||
|
||||
Reference in New Issue
Block a user