Consolidate the attribute creation
This commit is contained in:
@@ -362,5 +362,79 @@ RSpec.describe Msf::Exploit::Remote::CertRequest do
|
||||
subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
end
|
||||
end
|
||||
|
||||
context 'returned attributes' do
|
||||
context 'with cert_template supplied via opts' do
|
||||
it 'sets CertificateTemplate in the returned attributes' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key, cert_template: 'AdminTemplate')
|
||||
expect(attrs['CertificateTemplate']).to eq('AdminTemplate')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with cert_template supplied via datastore' do
|
||||
before { subject.datastore['CERT_TEMPLATE'] = 'UserTemplate' }
|
||||
|
||||
it 'sets CertificateTemplate from the datastore' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(attrs['CertificateTemplate']).to eq('UserTemplate')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no cert_template is supplied' do
|
||||
it 'does not include CertificateTemplate in the returned attributes' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(attrs).not_to have_key('CertificateTemplate')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with alt_dns supplied via opts' do
|
||||
it 'includes dns in the SAN attribute' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key, alt_dns: 'host.example.com')
|
||||
expect(attrs['SAN']).to include('dns=host.example.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with alt_upn supplied via opts' do
|
||||
it 'includes upn in the SAN attribute' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key, alt_upn: 'alice@example.com')
|
||||
expect(attrs['SAN']).to include('upn=alice@example.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with alt_sid supplied via opts' do
|
||||
let(:sid) { 'S-1-5-21-1234567890-1234567890-1234567890-500' }
|
||||
|
||||
before { allow(Rex::Proto::X509::Request).to receive(:build_csr).and_return(double('csr', to_der: '')) }
|
||||
|
||||
it 'includes the prefixed URL SAN entry in the returned attributes' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key, alt_sid: sid)
|
||||
expect(attrs['SAN']).to include("url=#{Rex::Proto::X509::SAN_URL_PREFIX}#{sid}")
|
||||
end
|
||||
|
||||
it 'includes the bare URL SAN entry in the returned attributes' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key, alt_sid: sid)
|
||||
expect(attrs['SAN']).to include("url=#{sid}")
|
||||
end
|
||||
end
|
||||
|
||||
context 'with alt_dns and alt_upn supplied' do
|
||||
it 'joins both SAN entries with &' do
|
||||
_csr, _key, attrs = subject.create_csr(
|
||||
username: 'alice', private_key: rsa_key,
|
||||
alt_dns: 'host.example.com', alt_upn: 'alice@example.com'
|
||||
)
|
||||
expect(attrs['SAN']).to include('dns=host.example.com')
|
||||
expect(attrs['SAN']).to include('upn=alice@example.com')
|
||||
expect(attrs['SAN']).to include('&')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no SAN values are set' do
|
||||
it 'does not include SAN in the returned attributes' do
|
||||
_csr, _key, attrs = subject.create_csr(username: 'alice', private_key: rsa_key)
|
||||
expect(attrs).not_to have_key('SAN')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -211,7 +211,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:res) { double('response', code: 200, body: 'Certificate request was denied by policy') }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return(csr)
|
||||
allow(subject).to receive(:create_csr).and_return([csr, nil, {}])
|
||||
allow(subject).to receive(:send_request_raw).and_return(res)
|
||||
end
|
||||
|
||||
@@ -225,7 +225,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:res) { double('response', code: 200, body: 'Certificate request failed due to an error') }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return(csr)
|
||||
allow(subject).to receive(:create_csr).and_return([csr, nil, {}])
|
||||
allow(subject).to receive(:send_request_raw).and_return(res)
|
||||
end
|
||||
|
||||
@@ -239,7 +239,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:res) { double('response', code: 401, body: 'Error: invalid credentials provided') }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return(csr)
|
||||
allow(subject).to receive(:create_csr).and_return([csr, nil, {}])
|
||||
allow(subject).to receive(:send_request_raw).and_return(res)
|
||||
end
|
||||
|
||||
@@ -253,7 +253,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:res) { double('response', code: 200, body: 'Certificate generated successfully, no location here') }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return(csr)
|
||||
allow(subject).to receive(:create_csr).and_return([csr, nil, {}])
|
||||
allow(subject).to receive(:send_request_raw).and_return(res)
|
||||
end
|
||||
|
||||
@@ -287,7 +287,7 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
let(:get_res) { double('response', code: 200, body: certificate.to_der) }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return([csr, rsa_key])
|
||||
allow(subject).to receive(:create_csr).and_return([csr, rsa_key, { 'CertificateTemplate' => template }])
|
||||
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
|
||||
@@ -313,6 +313,14 @@ RSpec.describe Msf::Exploit::Remote::HTTP::WebEnrollment do
|
||||
)
|
||||
subject.retrieve_cert(target_ip, authenticated_client, identity, template)
|
||||
end
|
||||
|
||||
it 'posts CertAttrib with key:value format' do
|
||||
expect(subject).to receive(:send_request_raw).with(
|
||||
hash_including('vars_post' => hash_including('CertAttrib' => "CertificateTemplate:#{template}"))
|
||||
).and_return(post_res)
|
||||
allow(subject).to receive(:send_request_raw).and_return(get_res)
|
||||
subject.retrieve_cert(target_ip, authenticated_client, identity, template)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -284,7 +284,7 @@ RSpec.describe Msf::Exploit::Remote::MsIcpr do
|
||||
let(:csr_double) { double('csr', to_der: 'der') }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:create_csr).and_return(csr_double)
|
||||
allow(subject).to receive(:create_csr).and_return([csr_double, rsa_key, {}])
|
||||
allow(icpr).to receive(:cert_server_request).and_return({ status: :issued })
|
||||
end
|
||||
|
||||
@@ -309,57 +309,12 @@ RSpec.describe Msf::Exploit::Remote::MsIcpr do
|
||||
end
|
||||
end
|
||||
|
||||
context 'certificate template' do
|
||||
it 'uses cert_template from opts' do
|
||||
expect(icpr).to receive(:cert_server_request).with(hash_including(
|
||||
attributes: hash_including('CertificateTemplate' => 'AdminTemplate')
|
||||
))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key, cert_template: 'AdminTemplate' })
|
||||
end
|
||||
|
||||
it 'falls back to datastore CERT_TEMPLATE' do
|
||||
subject.datastore['CERT_TEMPLATE'] = 'UserTemplate'
|
||||
expect(icpr).to receive(:cert_server_request).with(hash_including(
|
||||
attributes: hash_including('CertificateTemplate' => 'UserTemplate')
|
||||
))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key })
|
||||
end
|
||||
end
|
||||
|
||||
context 'SAN attributes' do
|
||||
it 'includes dns SAN when alt_dns is in opts' do
|
||||
expect(icpr).to receive(:cert_server_request).with(hash_including(
|
||||
attributes: hash_including('SAN' => 'dns=host.example.com')
|
||||
))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key, alt_dns: 'host.example.com' })
|
||||
end
|
||||
|
||||
it 'includes upn SAN when alt_upn is in opts' do
|
||||
expect(icpr).to receive(:cert_server_request).with(hash_including(
|
||||
attributes: hash_including('SAN' => 'upn=alice@example.com')
|
||||
))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key, alt_upn: 'alice@example.com' })
|
||||
end
|
||||
|
||||
it 'includes both dns and upn SANs when both are set' do
|
||||
expect(icpr).to receive(:cert_server_request) do |args|
|
||||
san = args[:attributes]['SAN']
|
||||
expect(san).to include('dns=host.example.com')
|
||||
expect(san).to include('upn=alice@example.com')
|
||||
{ status: :issued }
|
||||
end
|
||||
subject.send(:do_request_cert, icpr, {
|
||||
username: 'alice', private_key: rsa_key,
|
||||
alt_dns: 'host.example.com', alt_upn: 'alice@example.com'
|
||||
})
|
||||
end
|
||||
|
||||
it 'omits SAN attribute entirely when no alt values are set' do
|
||||
expect(icpr).to receive(:cert_server_request) do |args|
|
||||
expect(args[:attributes]).not_to have_key('SAN')
|
||||
{ status: :issued }
|
||||
end
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice', private_key: rsa_key })
|
||||
context 'attributes pass-through' do
|
||||
it 'passes the attributes hash from create_csr directly to cert_server_request' do
|
||||
attrs = { 'CertificateTemplate' => 'TestTemplate', 'SAN' => 'upn=alice@example.com' }
|
||||
allow(subject).to receive(:create_csr).and_return([csr_double, rsa_key, attrs])
|
||||
expect(icpr).to receive(:cert_server_request).with(hash_including(attributes: attrs))
|
||||
subject.send(:do_request_cert, icpr, { username: 'alice' })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user