Defused That SAN Flag!

In May, Microsoft has fixed a bug that allowed normal users to impersonate Domain Controllers. This bug allowed non-privileged users to obtain a logon certificate issued to a domain controller, because users can write to the Active Directory attribute dnsHostNameof a computer they have joined to the domain. If a machine can enroll for a certificate with naming attributes coming from AD (common 802.1x certificate config), and if this name was change to that of a domain controller, the client computer effectively ‘becomes a domain controller account’ when logging on with that certificate.

Microsoft did neither change write permissions to that attribute nor change anything related to the domain join process. They went for demanding a ‘stronger’ mapping between certificates and user / computer objects. As I’ve demonstrated on this blog again and again and again, a user principal name (or for a computer: a fully qualified DNS host name) in a certificate has been sufficient to allow for logging on with that certificate. This applies to – for example – smart card logon, 802.1x network logon using Microsoft NPS as a radius server, or logging on to web applications on IIS with AD cert mapping enabled.
But Applying the May 2022 security update to an AD-integrated (Enterprise) Windows Certification Authority (ADCS), the CA will add a new certificate extension to every certificate whose naming attributes are built from AD attributes. The new attribute has an object ID not (yet?) resolved into a friendly name, and its value contain the security identifier (SID) of the account requesting the certificate. (There are also other string mapping options, such as adding a Serial Number of a certificate manually, as a name mapping in AD, see the MS support article for details.)

A domain controller with May updates applied will check that SID attribute when a user or machine logs on with a mapped certificate. For now, also the old certificates – without SID – are still considered valid, but a warning is logged in the system event log. Next year in May, so-called Full Enforcement mode will be turned on, and logon certificates without SID will not be considered good enough. So, the big impact of this updates is:  If you use certificate for logon of AD users or computers: Renew all logon certificates before May 2023 (E.g. by using the Re-enroll all certificate holders function of a certificate template).

But there is an interesting ‘side effect’. Maybe it explains in part why Microsoft chose to fix the bug in this way (pure speculation) – instead of changing the domain join process or permissions on computer objects:

The flag EDITF_ATTRIBUTESUBJECTALTNAME2 has also been defused, sort of!

This flag allows to add custom Subject Alternatives Names (such as UPN or DNS name) to *any* certificate, even those configured for names coming from Active Directory. Unfortunately, the flag had been quite popular among web server administrators. Without this flag, you need to resort to a more involved post-processing of requests in the queue or maybe third-party tools. I proposed to use certutil -extensions recently, as a replacement for the flag.

With May 2022 updates applied *and* flag EDITF_ATTRIBUTESUBJECTALTNAME2 active, you can still maliciously add a UPN via the /certsrv web application to a template that ‘should actually be auto-enrolled’. The ‘evil’ UPN is replacing the UPN of the true requester. But the CA is now adding the new extension for the SID, which prevents the requester from impersonating an administrator!

Demo:

Create a key a key pair and certificate request using (e.g.) openssl, certmgr.msc, certreq. I used the Certificates MMC certmgr.msc to create a custom PKCS10 request file, added a silly non-standard Common Name but no SAN. The resulting request looks like this:

C:\TEST>certutil no-upn.req.txt
PKCS10 Certificate Request:
Version: 1
Subject:
CN=No UPN in the CSR
Name Hash(sha1): 2a474f6c9532bd563ae142717477f64de056abc4
Name Hash(md5): 371ef17a1b2f856cdb5814ac09c1bb8c

Public Key Algorithm:
Algorithm ObjectId: 1.2.840.113549.1.1.1 RSA (RSA_SIGN)
Algorithm Parameters:
05 00
Public Key Length: 2048 bits
Public Key: UnusedBits = 0
0000 30 82 01 0a 02 82 01 01 00 cf cb d9 07 24 d0 0f
0010 b9 f8 79 13 47 a1 3f 8c 4f 33 c0 28 be 8e c3 62
0020 53 cb 43 a2 fc 01 df d3 59 0e a7 72 1d ad 86 c3
0030 c8 9f 5e cc 31 1b ad a2 56 d2 f5 5e c2 67 80 96
0040 35 79 54 a1 3d db a8 ce 22 5b 2a 6b 2f 80 e2 b5
0050 20 cd aa d4 a8 0d 38 7a 98 8e 9c d0 cc 9b 9e 90
0060 c5 50 4c cf 49 e3 77 84 56 8b e7 fb 8b 6f 89 2a
0070 ba bc f8 ec e7 ce b6 bd d9 f5 04 ab 84 2d 00 ea
0080 c5 05 7a e6 36 0c 5c 3f c5 c6 c3 2c a2 7d a9 f3
0090 36 3e d6 91 01 f5 ab 37 08 24 c0 6b 19 1b ef 24
00a0 58 6e a1 96 ce f6 98 52 78 2d 0f a8 65 f9 f9 f0
00b0 99 7a fc 92 ee 1d 13 ac 06 d7 18 88 c2 2c 85 da
00c0 31 c9 d4 80 cf 88 a4 aa b1 9f 04 6f 00 ed 62 ff
00d0 d4 9d a8 d7 cb 59 ab ea fb a3 91 51 42 22 10 97
00e0 b8 23 1f b8 28 e5 f5 bb 9e e4 66 2c a4 e6 53 be
00f0 8e 5f ae 94 29 68 8a d1 c0 48 6e 55 fa 47 6d dc
0100 ce 3c c9 42 66 7b 89 62 35 02 03 01 00 01
Request Attributes: 4
4 attributes:

Attribute[0]: 1.3.6.1.4.1.311.13.2.3 (OS Version)
Value[0][0], Length = e
10.0.20348.2

Attribute[1]: 1.2.840.113549.1.9.14 (Certificate Extensions)
Value[1][0], Length = 21
Certificate Extensions: 1
2.5.29.14: Flags = 0, Length = 16
Subject Key Identifier
f76611403821353e1d37a3c0961715c91bfde569

Attribute[2]: 1.3.6.1.4.1.311.21.20 (Client Information)
Value[2][0], Length = 2c
Client Id: = 5
ClientIdDefaultRequest -- 5
User: PANIC\webadmin
Machine: virus.pan.ic
Process: MMC.EXE

Attribute[3]: 1.3.6.1.4.1.311.13.2.2 (Enrollment CSP)
Value[3][0], Length = 58
CSP Provider Info
KeySpec = 0
Provider = Microsoft Software Key Storage Provider
Signature: UnusedBits=0
Signature Algorithm:
Algorithm ObjectId: 1.2.840.113549.1.1.11 sha256RSA
Algorithm Parameters:
05 00
Signature: UnusedBits=0
0000 8a 3a 77 56 27 fe 26 e2 06 44 df 2f c1 f4 8c 75
0010 2d 89 cd 9d fd 1c 1c 8d d3 23 48 66 27 16 1b 72
0020 c4 af c8 e3 00 5f dc c2 7c 7a b2 d6 21 1e 4f 27
0030 ce 55 c6 86 f3 6f c9 94 97 f3 7e 2e 91 0c 7b 88
0040 61 24 b4 ca c9 12 01 e1 76 54 c9 55 ae de 37 6d
0050 c9 70 40 b1 3e ea 1f 3b dc 76 54 d9 3f 65 da 2f
0060 69 21 77 80 b5 e6 ee 0c 10 c6 84 c6 05 87 bc 07
0070 28 fd ee a2 58 c9 ac 6a 3b e9 b5 37 2b b1 56 99
0080 ec da 3f 1d e3 57 4e d4 c4 53 6c cd a4 38 55 bf
0090 3d 20 37 20 f7 b1 2d c7 6a 0d 73 61 a2 63 99 76
00a0 63 7e 3d 3a 7c ca ce 77 9a db 02 a1 96 2a 3d 61
00b0 e0 6a b9 d5 58 1a a5 a1 93 c0 f5 04 70 61 5f 1b
00c0 5d 1e 51 27 03 53 64 0f a4 d2 53 3a 28 0f 02 84
00d0 3d c5 4d 8f 84 b9 85 d9 60 79 24 89 12 67 e8 07
00e0 aa a2 5a 94 64 a1 99 e4 dc 88 d5 50 80 6f b8 da
00f0 a6 92 99 a7 e2 db 20 30 0f 4c bf 2d dd c1 81 42
Signature matches Public Key
Key Id Hash(rfc-sha1): f76611403821353e1d37a3c0961715c91bfde569
Key Id Hash(sha1): 38783664c43762c48af5e3eb523ae28f10d31066
Key Id Hash(bcrypt-sha1): 5cbf84779f3ea073acdbfbcdbfca6a6ed7d2d1c4
Key Id Hash(bcrypt-sha256): a46d156a0a04f87292c5d34de3c723b7e704149c4f291285907cbf16db29183c
CertUtil: -dump command completed successfully.

Windows also adds a request attribute that denotes the requesting user (PANIC\webadmin) – but this is not what is important for the checks that follow. This webadmin user does not have any special AD permissions.

The user submits this certificate signing request (CSR) as a request for a User template – a standard template that makes the CA pull attributes from AD. I am picking this old (v1) template, as it belongs to the set of templates automatically published if you install a next-next-finish CA. A typical certificate intended to be auto-enrolled would be a v2 template created by copying (e.g.) this template. Even though the ‘intended’ way of enrollment is auto-enrollment or ‘next-next-finish’ MMC enrollment (without changing any attributes), nothing prevents a user from creating key pair and request (CSR) offline – and submitting the CSR file manually.

The ‘evil webadmin’ adds a UPN using enrollment app /certsrv. The UPN is added to the attributes form field as SAN:upn=administrator@[domain].

Windows ADCS, /certsrv. Submit CSR with custom UPN.

When issuing the certificate the CA …

1) … overwrites the silly CN with the one of the requester (Web Admin):

Certificate issued to non-privileged user, CN from AD

2) … adds the malicious UPN instead of the true one (webadmin@pan.ic):

Certificate issued to non-privileged user, UPN added by user

3) … adds the new SID attribute

Certificate issued to non-privileged user, SID added by CA

Checking the SID – yes, that’s webadmin’s!

C:\TEST>whoami /all

USER INFORMATION
----------------

User Name SID
============== ============================================
panic\webadmin S-1-5-21-1468012755-800561317-457473099-1104

...

Now the user tries to logon with this certificate – and logon fails because the SID does not match the UPN. For a quick logon test I use the ASP application I showed in my post about  IIS certificate mapping.  I get the certificate prompt, pick this certificate – and get HTTP Error 401.2 - Unauthorized.

This usually means that I have an error in the mapping config :-) But this time the DC will tell us exactly what happened. Event 41 is recorded at the DC, in the system event log:

The Key Distribution Center (KDC) encountered a user certificate that was valid but contained a different SID than the user to which it mapped. As a result, the request involving the certificate failed. See https://go.microsoft.com/fwlink/?linkid=2189925 to learn more.

User: Administrator
User SID: S-1-5-21-1468012755-800561317-457473099-500
Certificate Subject: @@@CN=Web Admin, OU=Let's Hack, DC=pan, DC=ic
Certificate Issuer: Panic CA
Certificate Serial Number: 4B00000023F6445390D0D6D4EE000000000023
Certificate Thumbprint: 47F6F9BAB4AD3F0EB93F35F4D95B964FD39B20B0
Certificate SID: S-1-5-21-1468012755-800561317-457473099-1104

So that’s what I mean by having defused the flag!

Note that you can still ‘hack a UPN’ if you have enroll access to a template not configured for names coming from Active Directory. The CA does not embed a SID attribute into such certificates, and they look like any ‘old’ logon certificate issued before May 2022. logon is still possible now in compatibility mode – for now! But this will change in one year latest!

Recorded event 39 in this case:

The Key Distribution Center (KDC) encountered a user certificate that was valid but could not be mapped to a user in a secure way (such as via explicit mapping, key trust mapping, or a SID). Such certificates should either be replaced or mapped directly to the user via explicit mapping.

So, it’s recommended turn off the SAN flag even though the update has been applied.

I would handle the May update like this:

  • Check that all CAs have been patched by checking the SID attribute is added to logon certificates with names from AD now.
  • Watch out for the Kerberos errors in the system event log of DCs. If you see warnings, then certificates are used to logon, and certificates with validity periods greater that a year will not be accepted in the future.
  • Re-enroll all certificate holders to replace all logon certificates.
  • If Kerberos warnings have ceased, turn on Full Enforcement before Microsoft does.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.