Inside Kerberos – 6: Conversations

We have covered a lot of ground so far, and we have touched on the Kerberos conversations that go on, but let’s take a deeper look at exactly how these messages are made up and how they are protected.

Elements to protect the transmission

Secret Keys

Secret keys are stored inside the Security Account Manager (SAM) database on the Domain Controllers. The following keys are stored based on passwords using a One Way Hash function. The secret keys in Active Directory include:

User Key

krbtgt Key

Service Key

Trust Key

Session Keys

Session keys are generated by one party and security transmitted to another party, often secured using a secret key. Session keys are not stored long term and are only used between a given set of actors. The session keys used by Kerberos include:

TGS Session Key

Session Key

Application Sub-key

Application Reply Sub-key

Encryption

Most often we see Kerberos communication protected by AES256 based encryption, which is negotiated between the KDC and the client. However, by default Windows Domain Controllers support RC4 as an encryption method, and the bad thing about this is that the encryption key is the NT Hash itself… This means that anyone with another user’s NT Hash can get a Kerberos ticket as that user and therefore access any resources as that user.

As long as you don’t have any pre-Vista/2008 OSes and you don’t have any applications that rely on RC4 then you can look to disabled this via Group Policy (Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options > Network Security: Configure encryption types allowed for Kerberos) Note that DES is disabled by default since Windows 7, Windows 2008, however RC4 is still available.

Of course before you make this change in production you need to test this change in a non-production environment first.

Network Flows

Authentication Service

The Authentication Service flow is part of the KDC and is all about surprise, surprise… authentication. This flow verifies the user and returns to them the TGT and the TGS Session Key. Picking this flow a part we see:

1. Client to KDC – KRB_AS_REQ

The client locates a KDC for it’s own realm and creates a KRB_AS_REQ message. This initial message contains:

The KDC uses it’s stored value of the user’s secret key to decrypt the pre-authentication data and validates that it is correct (in the case of a timestamp it needs to be within the tolerance set for Active Directory) Assuming the validation succeeds then a KRB_AS_REP is constructed with the following main fields:

padata structure for encryption info, informing the client the encryption method and the salt used

crealm: the user’s FQDN

cname: left part of the user principal name

ticket: the TGT, which includes the krbtgt service and realm of the issuer as well as information encrypted with the krbtgt secret key

enc-part: the TGS Session Key, and information about the TGT as well as the original nonce, all encrypted with the user’s secret key. The client uses this information to validate the TGT as well as cache the TGT and TGS Session Key

At the end of this conversation the client has a TGT that is encrypted with the krbtgt secret key, and a TGS Session Key that can be used to secure the Ticket Granting Service flow.

Ticket Granting Service

The Ticket Granting Service flow is also part of the KDC and I bet you can guess what this is aiming to do… Grant Tickets to Services. This flow verifies the TGT and returns to user the ST and the Session Key. Picking this flow a part we see:

1. Client to KDC – KRB_TGS_REQ

The client locates a KDC in its own realm and looks up the TGT and TGS Session Key in its cache. If not found then it starts an Authentication Service flow first. Once it has the TGT and TGS Session Key then the KRB_TGS_REQ is crafted with the following main fields:

padata structure with a PA-TGS-REQ structure which in turn includes:

the TGT

an authenticator (encrypted with the TGS Session Key). This authenticator includes:

crealm: the user’s realm

cname: the left part of the user principal name

cksum: A checksum of the req_body structure below

cusec/ctime: time information to prevent replaying

subkey: The client can optionally add an encryption key to use for any responses

req_body structure including:

kdc-options: forwardable, renewable, canonicalize

realm: the realm we’re trying to contact

sname: the service principal name for the service we’re trying to consume

till: The ideal duration of the Session Ticket (set to around 20 years)

nonce: a random value generated by the client

etype: an ordered list of preferred encryption types

2. KDC to Client – KRB_TGS_REP (in this case a cross-realm referral)

The response the KDC gives depends on whether the service principal is in it’s own domain or a trusting domain. In this case we’re assuming that it is in a trusting domain, and so the KDC returns a referral, which includes:

crealm: the user’s realm

cname: the left part of the user principal name

ticket: a TGT with realm and sname set to the krbtgt service and FQDN to contact next, as well as information encrypted using the trust secret key

enc-part: the TGS Session Key, and information about the TGT as well as the original nonce, all encrypted with the subkey from the KRB_TGT_REQ (if present) or the user’s secret key. The client uses this information to validate the TGT as well as cache the TGT and TGS Session Key

3. Client to KDC – KRB_TGS_REQ

Given that we got a referral a new KRB_TGS_REQ is created to be sent to the krbtgt we got in step 2, with the following main fields:

padata structure with a PA-TGS-REQ structure which in turn includes:

the TGT (from step 2) but with realm set to the user’s realm (so that the receiving KDC knows which trust secret key to use to decrypt)

an authenticator (encrypted with the TGS Session Key). This authenticator includes:

crealm: the user’s realm

cname: the left part of the user principal name

cksum: A checksum of the req_body structure below

cusec/ctime: time information to prevent replaying

subkey: The client can optionally add an encryption key to use for any responses

req_body structure including:

kdc-options: forwardable, renewable, canonicalize

realm: the realm we’re trying to contact

sname: the service principal name for the service we’re trying to consume

till: The ideal duration of the Session Ticket (set to around 20 years)

nonce: a random value generated by the client

etype: an ordered list of preferred encryption types

4. KDC to Client – KRB_TGS_REP

Assuming the TGS Request validates, i.e. ticket is valid, authenticator can be decrypted, cksum matches the req_body, then the KDC creates a KRB_TGS_REP and returns to the client the following fields:

crealm: the user’s realm

cname: the left part of user principal name

ticket: the Service Ticket with realm and sname set to the service we’re trying to contact, and information encrypted using the service secret key

enc-part: The Session Key and information about the Service Ticket as well as the original nonce, all encrypted using the subkey in the request (if present) or the user’s secret key. The client uses this information to validate the response and cache the Service Ticket and Session Key

Application

The application flow is embedded within whatever application the user is trying to access. In the screenshot below we’ve requested access to an SMB share

The Server validates the ticket, decrypts the authenticator and assuming the user is authorized then it will reply with an SMB Session Response which again includes a GSS-API structure, this time encrypted either using the Session key, or using the subkey from the request:

cusec/ctime: returned from the client’s request (to validate that the server was the one how managed to decrypt the authenticator)

subkey: an optional server generated encryption key to use for all future communication in this session

Twan is a senior consultant with over 20 years of experience. He has a wide range of skills including Messaging, Active Directory, SQL, Networking and Firewalls. Twan loves to write scripts and get deep and dirty into debugging code, in order to understand and resolve the most complex of problems.

Nero Blanco IT Limited is a company initially formed by highly skilled and experienced independent contractors who saw a problem with how large technology migration and consolidation programs were undertaken.