Why Kerberos

Kerberos is a network authentication protocol, version 5 of which is defined in RFC 4120, in which a trusted third party issues encrypted, time-limited tickets that let a user prove their identity to services without ever sending a password over the network. Active Directory has used it as its default authentication protocol since Windows 2000; Linux and macOS speak it too, and the same protocol runs in MIT Kerberos and in FreeIPA (see Linux and Identity).

Kerberos was designed around three goals:

  • No passwords on the wire. The password is turned into a key on the client, and only things encrypted with that key travel. Someone capturing traffic does not get the password.
  • Sign in once. After the first exchange, the client gets access to many services without asking the user again: the single sign-on of a Windows domain.
  • Mutual authentication. The client can verify that it talks to the real service, not an impostor, because only the real service can decrypt its ticket.

The actors

A Kerberos exchange has three parties: the client (a user or computer), the service it wants to use (a file server, a web application, a database), and the key distribution center (KDC), the trusted service that knows the long-term keys of all accounts in a realm and issues tickets with them. The KDC has two parts: the authentication service (AS), which checks who the user is, and the ticket-granting service (TGS), which hands out tickets for individual services.

In Active Directory, every domain controller runs a KDC, listening on port 88; clients find one through DNS (see DNS and Active Directory). The Kerberos realm is the domain name in capitals, AD.EXAMPLE.COM. Every account's long-term key is derived from its password; the KDC itself uses the key of a special account, krbtgt. Whoever obtains the krbtgt key can forge tickets for anyone (a "golden ticket", MITRE ATT&CK T1558.001), which is why DCs are the most protected systems in a domain and why incident response after a domain compromise includes resetting the krbtgt password twice. Attacks and their detection are covered on Attacks on Identity.

The Kerberos exchange step by step

Lucía, a billing clerk, signs in to her laptop in the morning and then opens \\fs01\billing. Behind the scenes, three exchanges take place:

Kerberos sequence between the client, the KDC's authentication service and ticket-granting service, and a file service. 1: the client sends an AS request with preauthentication. 2: the authentication service returns a ticket-granting ticket. 3: the client sends a TGS request with the TGT and the service principal name. 4: the ticket-granting service returns a service ticket. 5: the client sends an AP request with the service ticket to the service. 6: the service optionally replies to prove its own identity. Client KDC on a domain controller AS TGS Service (fs01) 1 AS-REQ (preauth) 2 AS-REP: TGT 3 TGS-REQ: TGT + SPN 4 TGS-REP: service ticket 5 AP-REQ: service ticket + authenticator 6 AP-REP (optional): mutual authentication
Steps 1–2 happen once per sign-in; steps 3–4 once per service (the tickets are cached); step 5 on each new connection. The service never contacts the KDC itself.

1–2: Getting a ticket-granting ticket

The client sends an AS-REQ to the authentication service. With Kerberos preauthentication, the client includes the current time encrypted with the key derived from the user's password, so the KDC can verify that the requester knows the password before it returns anything encrypted with that key. Preauthentication is on by default in AD. An account with the "Do not require Kerberos preauthentication" flag lets anyone request a reply for it and try to crack the password offline (AS-REP roasting, T1558.004). Find such accounts and remove the flag:

Get-ADUser -Filter 'DoesNotRequirePreAuth -eq $true' | Select-Object SamAccountName

If the timestamp checks out, the KDC answers with an AS-REP containing a ticket-granting ticket (TGT): a ticket for the ticket-granting service itself, encrypted with the krbtgt key, which proves to the KDC that the user authenticated and is used to request service tickets without the password. The client cannot read the TGT; it only stores it. The reply also contains a session key, encrypted with the user's key, that the client uses in the next step. From here on, the password is no longer needed.

3–4: Getting a service ticket

When Lucía opens \\fs01\billing, the client sends a TGS-REQ: the TGT, an authenticator (a fresh timestamp encrypted with the session key, which proves the TGT is not replayed) and the name of the service it wants, cifs/fs01.ad.example.com. The KDC looks up which account has that service principal name and returns a TGS-REP with a service ticket: a ticket for one specific service, encrypted with the key of the account that runs the service, which carries the user's identity and group memberships and a session key for client and service.

In AD, the group memberships travel in a Microsoft extension inside the ticket, the Privilege Attribute Certificate (PAC). That is why a new group membership needs new tickets: the old ones still carry the old list (see when a membership change takes effect).

5–6: Using the service

The client sends the service ticket and a new authenticator to the file server in an AP-REQ. The file server decrypts the ticket with its own key; if that works, the ticket must have come from the KDC. It reads the user's identity and groups from the ticket and checks the authenticator's timestamp. No call to a DC is needed, which makes Kerberos fast and scalable. If the client asks for mutual authentication, the service proves its identity in an AP-REP encrypted with the session key, which only the real service could have read from the ticket.

The flip side: because a service ticket is encrypted with the service account's key, any authenticated user can request one and try to guess the password offline. Against an account with a long random password, such as a computer account or a group Managed Service Account, that is hopeless; against svc-sql with a password from 2014 it is not. That is Kerberoasting (T1558.003).

Service principal names

A service principal name (SPN) is the unique name of a service instance in Kerberos, in the form serviceclass/host[:port], registered on the account that runs the service so the KDC knows which key to encrypt service tickets with. Examples:

  • HOST/pc-bil-014.ad.example.com, registered automatically on each computer account and covering built-in services such as file sharing (cifs);
  • HTTP/intranet.ad.example.com for a web application whose application pool runs as a service account;
  • MSSQLSvc/sql01.ad.example.com:1433 for a SQL Server instance.

Each SPN must be registered on exactly one account in the forest. The setspn tool manages them:

setspn -L AD\svc-intranet                              # list SPNs of an account
setspn -Q HTTP/intranet.ad.example.com                 # which account has this SPN?
setspn -S HTTP/intranet.ad.example.com AD\svc-intranet # add, after checking for duplicates
setspn -X -F                                           # find duplicates in the forest

Two SPN problems cause most Kerberos tickets that reach the service desk:

  • Duplicate SPN. Two accounts claim the same name, typically after a service was moved from one account to another and the old SPN was left behind. The KDC cannot know whose key to use, logs an error on the DC, and the request fails; many clients then quietly fall back to NTLM. Always add SPNs with setspn -S, never -A, which skips the duplicate check.
  • SPN on the wrong account. The KDC encrypts the ticket for the account that has the SPN, but the service runs under another account and cannot decrypt it. The client sees KRB_AP_ERR_MODIFIED errors, often after someone changed an application pool from a service account to a built-in identity.

Time, clock skew and ticket lifetimes

Authenticators and tickets carry timestamps, and services remember recently seen authenticators, so a captured message cannot be replayed later. That only works if clocks agree. Clock skew is the difference between the clocks of two systems; Kerberos rejects requests whose timestamps differ from the receiver's clock by more than an allowed maximum, which is 5 minutes by default in Windows domains. Time zones do not matter: Kerberos compares instants in UTC, so a laptop set to the wrong time zone but the correct UTC time is fine.

# Would a Kerberos service accept these requests? Check the clock skew.
from datetime import datetime, timedelta, timezone

MAX_SKEW = timedelta(minutes=5)  # the Windows default
server_time = datetime(2026, 10, 1, 9, 0, 0, tzinfo=timezone.utc)

# Timestamps from the authenticators that clients sent (ISO 8601).
requests = [
    ("PC-BIL-014", "2026-10-01T09:01:30+00:00"),
    ("PC-WS-031", "2026-10-01T08:54:59+00:00"),
    ("LAB-VM-07", "2026-10-01T11:00:10+02:00"),  # local time, with offset
    ("PC-NOC-02", "2026-10-01T09:05:00+00:00"),
    ("SRV-OLD-01", "2026-10-01T09:07:45+00:00"),
]

for host, stamp in requests:
    skew = datetime.fromisoformat(stamp) - server_time
    seconds = int(skew.total_seconds())
    verdict = "accept" if abs(skew) <= MAX_SKEW else "reject (KRB_AP_ERR_SKEW)"
    print(f"{host:<11}{seconds:+5d} s  {verdict}")
PC-BIL-014   +90 s  accept
PC-WS-031   -301 s  reject (KRB_AP_ERR_SKEW)
LAB-VM-07    +10 s  accept
PC-NOC-02   +300 s  accept
SRV-OLD-01  +465 s  reject (KRB_AP_ERR_SKEW)

LAB-VM-07 shows 11:00 on its clock but is only 10 seconds off, because its offset says it is two hours ahead of UTC. PC-WS-031 is rejected for being one second too far behind: the limit is sharp.

Windows keeps clocks in line through a hierarchy: members synchronize with a DC, DCs with the PDC emulator of their domain, and the PDC emulator of the forest root domain with a reliable external source over NTP (see NTP). w32tm /query /status shows where a machine gets its time; w32tm /resync forces a synchronization. A virtual machine that takes its time from the hypervisor host while also syncing with the domain is a classic source of drift.

Ticket lifetimes and klist

Tickets expire. In the Default Domain Policy, the maximum lifetime of a user's TGT is 10 hours, which covers a working day; a ticket can be renewed without the password up to a maximum renewal period set in the same policy. When it runs out, Windows gets a new one using the cached credentials. klist shows the tickets of the current session:

klist
Current LogonId is 0:0x3e7a1

Cached Tickets: (2)

#0>     Client: lromero @ AD.EXAMPLE.COM
        Server: krbtgt/AD.EXAMPLE.COM @ AD.EXAMPLE.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
        Start Time: 10/1/2026 8:15:03 (local)
        End Time:   10/1/2026 18:15:03 (local)
        Renew Time: 10/8/2026 8:15:03 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Kdc Called: DC01.ad.example.com

#1>     Client: lromero @ AD.EXAMPLE.COM
        Server: cifs/fs01.ad.example.com @ AD.EXAMPLE.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
        Start Time: 10/1/2026 8:16:40 (local)
        End Time:   10/1/2026 18:15:03 (local)
        Renew Time: 10/8/2026 8:15:03 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Kdc Called: DC01.ad.example.com

Ticket #0 is the TGT (server krbtgt/…, flag initial), ticket #1 the service ticket for the file server. klist purge deletes the cached tickets, so the next access requests fresh ones, which is useful after an SPN fix. No ticket for a service at all, while access works, usually means the connection used NTLM.

Delegation

Sometimes a service must act as the user toward another service: a web application that reads a report from SQL Server with the permissions of the person who opened the page. Kerberos delegation is the Active Directory feature that lets a service obtain Kerberos tickets to other services on behalf of a user who authenticated to it. There are three kinds, from oldest and riskiest to newest:

Kind How it works Risk
Unconstrained The user's TGT is forwarded to the service, which can then request tickets to any service as that user. High: whoever controls that server can reuse the TGTs of everyone who connects, including administrators. DCs have it by design; other servers should not.
Constrained The service account gets a list of SPNs it may delegate to; set by a domain administrator on the front-end account. Limited to the listed services, but configure it carefully.
Resource-based constrained The back-end resource lists which front-end accounts may delegate to it; its owner decides. Anyone with write access to that setting on a computer object can abuse it; review who can modify computer objects.

Defenses: find and remove unconstrained delegation outside the DCs, mark privileged accounts "Account is sensitive and cannot be delegated" or put them in the Protected Users group, and review delegation settings as part of regular access reviews.

# Computers trusted for unconstrained delegation (expect only DCs here)
Get-ADComputer -Filter 'TrustedForDelegation -eq $true' | Select-Object Name

Encryption types: AES, not RC4

Tickets and session keys can be encrypted with several algorithms. Current Windows uses AES (AES256 and AES128 with SHA-1 based integrity, from RFC 3962). The older RC4-HMAC type uses the account's NT hash, the unsalted hash of its password, as the key, which makes offline cracking of service tickets much faster and links Kerberos weaknesses to NTLM ones. See symmetric encryption for the algorithms themselves.

Microsoft has been removing RC4 from Kerberos in phases, tracked as CVE-2026-20833:

  • 13 January 2026: updates added audit events and a registry setting to test the new behavior early.
  • 14 April 2026: enforcement on by default. Domain controllers issue service tickets with AES only for accounts without an explicit msDS-SupportedEncryptionTypes value; rollback was still possible.
  • From July 2026: the rollback setting is removed. RC4 is used only where it is explicitly configured on an account.

To find what still uses RC4, look at the DC security events 4768 (TGT requested) and 4769 (service ticket requested): the field "Ticket Encryption Type" shows 0x12 for AES256 and 0x17 for RC4. Old appliances, Java applications with fixed keytabs and accounts whose password was last set before AES keys existed are the usual suspects; resetting such an account's password generates its AES keys.

NTLM

NTLM (NT LAN Manager) is Microsoft's older challenge-response authentication protocol, in which the client proves knowledge of the password by computing a response to a random challenge from the server using the password's hash, without a ticket or a trusted third party in the exchange. It still exists because Kerberos needs things NTLM does not: a reachable DC, a name with an SPN, and a domain. Workgroup computers, local accounts, connections by IP address and old applications fall back to it.

The exchange takes three messages:

  1. NEGOTIATE: the client says it wants to use NTLM.
  2. CHALLENGE: the server sends a random number.
  3. AUTHENTICATE: the client returns a response computed from the challenge and the user's NT hash. For a domain account, the server passes it to a DC, which checks it.

Why NTLM is weaker

  • No mutual authentication. The client never verifies the server, so it can be tricked into authenticating to an attacker.
  • Relay. An attacker in the middle can forward a challenge and the victim's response to another server and be signed in there as the victim (an adversary-in-the-middle technique, T1557). SMB signing, LDAP signing and channel binding (see Directory Services and LDAP) and Extended Protection for Authentication on web servers break relaying.
  • The hash is the password. The response is computed from the NT hash, not from the password itself, so an attacker who steals a hash from memory can authenticate without knowing the password (pass-the-hash, T1550.002).
  • Weak old versions. NTLMv1 and LAN Manager use cryptography that can be broken quickly.

Deprecation and removal

In June 2024 Microsoft marked all NTLM versions (LAN Manager, NTLMv1 and NTLMv2) as deprecated: they still work, but are no longer developed, and applications should call the Negotiate package, which prefers Kerberos. NTLMv1 is removed starting with Windows 11 24H2 and Windows Server 2025. Early in 2026 Microsoft published a roadmap toward disabling network NTLM by default, which as reported describes three phases: better NTLM auditing (in Windows 11 24H2 and Server 2025), then features that let Kerberos work in cases that used to need NTLM, such as IAKerb and a local KDC (planned for the second half of 2026), and finally a future Windows release in which network NTLM is off by default but can be turned back on by policy. Check Microsoft's current documentation before planning around specific dates.

Audit before you block

Turning NTLM off without knowing who uses it breaks printers, scanners and line-of-business applications on a Monday morning. Audit first:

  • Enable the Group Policy security options Network security: Restrict NTLM: Audit NTLM authentication in this domain (on DCs) and Audit Incoming NTLM Traffic (on servers); see Group Policy. Events appear in Applications and Services Logs › Microsoft › Windows › NTLM › Operational.
  • In the Security log, logon event 4624 shows "Authentication Package: NTLM" and the NTLM version used, which is how you find remaining NTLMv1.
  • Fix the causes (add the missing SPN, use names instead of IP addresses, update the application), then restrict NTLM with exceptions for what cannot be fixed yet, and shrink the exception list over time.

Common mistakes

  • Ignoring time. A server whose clock drifted 6 minutes rejects every Kerberos request. Check w32tm /query /status early in any "sudden sign-in failures on one server" ticket.
  • Moving a service without moving its SPN, which leaves duplicates or an SPN on the wrong account.
  • Service accounts with weak passwords and RC4. They are exactly what Kerberoasting targets; use gMSAs and AES.
  • Unconstrained delegation "to make it work". Use constrained or resource-based delegation for the specific services instead.
  • Disabling NTLM without auditing. Measure first; then restrict with exceptions.