Skip to content

8.4.8 — Directories: LDAP, Active Directory and Kerberos

You press Ctrl+Alt+Del on a work laptop, type a password, and a desktop appears. Then you open a file share and a printer and an internal website, and none of them ask for anything.

Your password was never sent to any of those services, and it was sent to the domain controller only in a form that is not the password. What travelled instead were tickets. This page is what actually happened, and it matters because Active Directory still runs identity inside most large organisations — which means it is what your application will integrate with, and what an attacker who gets inside the network will target.

1. LDAP: the directory itself

A directory is a database optimised for reading hierarchical information about people, groups and machines. LDAP (Lightweight Directory Access Protocol, RFC 4511) is the protocol for querying one.

Entries form a tree, and each entry's name is its path from the root:

dc=example,dc=com                      ← domain component
  ou=People                            ← organisational unit
    cn=Ana Ruiz                        ← common name
  ou=Groups
    cn=Finance-Approvers

A distinguished name (DN) is the full path, read leaf-first:

cn=Ana Ruiz,ou=People,dc=example,dc=com

The leftmost component is the relative distinguished name (RDN). A DN is an identifier, not a search key — you generally have to find it before you can use it, which is why section 3's pattern exists.

Each entry has an objectClass determining which attributes it may hold: person, organizationalPerson, user, group. The attributes you will actually use:

AttributeMeaning
cnCommon name (display name)
sn, givenNameSurname, first name
mailEmail address
uidLogin name (OpenLDAP)
sAMAccountNameLogin name (Active Directory, pre-2000 format)
userPrincipalNameana@example.com style login (Active Directory)
memberOfGroups this user belongs to
objectGUID / objectSidImmutable identifiers

Use objectGUID (or objectSid) as the stable key, never the DN. A DN changes when someone moves between organisational units — a promotion, a department transfer — and an application keyed on DN loses the user's history at that moment.

Operations: bind (authenticate), search, add, modify, delete, unbind.

A search takes a base DN, a scope (base, one, sub) and a filter in prefix notation:

(&(objectClass=user)(sAMAccountName=ana)(memberOf=cn=Finance-Approvers,ou=Groups,dc=example,dc=com))

Read it as: AND(is a user, login is ana, is in Finance-Approvers).

LDAP injection is real and under-discussed. Interpolating user input into a filter lets an attacker inject )(objectClass=* and turn a specific lookup into "everything", or restructure the boolean logic to bypass a group check. Escape \ * ( ) NUL in every value, or use a library that parameterises filters. It is the same class of bug as SQL injection (Chapter 8.5.1) with fewer people watching for it.

Transport: port 389 plaintext, 636 for LDAPS, or 389 with StartTLS. A simple bind sends the password in the clear, so LDAP without TLS is a plaintext password on the wire — and it is still found in production. Active Directory now requires signing and channel binding by default, which is why older applications broke after a Windows update.

Anonymous bind allows reads without credentials. Frequently enabled and frequently a full employee directory available to anyone who can reach port 389.

2. Active Directory

Active Directory is not "LDAP for Windows". It is a bundle:

  • LDAP for directory queries.
  • Kerberos for authentication.
  • DNS for locating domain controllers — _ldap._tcp.dc._msdcs.example.com SRV records, which is why AD breaks in confusing ways when DNS is wrong.
  • Group Policy for pushing configuration to machines.
  • A replication system between domain controllers.

The structure: a domain is an administrative boundary with its own users and policy. A forest is one or more domains sharing a schema and trust. Organisational units group objects inside a domain for delegation and policy.

Domain controllers hold a writable copy each — multi-master replication, so changes can be made anywhere and converge. Replication is asynchronous, so a password changed on one controller may not be known at another for a short time, which produces the "I just changed my password and it does not work on the other site" report. A global catalogue holds a partial copy of every domain in the forest for forest-wide searches.

A service principal name (SPN) names a service for Kerberos, like HTTP/intranet.example.com. Missing or duplicate SPNs are the most common cause of Kerberos failing back to NTLM, which is where several attacks live.

3. Authenticating an application against a directory

The search-then-bind pattern, which is what you actually implement:

ts
// 1. Bind as a low-privilege service account
await client.bind(SERVICE_DN, SERVICE_PASSWORD);              // (1)

// 2. Find the user's DN by their login name
const { searchEntries } = await client.search(BASE_DN, {
  scope: 'sub',
  filter: `(&(objectClass=user)(sAMAccountName=${escapeLdap(input)}))`,  // (2)
  attributes: ['dn', 'mail', 'objectGUID', 'memberOf'],
});
if (searchEntries.length !== 1) throw new AuthError('invalid credentials');  // (3)

// 3. Bind as the user with their password — this is the authentication
await userClient.bind(searchEntries[0].dn, password);          // (4)

(1) The service account needs read access only. It is a standing credential in your configuration, so treat it as a secret (Chapter 8.6.1) and never make it a domain administrator. (2) escapeLdap is mandatory, per the injection note above. (3) Zero or several matches must produce the same generic error as a wrong password — otherwise you have account enumeration (Chapter 8.4.1). (4) A successful bind is the proof. An empty password must be rejected before this line: some servers treat an empty password as an anonymous bind, which succeeds, and that turns "authenticate" into "always yes". This is a real and repeatedly rediscovered vulnerability.

Then check group membership from memberOf, remembering that nested groups may not appear unless you query recursively.

The honest recommendation: prefer OIDC or SAML if the organisation has an identity provider in front of the directory. Direct LDAP binding means your application handles user passwords, which is exactly what federation was invented to avoid, and it cannot support MFA.

4. Kerberos

Kerberos (MIT, 1980s; version 5 is RFC 4120) answers a hard question: authenticate a user to many services without sending their password to any of them, over a network you do not trust.

The key distribution centre (KDC) runs on each domain controller and has two parts: the authentication service (AS) and the ticket-granting service (TGS).

clientKDC (domain controller)file server① AS-REQ — pre-auth encrypted with the password key② AS-REP — TGT (encrypted to krbtgt) + session key③ TGS-REQ — TGT + "I want cifs/files.example.com"④ TGS-REP — service ticket, encrypted to the service's key⑤ AP-REQ — present the service ticket + authenticatorthe file server never contacts the KDC — it decrypts the ticket with its own key
Three exchanges. The password is used only to derive a key locally; the ticket-granting ticket is then the credential for everything else.

Step by step:

① AS-REQ. The client derives a key from the password locally and sends a timestamp encrypted with it — pre-authentication, proving it knows the password without transmitting it.

② AS-REP. The KDC returns a ticket-granting ticket (TGT), encrypted with the krbtgt account's key so only the KDC can read it, plus a session key encrypted to the client. The TGT typically lasts 10 hours.

③ TGS-REQ. To reach a service, the client presents the TGT and names the SPN.

④ TGS-REP. The KDC returns a service ticket encrypted with that service's key.

⑤ AP-REQ. The client presents the ticket to the service, which decrypts it with its own key and learns who the user is — without contacting the KDC at all. That is what makes Kerberos scale, and it is why revocation is bounded by ticket lifetime rather than immediate.

Two consequences to remember. Clock skew matters: tickets carry timestamps and the default tolerance is five minutes, so a machine with a wrong clock fails to authenticate with a message that mentions nothing about time. And the krbtgt key is the crown jewels — anyone holding it can forge a TGT for anyone.

5. Kerberos attacks

These appear in every internal penetration test report, and knowing the shape is enough.

Kerberoasting. Any authenticated user may request a service ticket for any SPN. That ticket is encrypted with the service account's password key, so the attacker takes it away and cracks it offline at unlimited speed. The defence is that service account passwords must be long and random — or better, use group managed service accounts, where Windows generates and rotates a 120-character password nobody types.

AS-REP roasting. Accounts with pre-authentication disabled will return an AS-REP encrypted with the password key to anyone who asks, crackable offline. Do not disable pre-authentication.

Pass-the-ticket. Steal a ticket from a compromised machine's memory and reuse it. This is why an administrator logging in to a workstation leaves credentials there, and why privileged accounts should use dedicated administrative workstations.

Golden ticket. With the krbtgt key, forge a TGT for any user with any group membership, valid until the key changes. Recovery requires rotating krbtgt twice — the account keeps its previous key for compatibility, so one rotation leaves forged tickets working.

Silver ticket. With one service account's key, forge tickets for that service only. Quieter, because the KDC is never involved.

Delegation abuse. Kerberos delegation lets a service act as the user to another service. Unconstrained delegation stores the user's TGT on the front-end server, so compromising that server yields tickets for everyone who used it. Constrained delegation limits which services; resource-based constrained delegation is the modern form. Unconstrained delegation on any internet-facing service is a finding.

6. NTLM, and why it should go

NTLM is the older challenge-response protocol: the server sends a challenge, the client responds using a hash of the password, and a domain controller verifies.

It is still enabled almost everywhere, because it works without Kerberos infrastructure — when connecting by IP address rather than name, across untrusted domains, or when an SPN is missing.

Pass-the-hash: the response is computed from the password hash, so an attacker with the hash never needs the password. Dumping hashes from one machine's memory gives access anywhere that account is valid — the primary mechanism of lateral movement in Windows networks.

NTLM relay: the protocol does not bind the authentication to a channel, so an attacker who can make a victim authenticate to them can relay that authentication to a different server and act as the victim. SMB signing, LDAP channel binding and Extended Protection for Authentication are the defences, and they are why recent Windows updates enforce them by default.

The direction is clear: disable NTLM where possible, audit where it is still used first (turning it off blind breaks applications), and fix the causes — missing SPNs, connections by IP address, legacy applications.

7. Active Directory, LDAP and Entra ID untangled

This confusion is worth clearing precisely, because it comes up constantly.

LDAP is a protocol. Active Directory is a product that speaks LDAP and Kerberos among other things. Microsoft Entra ID (formerly Azure AD) is a different product with a similar name.

Entra ID is not Active Directory in the cloud. It does not speak LDAP or Kerberos. It speaks OIDC, OAuth 2.0, SAML and the Microsoft Graph API. It has no organisational units and no Group Policy. An application that binds to LDAP cannot point at Entra ID — this surprises teams mid-migration, and the answer is to move the application to OIDC.

Hybrid identity connects the two with a synchronisation agent, and the choice of authentication method is a real decision:

  • Password hash synchronisation — a hash of the password hash is synced to the cloud, so Entra authenticates on its own. Simplest and most resilient: cloud logins keep working when the on-premises network is down.
  • Pass-through authentication — Entra forwards the check to an on-premises agent. No password material in the cloud, and it depends on on-premises availability.
  • Federation — Entra redirects to on-premises AD FS via SAML. The most control and the most to run, including the certificate rotation of Chapter 8.4.5.

For new applications: OIDC against Entra ID, not LDAP against a domain controller. Chapter 8.4.9 covers that integration in practice.

What the interviewer will push on

"What is the difference between LDAP, Active Directory and Entra ID?" LDAP is a protocol; Active Directory is a product bundling LDAP, Kerberos, DNS and Group Policy; Entra ID is not AD in the cloud — no LDAP, no Kerberos, no organisational units, just OIDC/SAML/Graph. Naming that last point unprompted saves a real migration surprise.

"How would you authenticate users against Active Directory?" Search-then-bind: a low-privilege service account finds the DN, then bind as the user with their password. Then the three details — escape the filter input, return a generic error for zero or many matches, and reject an empty password before binding, because an empty password can be treated as an anonymous bind that succeeds.

"Explain Kerberos." Three exchanges: get a TGT from the AS using a locally derived password key, exchange it at the TGS for a service ticket, present that to the service. The service decrypts with its own key and never contacts the KDC, which is what makes it scale. Add the clock-skew requirement, because that is what you will actually debug.

"What is Kerberoasting?" Any authenticated user can request a service ticket for any SPN, and that ticket is encrypted with the service account's password key, so it can be cracked offline at unlimited speed. The defence is long random service account passwords or group managed service accounts — not detection.

"Why is a golden ticket so serious?" It is forged with the krbtgt key, so it authenticates as anyone with any group membership and the KDC issued nothing to revoke. Recovery requires rotating krbtgt twice, because the account retains its previous key for compatibility — the detail that shows you have read an incident report rather than a summary.

"Why does NTLM still exist and why is it dangerous?" It works without Kerberos infrastructure — by IP address, across trust boundaries, when an SPN is missing. It is dangerous because the response is computed from the hash, so pass-the-hash needs no password, and because it can be relayed to another server. Audit before disabling, and fix the causes.

One thing to volunteer: point out that a DN changes when a user moves organisational unit, so an application keyed on DN loses that user's identity on a promotion or transfer. Key on objectGUID. It is a one-line design decision that quietly breaks applications years later.

Recall

  • LDAP is a tree of entries named by distinguished name. Key users on objectGUID, never the DN — a DN changes when someone moves organisational unit.
  • Escape LDAP filter input — injection restructures the boolean and turns a lookup into "everything". A simple bind sends the password in the clear, so TLS is mandatory, and anonymous bind often exposes the whole directory.
  • Authenticate with search-then-bind: service account finds the DN, then bind as the user. Reject an empty password first — it can become an anonymous bind that succeeds.
  • Active Directory = LDAP + Kerberos + DNS + Group Policy + multi-master replication. Replication lag explains "my new password does not work at the other site". Missing or duplicate SPNs cause silent fallback to NTLM.
  • Kerberos in three exchanges: TGT from the AS (pre-auth proves the password locally), service ticket from the TGS, then presented to the service — which never contacts the KDC. Five-minute clock tolerance; the krbtgt key is the crown jewels.
  • Attacks: Kerberoasting (offline cracking of any service ticket — fix with long random or group managed service account passwords), AS-REP roasting, pass-the-ticket, golden ticket (rotate krbtgt twice), silver ticket, and unconstrained delegation storing everyone's TGT on one server.
  • NTLM enables pass-the-hash and relay because the response derives from the hash and is not channel-bound. Audit first, then disable, and fix the causes.
  • Entra ID is not AD in the cloud: no LDAP, no Kerberos, no OUs — OIDC/SAML/Graph. Hybrid options are password hash sync (most resilient), pass-through, or federation.

Self-test: Why key on objectGUID rather than DN? · What can an empty-password bind do to your login logic? · Why does the file server not contact the KDC? · What makes Kerberoasting possible for any authenticated user? · Why must krbtgt be rotated twice? · What does an LDAP-bound application do when the company moves to Entra ID?

Next: 8.4.9 takes the cloud side of this in practice — Entra ID tenants, app registrations, service principals, managed identities and conditional access, and how to debug a login that fails with a correlation id and nothing else.