It’s been a rough year for Microsoft’s Kerberos implementation. The culmination was last week when Microsoft announced critical vulnerability MS14-068. In short, this vulnerability allows any authenticated user to elevate their privileges to domain admin rights. The issues discussed in this article are not directly related this bug. Instead we’ll focus on design and implementation weaknesses that can be exploited under certain conditions. MS14-068 is an outright bug which should be patched immediately. If you haven’t patched it yet, I suggest you skip this article for now and work that issue right away. Then come back later for some more Kerberos fun!
Our red-team friends have been quite busy recently dissecting Kerberos and have uncovered some pretty concerning issues along the way. Issues, or attacks, such as the “Golden Ticket”, the “Silver Ticket”, man-in-the-middle (MITM) password cracking, and user passwords being reset without user knowledge have all been discovered, disclosed, or advanced over the past few months. These techniques can allow for credential theft, privilege escalation, and impersonation—goals in just about any advanced attack. As incident responders, these are issues we should definitely understand in order to “Know thy enemy”. So let’s get to it. We’ll start with a discussion of the Kerberos architecture and see how the placement of a compromised host impacts the security of the design.
In my previous article on network authentication, I presented the following diagram to show how Kerberos addresses the man-in-the-middle design weakness we face with NTLM:
This architecture addresses the man-in-the-middle issue for our privileged accounts that are connecting to compromised hosts. It allows the user authentication to take place between the trusted client and the DC. The DC then provides a non-forwardable, target-specific “ticket” to use for connecting to the remote compromised host. That works great for our IR account scenario, as well as many other scenarios where privileged accounts are reaching out to untrusted hosts.
However, several Kerberos weaknesses come to light when the situation gets flipped around. If we make the compromised host the client, rather than the target, then we see several issues arise. Here’s that same diagram with the scenario flipped, along with a fuller description of the Kerberos steps and a summary of the issues/attacks raised recently:
Seeing all these issues in one diagram looks pretty ominous. Fortunately these issues are not deal-breakers for Kerberos, but they should get your attention and hopefully are getting Microsoft’s attention as well.
I’m going to describe each of these issues while stepping through the Kerberos authentication process. I’ll then provide a few thoughts on mitigations. First though, let’s start with a high level description of Kerberos.
Microsoft’s implementation of Kerberos allows users (UPN: user principal names) to authenticate to services (SPN: service principal names)—such as CIFS, Terminal Services, LDAP, WS-Management, and even the local host itself (the local host is treated as a service when you perform an interactive logon with a domain account).
Authentication is first done between the user and a trusted 3rd-party called the Key Distribution Center (KDC), which is the domain controller in Microsoft domains. This initial authentication is done via the user’s long-term key, which is derived from the user’s password in most environments.
When users are ready to authenticate to services, they request a new service ticket from the KDC. That service ticket is unique to the target service and it includes identity information about the user, such as group membership, inside a structure called the Privilege Attribute Certificate (PAC). The new service ticket and a new set of temporary encryption keys, called session keys, are passed to the client and then to the service. The client and the service use the session keys to authenticate each other, as well as encrypt data between them as necessary. Once the target service receives the service ticket, it will read the included identity information about the user and make a decision as to whether the user is authorized to use the service as requested.
That’s Kerberos in a nutshell. Of course there are plenty of additional details, some of which we’ll get into shortly. However, my goal is to strike a balance between providing enough information to fully describe the problems, yet not overwhelm you with unnecessary details. For example, short-lived session keys are very important to the inner workings of Kerberos, but since they are not directly pertinent to the problems being discussed, I’m going to mostly avoid mentioning them here. If you find yourself needing more details though, two general resources I recommend are Microsoft’s article “How the Kerberos Version 5 Authentication Protocol Works” and Mark Minasi’s recorded TechEd presentation, “Cracking Open Kerberos: Understanding How Active Directory Knows Who You Are”.
Microsoft Kerberos Step-by-Step
Now that we’ve covered the basics, let’s dig deeper and look at each step of a typical Microsoft Kerberos transaction. Along the way, we’ll also discuss the weaknesses that provide avenues for attack.
Step 1–Authentication Service Request (AS-REQ): The user initially authenticates to the KDC’s authentication service (AS) for a special service ticket called a ticket-granting ticket (TGT). This most commonly occurs when the user initiates an interactive logon, though it can happen in other situations too. This initial request encrypts the current UTC timestamp of the format YYYYMMDDHHMMSSZ with a long-term key. In password-based environments, the long-term key is derived from the user’s password.
Multiple encryption types are normally available. The client should choose the strongest mutually-supported encryption type, but of course an attacker can produce a downgrade attack to choose weaker encryption. Here’s a brief summary of possible encryption types:
- DES-CBC-CRC (disabled by default in Vista/2008)
- DES-CBC-MD5 (disabled by default in Vista/2008)
- RC4-HMAC (XP & 2003 default, as well as the strongest encryption they support)
- AES128-CTS-HMAC-SHA1-96 (introduced with Vista/2008)
- AES256-CTS-HMAC-SHA1-96 (default in Vista/2008 and higher)
When a user logs in, Windows will create a long-term key for each encryption method supported by the client OS. Let’s take a look at the long-term keys for user ‘mike’ on a Windows 7 host that supports both the newer AES and older RC4 algorithms:
In last week’s article, we calculated user mike’s NT hash, which is simply the MD4 hash of the user’s Unicode password. Here it is again—and notice that the hash value is the same as the RC4 long-term key:
$ echo -n Use4Passphrase,K? | iconv -t UTF-16LE | openssl md4
As you can see, Microsoft uses the NT (NTLM) hash for Kerberos RC4 encryption. Crazy, huh? Why is this the case? Apparently it was to support a more seamless upgrade from NT4 (NTLM/LM only) to Windows 2000 (the first version to support Kerberos).
The fact that an NT hash can be used to create Kerberos tickets leads to the ability to do something Benjamin Delpy, the creator of mimikatz, has termed “overpass-the-hash”. The idea being, you can do more in Kerberos with the NT hash than you can from a standard pass-the-hash attack that utilizes NTLM. The ability to use the NT hash to create Kerberos tickets opens up a few additional possibilities that can only be done via Kerberos, such as changing a user’s password and joining a machine to a domain. In fact, the ability to change a password without the user’s knowledge using the NT hash caused a stir this summer following this disclosure by Aorato. Once an attacker has changed the password, they have at least a small window of opportunity to use services like Remote Desktop and Outlook Web Access that require the password.
Step 2–Authentication Service Response (AS-REP): Assuming the client encrypted the timestamp correctly in Step 1, and the time is within the accepted skew (5 minutes by default), then the user will have passed authentication. The KDC then constructs a special service ticket, called the ticket-granting ticket (TGT), to be used when requesting other service tickets from the KDC’s Ticket-Granting Service (TGS). Like all service tickets, the TGT includes identity information about the user, including username and group memberships.
Also like all service tickets, the TGT is encrypted with the target service’s long-term key. By encrypting service tickets with the destination service’s long-term key, this protects the information in the ticket from being read or modified since only the KDC and target service know the long-term key. In the case of the special TGT service ticket, the target service account is the built-in ‘krbtgt’ account.
An interesting feature of Kerberos is that authentication is effectively stateless. In subsequent communications with the user, the KDC only knows that it previously authenticated this user because the TGT that the client will send in Step 3 has been encrypted with its ‘krbtgt’ account. Once the KDC receives that encrypted TGT again, it trusts that the user must have previously authenticated and that all the included user and group information in the encrypted ticket is accurate. This is by design so that any DC in the domain can process subsequent requests without the need to synchronize authentications across all DCs. To a certain extent, it also does not have to spend additional cycles to look up the account information again as long as the ticket is valid (10 hours by default). There is a caveat to this though. Since it would be dangerous to assume for 10 hours that a user has not been deleted, disabled, or modified, the KDC will re-verify the account information if the TGT is more than 20 minutes old.
Let’s take a look at the user’s identity information embedded inside an encrypted ticket. The following screenshot is from a Powershell Remoting (WS-MAN) session that was captured and parsed with Wireshark:
What’s being parsed here is the Privilege Attribute Certificate (PAC) information. This has all the necessary information that allows the target service to determine if the user has the proper privileges to perform the requested action. In this example, user ‘mike’ is just a member of Domain Users, well-known group RID 513.
It’s worth noting again that the information in the ticket, including this PAC data, was created by the KDC and encrypted with the target service’s long-term key—a key that only the KDC and the target service account know. In order to parse these details in Wireshark, it’s necessary to provide Wireshark with the target accounts long-term Kerberos key, as shown here:
In case anyone wants to try this, what worked for me was using the Linux version of Wireshark (I could not get the PAC to parse in Windows Wireshark) and create the necessary keytab file with the Linux tool ktutil. More details on parsing Kerberos encrypted data can be found on Wireshark’s Kerberos page and this SAMBA presentation by Ronnie Sahlberg. (Thanks to Tim Medin for some guidance here!)
Step 3–Ticket-Granting Service Request (TGS-REQ): Now the client would like access to a service and it needs a new service ticket to do so. The client double-checks that its TGT is still valid (not expired) and if so, it sends a request to the ticket-granting service on the KDC. The request includes the user’s TGT and the specific service principal name that it would like to access. Assuming the TGT is properly encrypted with the ‘krbtgt’ account’s long-term key, and the TGT is less than 20 minutes old as previously mentioned, then the KDC’s ticket-granting service will assume this is an authentic request for an authentic user whose identity details are specified in the PAC inside the ticket. It will then continue to Step 4 to create the service ticket.
Now consider this: What if an attacker has the long-term key for the ‘krbtgt’ account? Well, in that case the attacker can create a TGT, put anything they want in it, and pass it to the KDC. If it’s less than 20 minutes old, then the TGT is treated as fact—the KDC believes it describes an authenticated user with the attributes described in the PAC details. This describes the “Golden Ticket” attack. It’s a ticket created by an attacker with the ‘krbtgt’ key that can give any user any rights (via group membership). In fact, it doesn’t even have to be a real user. It can be a fictitious username with domain admin membership, or any other membership the attacker chooses to give it. As long as the ‘krbtgt’ key is valid and the crafted TGT is less than 20 minutes old (and if it’s not, the attacker can simply create a new one), then the KDC will issue a service tickets for that user with the specified group membership. Here’s an example of creating a Golden Ticket for non-existent user ‘bevo’ with domain admin membership via well-known group RID 512:
Assuming I supplied a valid key for the ‘krbtgt’ account, I can get a service ticket to connect to any service in the domain as a domain admin. Furthermore, the fictitious user named ‘bevo’ is the name that would show up in the remote event logs!
The thing that makes this attack particularly devastating is that the password, and resulting keys, for the ‘krbtgt’ account almost never change. In fact, research has shown that there is “only one circumstance where this password automatically changes. The password for the KRBTGT account only changes when the domain functional level is upgraded from a NT5 version (2000/2003) to a NT6 version (2008/2012). If you move from 2008 -> 2012R2 domain functional level, this hash won’t change.”
This opens up a can of worms for organizations that have previously had their domain compromised and credentials dumped from a domain controller. Or perhaps had the Active Directory data get out of their control via an old backup, or DC VM archive, or even an attack they are unaware of.
The takeaway is that if you are responding to a potential domain compromise and see unusual activity, perhaps even from non-existent users, then the Golden Ticket could possibly be in play. Furthermore, if you’re in a situation where you need to reset the ‘krbtgt’ account for recovery, be sure to change it twice, as described here and here. Probably the better course of action is to leave the old domain for dead and move to a new pristine domain/forest, but unfortunately that’s not always feasible.
Step 4–Ticket-Granting Service Response (TGS-REP): Once the TGS examines and verifies the TGT, it creates the requested service ticket. The client’s identity from the TGT is copied into a PAC in the new service ticket. Then the new service ticket is sent to the client, who will then pass it on to the target service.
The new service ticket is encrypted with the target service account’s long-term key and the embedded PAC is signed by the ‘krbtgt’ account for verification in optional Step 6. In most cases, the target service account is the computer account for the remote service. This is true for common services such as CIFS, RPC, Scheduler, WS-MAN, and many more. However, the target service account could be a dedicated domain user account used to run the service.
It’s interesting to note that the KDC cannot determine if the user will be able to get access to the target service. It simply returns a valid ticket. Authentication does not imply authorization. Authorization is determined by the target service based on the user and group information in the PAC.
There is no obstacle to requesting service tickets other than having a valid TGT. A user can request service tickets to any service in the domain. Again, the KDC doesn’t know if the user is authorized for the service—that’s up to the service to decide—so it happily issues tickets for any valid request it receives. For a large domain, there could be thousands, perhaps even millions of services, as each host typically has a few SPNs. Check for yourself with the command “setspn –l <account-name>”. The <account name> should be either a computer name or dedicated user account for hosting services.
Why would this be of interest? Since the service ticket is encrypted with the service account’s long-term key, an attacker can gather service tickets and attempt a brute-force attack on the long-term key that was used to encrypt the ticket. If the key can be derived, then there’s potential to elevate privileges via the “Silver Ticket” attack (more on Silver Tickets in Step 5). The attacker could also take the cracked key and connect to other hosts on the network if the service account has sufficient rights.
By the way, when discussing Kerberos cracking via MITM, I use the terms password and key almost interchangeable. This is because the most efficient way to crack the key that created the Kerberos ticket is to start with a dictionary attack against the password that created the Kerberos encryption key. So yes, the MITM attack is cracking the key, but it typically involves first guessing the password that created that key.
For most service accounts, brute-force cracking the password and resulting key is very difficult because they belong to the built-in computer account. The password for computer accounts is very complex and highly unlikely to be cracked, regardless of RC4 or AES encryption. However for some services, the service does not use the built-in computer account to run the service, but instead uses a dedicated domain user account. Tim Medin has done a lot of research in this area and has found that MS-SQL services are particularly vulnerable to attack because they are typically configured with a domain account rather than a computer account. Furthermore, many blogs suggest that the quick way to get the job done is to give the MS-SQL service account domain admin rights. Yikes!
Whether given domain admin rights or not, what is the chance that this dedicated MS-SQL account, or any other domain service account, was given a strong password? Probably a good chance in some environments and a poor chance in others. If the password is poor, then the password and resulting Kerberos key can be cracked–period. It can be cracked faster if the encryption type is RC4 rather than AES since the Kerberos AES function requires much more computational efffort to generate a guess than RC4. Therefore, along with the “overpass-the-hash” issue described in Step 1, MITM vulnerabilities provide another incentive to decommission RC4 encryption in favor of AES.
Definitely check out the work by Tim Medin on this issue. He did a great presentation at DerbyCon where he goes through this in great detail. He also debuts his toolset called Kerberoast, which among other things, provides a tool to crack the Kerberos TGS-REP responses. He also shows how the discovered password/long-term key can be used to create a Silver Ticket, which I’ll describe in the next step.
Step 5–Application Server Request (AP-REQ): Once the user receives the service ticket, it’s ready to forward on to the target service. The service will decrypt the ticket with the service account’s long-term key. After it decrypts the ticket, it will check the user’s information within the PAC. Based on the account information, the service decides whether or not to authorize the user to perform the requested action.
At this point, the service could proceed to optional Step 6 to validate the PAC information with the KDC. Only the KDC can validate the PAC because the validation occurs via a signature with the ‘krbtgt’ account. Ideally this validation would happen to verify that user information is accurate, but it rarely does due to the performance impact. The validation exceptions are discussed in a number of places, such as the Technet article “Understanding Microsoft Kerberos PAC Validation” and the previously mentioned 20-minute rule article. In a nutshell, as Tim put it in his DerbyCon presentation, “Basically, if it runs as a service, it will not verify”. My own testing backs this up. I’ve yet to find a way to get services that “Act as part of the operating system” (of which most do) to validate, even with the ValidateKdcPacSignature value is set to 1 in the registry as described in the above Technet article.
So is it problem if the service doesn’t verify the PAC information? Yes, it is a problem if the service account’s long-term key can be discovered (for example, via the MITM attack discussed with Step 4). If an attacker discovers the long-term key, a service ticket can be crafted that the service will decrypt and trust as long as it doesn’t verify the PAC with the KDC. What if an attacker creates a service ticket that says the connecting client is a member of the domain admins group? If the ticket is encrypted with the service’s long-term key, and the service doesn’t verify the PAC data, then it assumes it to be true and will grant access to the connecting user as though they were a domain admin. This is the “Silver Ticket”.
Why doesn’t Microsoft always verify? For performance reasons. From the Technet article referenced above, “Performing PAC validation implies a cost in terms of response time and bandwidth usage. It requires bandwidth usage to transmit requests and responses between an application server and the DC. This may cause some performance issues in high volume application servers (KB906736). In such environments, user authentication may induce additional network delay and traffic for carrying PAC validation messages between the server and the DC.”
Step 6—Verify Service Ticket PAC (Optional) (VERIFY-PAC): As just discussed, the service has the option to send the PAC information to the KDC to verify the ‘krbtgt’ account’s signature. This ensures the KDC created the service ticket. This can be enforced, but it rarely is for performance reasons.
Step 7–Application Server Response (Optional) (AP-REP): Optionally, the user might have requested in Step 5 that the target service verify its identity for mutual authentication. If so, the service encrypts a timestamp with the session key that only the user and service should know and sends it back to the user for verification.
I’m going to mention just a few things here, and also refer you to a great resource with many more suggestions for hardening your Windows environment. The paper “Mitigating Service Account Credential Theft on Windows” by HD Moore, Joe Bialek, and Ashwath Murthy provides a very good discussion of the problems we face with privileged accounts, along with a significant list of recommendations beginning on page 8 of the 13 page paper.
Of the Kerberos issues discussed here, the Golden Ticket issue is the most concerning. Of course it’s concerning if you know your domain controller was compromised and AD credentials were dumped. Unless the ‘krbtgt’ account was reset twice, then consider that domain to still be compromised. Furthermore, it’s also concerning if you don’t know if your domain controller was compromised. What if there are indications of compromise, but no solid proof? What if there aren’t even any indications? Does that mean it hasn’t happened and that it’s okay to keep this almighty ‘krbtgt’ password unchanged for years and years? That goes against one of our primary security principles—the idea that we should refresh passwords regularly in order to avoid exposure from stolen credentials. I hope Microsoft addresses this by forcing a password rotation scheme for the ‘krbtgt’ account. In theory it should not be a problem. The reason you have to change this account’s password twice to invalidate the current password is because there is a built-in fault tolerance to allow for the previous password to still work. So it should be possible to frequently rotate in new passwords/keys. At least that way a compromise (known or unknown) does not last effectively for years.
Regarding the Silver Ticket issue, always enforcing PAC validation doesn’t currently appear to be a feasible solution. Therefore, the best bet here is to do something you’d want to do anyway—enforce very strong passwords for your service accounts to mitigate the MITM attack. Probably the best ways to do that is to use Microsoft’s Managed Service Account feature, which among other things rotates strong passwords every 30 days for designated service accounts.
Lastly, to help address both the MITM and “overpass-the-hash” issue, disable the older RC4 encryption method if possible. This makes brute-force MITM attacks more time consuming and prevents the NT hash from being used to create Kerberos tickets. From a Windows perspective, this can be done via Group Policy after all XP and 2003 systems have been decommissioned.
Mike Pilkington is a Sr. Information Security Consultant and Incident Responder for a Fortune 500 company in Houston, TX, as well as a SANS instructor teaching FOR408 and FOR508. Find Mike on Twitter @mikepilkington.