Inside Kerberos – 1: Overview
I recently did some work at a client to help migrate them to a new Active Directory. While setting up the migration including password and SidHistory syncs I told them to be careful of Domain Local Groups which can cause issues if users are nested directly in them. Now I knew this was true, but I couldn’t explain why… So this multi-part blog is in honour of that question…
Ultimately I’d like this series to answer the following questions:
- Why is there a problem with SIDHistory and Domain Local Groups, and exactly what is the problem?
- Why is there a 64 KB limit on tokens, and exactly what is it counting towards that size?
- Why is there a limit of 1024 groups in an Access Token and where does it become a problem?
Before we dive too deeply let’s do some level setting. Bear with me as this will be quite high level and we’ll get in the weeds in future parts.
What is Kerberos?
Kerberos allows for the authentication of service requests between trusted hosts over an untrusted network. The key benefit is that it allows you to be authenticated without storing your password, nor transmitting that password over the network. It was developed by MIT for the Athena project. Versions 1 to 3 were internal development versions only, Version 4 was the first production version and version 5 strengthened the security of Kerberos, adding things like pre-authentication. It looks like Kerberos was originally purely an authentication protocol, and Microsoft used the extensions to add authorization to that as well.
What are the main components of Kerberos?
Kerberos was the three headed dog of Hades, guardian of the gate to hell, and refers to the three parties; client, server and Key Distribution Center (KDC), which in Active Directory is the Domain Controller. These three elements work together to implement the protocol. The client and the server both trust the KDC, and the KDC holds a copy of the secret keys derived from the password of both the user and the system or service they want to try to access. The KDC splits into two main services, the Authentication Service (AS) and the Ticket Granting Service (TGS). The Authentication Service is what allows you to keep consuming services without needing to re-type your password all the time, and the Ticket Granting Service creates the information that the server needs to authorize the requests.
What are the communication flows in Kerberos?
Client sends a message to the KDC called KRB_AS_REQ, to which the KDC responds with a KRB_ERROR asking for pre-authentication which is a v5 addition to the Kerberos protocol. So the client again sends a KRB_AS_REQ to the KDC, this time with the pre-authentication information, who responds with a KRB_AS_REP. Inside that is a Ticket Granting Ticket (TGT) and a Ticket Granting Service Session Key (TGSSK) which are used in the Service Ticket flow
Service Ticket Flow
Client sends a message to the KDC called KRB_TGS_REQ, to which the KDC responds with a KRB_TGS_REP. This can either be a referral ticket to trusting realm and contain a TGT that can be used with that realm, or it is a standard response containing a Service Ticket (ST) and Service Ticket Session Key (STSK) which are used in the application flow
Client sends a message to the server called KRB_AP_REQ, to which (if mutual authentication is required) the Server responds with a KRB_AP_REP. This message is embedded in whatever protocol/application the client is trying to consume. E.g. it can be inside SQL, SMB, HTTP, etc. If mutual authentication was required then the client then uses the response to verify it is talking to the server it was expecting to before starting to make service requests. Both the Request and the Reply can optional contain a Sub Key (SK) to use to encrypt further communication, so that information is private to just that association.
Getting in the weeds
Alright so that’s Kerberos at a high level. Let’s get stuck in and explore parts of this in much more detail