*****By Dor Segal, Security Researcher at Silverfort*****
On November 11, 2020 Microsoft disclosed CVE-2020-17049, a new Kerberos Security Feature Bypass vulnerability. While the vulnerability itself will not be fixed before February 8th 2021, Microsoft has issued patches on November 8th and December 8th in order to mitigate its exploitation in the meantime. Very little was disclosed on the vulnerability’s internal workings, with neither a public POC or a technical analysis.
This post attempts to fill some of this gap by shedding a light on Kerberos Delegation in general and deep diving into the patch Microsoft has issued for CVE-2020-17049 KCD vulnerability itself.
Kerberos Delegation 101
Kerberos Delegation is one of the most complicated concepts of Kerberos authentication process. This extension over the standard protocol was originally created for providing services, and the service accounts they use, access to resources without actually granting them any kind of permissions.
Since its initial introduction, delegation has gone through a couple of important changes until it became the Resource-based Constrained Delegation we use today (aka KCD). So, before we approach the vulnerability itself, let’s review the different types of delegation and their respective pros and cons.
Stage 1: Unconstrained delegation
Unconstrained delegation was introduced in Windows Server 2000 and was the first to allow services to impersonate a user with access permissions. As the name indicates, this kind of delegation gives a service the power to use the user’s credentials to access any resource at any time.
The process requires the user to request a forawardable TGT and attach it to the service ticket. Then, the service takes the TGT and injects it to lsass.exe local cache for later use.
Nowadays we know this method is highly risky because it grants unlimited access the delegated services, which in the case compromise – would enable the attacker to harvest all cached tickets and get full access to all their privileges.
This kind of delegation still exists today, mostly to support backward compatibility, and can be detected by querying for ADS_UF_TRUSTED_FOR_DELEGATION flag in userAccountControl attribute. This flag is also monitored by Silverfort, which reports on services using unconstrained delegation.
Stage 2: Constrained delegation
The next generation of delegation is more limited and allows the service to impersonate access only to defined resources with the flag “Account is sensitive and cannot be delegated” on Active Directory to limit specific users from impersonation.
This type of delegation is where the service performs authentication using S4U2Self and S4U2Proxy extensions (MS-SFU).
So how does it work?
Our service account must have the TRUSTED_TO_AUTH_FOR_DELEGATION flag turned on and the ms-AllowedToDelegateTo attribute that includes the resource’s SPN.
A user authenticates as usual to the service using kerberos negotiation (TGT & TGS).
Now this starts to get complicated: a delegated service account requests a forwardable TGT to itself. We used this ticket to request a service ticket using S4U2SELF using the impersonated username for our cname PA-DATA field.
The service takes this ticket, attaches it to the resource service ticket (S4U2Proxy) with the constrained-delegation flag.
The received ticket is an impersonation of the current user by our service.
Stage 3: Resource-based Constrained Delegation
The major difference in this delegation is mostly administrative.
Instead of permitting the service to be delegated access to a resources, we give the power to the resource owner to define which service is allowed to perform delegation.
This is configurable by PowerShell using the PrincipalsAllowedToDelegateToAccount parameter or simply by editing the attribute msDS-AllowedToActOnBehalfOfOtherIdentity
Microsoft Security Patch for CVE-2020-17049 – Technical Analysis
Protocol vulnerabilities are always harder to mitigate due to the required backward compatibility support.
We started looking at Microsoft’s patch by reading the information published on the official website.
We understood that the vulnerability is about “tampering tickets” and it’s located somewhere in the process of Kerberos Constrained Delegation.
We chose to simulate delegation on a vulnerable Domain Controller and reproduce it on a patched one to check the difference:
The first noticeable change is located at the length of each packet, we can see the self-signed ticket (S4U2Self) request is the same but its response is 40 bytes longer.
This also applies to the next S4U2Proxy request and response, so what has changed?
A textual comparison wasn’t helpful because the changed text is encrypted inside the ticket.
After decrypting the cipher using the service’s keytab, the text is readable but still needs to be understood.
Looking at AuthorizationData field we can see a new Unknown field, starts at offset 840 with the size of 20.
Where does this new field come from? How does KDC handle it?
What I love most about protocols is that most of them have regularly maintained and updated RFCs – and Kerberos is no exception.
Visiting MS-SFU noticed it was updated on 11/23/2020. When we opened the Diff document we learned insection 184.108.40.206.2 that there is a new signature that is used to validate the integrity of the ticket. In addition, Microsoft’s patch hints that the first modified ticket is the S4U2Self.
We extracted some more information from the RFC by looking at the reference of Ticket Signature – MS-PAC 2.8.3:
“The KDC will use KDC (krbtgt) key [RFC4120], so that other KDCs can verify this signature on receiving a PAC.”
“The ticket signature is used to detect tampering of tickets by parties other than the KDC. The ticket signature SHOULD be included in tickets that are not encrypted to the krbtgt account (including the change password service) or to a trust account.”
“corresponding to the ticket signature will contain the value 0x00000010”
The MS-PAC RFC unveiled the mystery behind the unknown field in offset 840 – its a new ticket signature, encrypted using the krbtgt key to validate its integrity.
Kerberos Bronze Bit
On December 8th an implementation of CVE-2020-17049 KCD vulnerability in Kerberos bronze bit attack was released in more detail, shedding some more light about the manipulation of the S4U2Self ticket.
The exploit deals with decrypting and editing the bit of the forwardable field inside the encRepPart of ticket.
A service with delegation ability can produce S4U2Self tickets to all users even those with ‘Account is sensitive and cannot be delegated’ flag turned on.
This flag sets the forwardable flag to False but the ticket never gets validated by KDC in case of modification.
Disclosure of new vulnerability always arouses interest among security researchers. Typically, such disclosure doesn’t involve detailed description of the entailed bits and bytes. While this might make sense from the operational perspective, it’s equally important to leverage such disclosures to get better insights into the software implementation – in this case Kerberos delegation mechanism. If Knowledge is Power, I hope this analysis has made us a bit stronger.