Zurück zur Startseite

Kerberos für Entwickler: Protokoll und SSPI

Der Artikel zerlegt das Kerberos-Protokoll für AD: von Impersonation und TGT zur Delegation und C++-Code. SSPI-, PKINIT-, U2U-Beispiele zum Testen auf einer Maschine. Geeignet für Senior-Entwickler.

Kerberos: TGT, Delegation und C++-Code für SSPI
Advertisement 728x90

## Kerberos-Protokoll: Tiefgehender Einblick für Entwickler

Kerberos löst das Impersonationsproblem: Ein Dienst auf Rechner A erhält eine Anfrage von einem entfernten Client und muss Operationen im Namen dieses Clients ausführen, einschließlich Zugriff auf lokale Ressourcen. Dazu wird ein neues Access Token basierend auf den angegebenen Anmeldeinformationen erstellt. Ohne Kerberos würde der Dienst sein eigenes Token verwenden und den Zugriff auf Dateien blockieren, die erhöhte Privilegien erfordern.

In einem Szenario mit verketteten Anfragen fordert Dienst A Dienst B an. Delegation ermöglicht die Wahl: Impersonation aus dem eigenen Konto oder aus dem des ursprünglichen Clients. Kerberos übergibt verschlüsselte Tickets, die die SID des Benutzers, Gruppen und PAC (Privilege Attribute Certificate) enthalten.

Wichtige Komponenten:

Google AdInline article slot
  • Principal: eine Entität mit Passwort (Benutzer, Computer, Dienst).
  • KDC (Key Distribution Center): speichert Passwörter, stellt TGT (Ticket Granting Ticket) und Service-Tickets aus.
  • SPN (Service Principal Name): Diensteidentifikator, oft verknüpft mit dem Konto, unter dem der Dienst läuft.

Kerberos unterscheidet Authentifizierung von Autorisierung: Das Entschlüsseln des Tickets bestätigt die Identität, während das Token die Privilegien bestimmt.

Nachrichtenstruktur und Transport

Kerberos-Nachrichten verwenden ASN.1 (PER/DER-Codierung gemäß RFC 4120). Sie werden über UDP/TCP auf Port 88 übertragen. UDP eignet sich für kurze Pakete (TGT ~1-2 KB), TCP für größere (mit PAC).

KDC in Active Directory kombiniert AS (Authentication Service) und TGS (Ticket Granting Service). SRV-Einträge (_kerberos._tcp.<domain>) weisen auf Domain Controller hin.

Google AdInline article slot

AS-Exchange-Prozess (Erhalt des TGT):

  • Client → KDC: KRB_KDC_REQ (Vor-Authentifizierung mit Timestamp, verschlüsselt mit Passwort oder PKINIT).
  • KDC → Client: KRB_KDC_REP (TGT, verschlüsselt mit dem Langzeitschlüssel des Clients; Session Key in Vor-Authentifizierung).
  • Client speichert TGT in LSA (Local Security Authority).

TGS-Exchange (Service-Ticket):

  • Client → KDC: KRB_TGS_REQ (TGT + Authenticator + Dienstname/SPN).
  • KDC → Client: KRB_TGS_REP (Service-Ticket, Dienst-Session-Key).

AP-REQ (mit Service-Ticket) wird in LDAP, HTTP Negotiate, SMB, RPC gekapselt. Wireshark zeigt GSS-WRAP mit NTLM/Kerberos-Token.

Google AdInline article slot

Verschlüsselung und Schlüssel

Das Passwort wird zu einem Langzeitschlüssel gehasht (AES-256-CTs für Windows). Session Keys sind temporär und dienen zum Schutz von Nachrichten.

Beispiel-C++-Code für Kerberos-AES-Verschlüsselung mit CNG (Cryptography API: Next Generation):

#include <windows.h>
#include <ncrypt.h>
#include <ntstatus.h>

NTSTATUS EncryptKerberosAES(
    PUCHAR key, ULONG keyLen,
    PUCHAR plaintext, ULONG ptLen,
    PUCHAR* ciphertext, ULONG* ctLen) {
    NCRYPT_ALG_HANDLE hAlg = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;
    NTSTATUS status;

    status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0);
    if (!NT_SUCCESS(status)) return status;

    status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_CTS, sizeof(BCRYPT_CHAIN_MODE_CTS), 0);
    // Kerberos uses AES-CTS

    status = BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, key, keyLen);
    // ... encrypt logic with IV from Kerberos spec
    // Full code omitted for brevity

    BCryptCloseAlgorithmProvider(hAlg, 0);
    return status;
}

Der Code demonstriert die Einrichtung von AES im CTS-Modus (Cipher Text Stealing), spezifisch für Kerberos.

Arten der Delegation und Tests

Kerberos unterstützt constrained und unconstrained Delegation.

Delegationsoptionen:

  • Einfach: keine Delegation (Dienst leitet Anmeldeinformationen nicht weiter).
  • Unconstrained: vollständiges TGT-Forwarding (riskant, veraltet).
  • Constrained: S4U2Proxy – Service-Ticket nur für festgelegte SPN.
  • Resource-based constrained: auf der Dienstseite (Windows Server 2012+).

Testen auf einem Rechner: klist, AcquireCredentialsHandle mit SSPI verwenden. Beispiel für U2U (User-to-User):

CredHandle cred;
TimeStamp expiry;
AcquireCredentialsHandle(NULL, L"Kerberos", SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &cred, &expiry);
// U2U: impersonate without KDC, direct exchange

Für PKINIT: X.509-Zertifikat an AcquireCredentialsHandle mit SECPKG_CRED_CERTIFICATE übergeben. GSS-API ist ein Wrapper für SSPI unter Windows.

Cross-Domain-Authentifizierung und SPN

Trust Accounts (Name = Domain) ermöglichen Cross-Domain-Authentifizierung. Ein Client aus Domain A fordert ein TGT für den Trust Principal in Domain B an.

SPN hat kein Passwort – es identifiziert den Host/Benutzer. Duplizierte SPNs verweisen auf einen Principal. Das System erkennt den Typ am Format: host/<fqdn>, HTTP/<fqdn>.

Verwalten mehrerer Anmeldeinformationen:

  • ImpersonateHandleExplicit mit Logon.
  • LSA-Richtlinie für Multi-User-SPN.
  • Eigener GSS-Acceptor mit Prüfung mehrerer Schlüssel.

Wichtige Erkenntnisse

  • Kerberos ist die GSS-API-Schicht für Single Sign-On in AD; Tickets enthalten PAC mit SIDs/Gruppen.
  • Delegation ist entscheidend für Backend-zu-Backend; constrained minimiert Risiken.
  • SSPI testen: 3-5 Zeilen für AcquireCredentialsHandle statt Boilerplate.
  • PKINIT und U2U erweitern passwortlose Szenarien.
  • ASN.1 + AES-CTs bildet den Kern des Protokolls; in Wireshark auf Port 88 überwachen.

— Editorial Team

Advertisement 728x90

Weiterlesen